@absolutejs/voice 0.0.22-beta.443 → 0.0.22-beta.444
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 +37 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +113 -4
- package/dist/proofTrends.d.ts +2 -1
- package/dist/react/index.js +37 -3
- package/dist/reconnectContract.d.ts +88 -1
- package/dist/vue/index.js +37 -3
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -6428,6 +6428,9 @@ var readRealCallProfileTraceSurfaces = (events) => {
|
|
|
6428
6428
|
if (event.type === "client.barge_in") {
|
|
6429
6429
|
surfaces.add("barge-in");
|
|
6430
6430
|
}
|
|
6431
|
+
if (event.type === "client.reconnect") {
|
|
6432
|
+
surfaces.add("reconnect");
|
|
6433
|
+
}
|
|
6431
6434
|
}
|
|
6432
6435
|
return [...surfaces].sort();
|
|
6433
6436
|
};
|
|
@@ -6869,7 +6872,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
|
|
|
6869
6872
|
warnings.push(`Required real-call profile ${profileId} has ${String(summaryProfile?.sessionCount ?? 0)} session(s), expected at least ${String(options.minProfileSessions)}.`);
|
|
6870
6873
|
}
|
|
6871
6874
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
6872
|
-
const requiredSurfaces =
|
|
6875
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
6873
6876
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
6874
6877
|
for (const surface of requiredSurfaces) {
|
|
6875
6878
|
if (!observedSurfaces.has(surface)) {
|
|
@@ -6908,6 +6911,16 @@ var appendRealCallRecoveryActionQuery = (href, query) => {
|
|
|
6908
6911
|
const search = new URLSearchParams(entries).toString();
|
|
6909
6912
|
return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
|
|
6910
6913
|
};
|
|
6914
|
+
var resolveRequiredRealCallProfileSurfaces = (requiredProfileSurfaces, profileId) => {
|
|
6915
|
+
if (requiredProfileSurfaces === undefined) {
|
|
6916
|
+
return [];
|
|
6917
|
+
}
|
|
6918
|
+
if (Array.isArray(requiredProfileSurfaces)) {
|
|
6919
|
+
return requiredProfileSurfaces;
|
|
6920
|
+
}
|
|
6921
|
+
const requiredSurfacesByProfile = requiredProfileSurfaces;
|
|
6922
|
+
return requiredSurfacesByProfile[profileId] ?? [];
|
|
6923
|
+
};
|
|
6911
6924
|
var sleepVoiceRealCallProfileRecoveryLoop = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
6912
6925
|
var describeVoiceRealCallProfileRecoveryLoopAction = (action) => [
|
|
6913
6926
|
action.label ?? action.id ?? "recovery action",
|
|
@@ -7180,10 +7193,16 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
7180
7193
|
return true;
|
|
7181
7194
|
}
|
|
7182
7195
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
7183
|
-
const requiredSurfaces =
|
|
7196
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
7184
7197
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
7185
7198
|
return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
|
|
7186
7199
|
});
|
|
7200
|
+
const resolveRequiredProfileSurfaces = (profileId) => {
|
|
7201
|
+
if (typeof profileId !== "string") {
|
|
7202
|
+
return [];
|
|
7203
|
+
}
|
|
7204
|
+
return resolveRequiredRealCallProfileSurfaces(options.requiredProfileSurfaces, profileId);
|
|
7205
|
+
};
|
|
7187
7206
|
const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
|
|
7188
7207
|
const needsProfileProof = missingProfiles.length > 0 || warningProfiles.length > 0 || missingRoleProfiles.length > 0 || missingDepthProfiles.length > 0 || options.minCycles !== undefined && (report.summary.cycles ?? 0) < options.minCycles || options.minActionableProfiles !== undefined && report.defaults.summary.actionableProfiles < options.minActionableProfiles;
|
|
7189
7208
|
if (needsProfileProof) {
|
|
@@ -7206,6 +7225,19 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
7206
7225
|
method: "POST",
|
|
7207
7226
|
profileId
|
|
7208
7227
|
});
|
|
7228
|
+
const requiredSurfaces = resolveRequiredProfileSurfaces(profileId);
|
|
7229
|
+
const summaryProfile = typeof profileId === "string" ? summariesByProfile.get(profileId) : undefined;
|
|
7230
|
+
const observedSurfaces = new Set((summaryProfile?.surfaces ?? []).filter((value) => typeof value === "string"));
|
|
7231
|
+
if (requiredSurfaces.includes("reconnect") && !observedSurfaces.has("reconnect")) {
|
|
7232
|
+
actions.push({
|
|
7233
|
+
description: profileId ? `Run reconnect profile proof for ${profileId} when reconnect stability is required for this profile.` : "Run reconnect profile proof when required profiles depend on reconnect stability evidence.",
|
|
7234
|
+
href: appendRealCallRecoveryActionQuery(options.reconnectProofHref ?? "/api/voice/reconnect-proof", { profileId }),
|
|
7235
|
+
id: "collect-reconnect-proof",
|
|
7236
|
+
label: profileId ? `Run reconnect profile proof for ${profileId}` : "Run reconnect profile proof",
|
|
7237
|
+
method: "POST",
|
|
7238
|
+
profileId
|
|
7239
|
+
});
|
|
7240
|
+
}
|
|
7209
7241
|
}
|
|
7210
7242
|
}
|
|
7211
7243
|
if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
|
|
@@ -8031,6 +8063,7 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
8031
8063
|
var realCallProfileActionPaths = {
|
|
8032
8064
|
"collect-browser-proof": "/collect-browser-proof",
|
|
8033
8065
|
"collect-phone-proof": "/collect-phone-proof",
|
|
8066
|
+
"collect-reconnect-proof": "/collect-reconnect-proof",
|
|
8034
8067
|
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
8035
8068
|
refresh: "/refresh"
|
|
8036
8069
|
};
|
|
@@ -8056,11 +8089,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
|
8056
8089
|
...options,
|
|
8057
8090
|
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
8058
8091
|
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
8092
|
+
reconnectProofHref: options.reconnectProofHref ?? actionPath("collect-reconnect-proof"),
|
|
8059
8093
|
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
8060
8094
|
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
8061
8095
|
}).map((action) => ({
|
|
8062
8096
|
...action,
|
|
8063
|
-
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
8097
|
+
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-reconnect-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-reconnect-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
8064
8098
|
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
8065
8099
|
}));
|
|
8066
8100
|
return { actions, generatedAt: new Date().toISOString(), report };
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ export { buildVoiceAuditExport, exportVoiceAuditTrail, redactVoiceAuditEvent, re
|
|
|
9
9
|
export { createVoiceAuditHTTPSink, createVoiceAuditS3Sink, createVoiceAuditSinkDeliveryId, createVoiceAuditSinkDeliveryRecord, createVoiceAuditSinkDeliveryWorker, createVoiceAuditSinkDeliveryWorkerLoop, createVoiceAuditSinkStore, createVoiceMemoryAuditSinkDeliveryStore, deliverVoiceAuditEventsToSinks, summarizeVoiceAuditSinkDeliveries, } from "./auditSinks";
|
|
10
10
|
export { buildVoiceAuditDeliveryReport, createVoiceAuditDeliveryHTMLHandler, createVoiceAuditDeliveryJSONHandler, createVoiceAuditDeliveryRoutes, renderVoiceAuditDeliveryHTML, resolveVoiceAuditDeliveryFilter, } from "./auditDeliveryRoutes";
|
|
11
11
|
export { createVoiceBargeInRoutes, renderVoiceBargeInHTML, summarizeVoiceBargeIn, } from "./bargeInRoutes";
|
|
12
|
-
export { createVoiceReconnectContractRoutes, renderVoiceReconnectContractHTML, summarizeVoiceReconnectContractSnapshots, runVoiceReconnectContract, } from "./reconnectContract";
|
|
12
|
+
export { buildVoiceReconnectProofReport, createVoiceReconnectContractRoutes, createVoiceReconnectProofRoutes, renderVoiceReconnectContractHTML, summarizeVoiceReconnectProofSessions, summarizeVoiceReconnectContractSnapshots, runVoiceReconnectContract, } from "./reconnectContract";
|
|
13
|
+
export type { VoiceReconnectProofOptions, VoiceReconnectProofReport, VoiceReconnectProofRoutesOptions, VoiceReconnectProofStatus, } from "./reconnectContract";
|
|
13
14
|
export { assertVoiceRealtimeChannelEvidence, buildVoiceRealtimeChannelRuntimeSamplesFromTrace, buildVoiceRealtimeChannelReport, createVoiceRealtimeChannelRoutes, evaluateVoiceRealtimeChannelEvidence, renderVoiceRealtimeChannelHTML, renderVoiceRealtimeChannelMarkdown, } from "./realtimeChannel";
|
|
14
15
|
export type { VoiceRealtimeChannelAssertionInput, VoiceRealtimeChannelAssertionReport, VoiceRealtimeChannelBrowserCapture, VoiceRealtimeChannelIssue, VoiceRealtimeChannelReport, VoiceRealtimeChannelReportOptions, VoiceRealtimeChannelRoutesOptions, VoiceRealtimeChannelRuntimeSample, VoiceRealtimeChannelStatus, } from "./realtimeChannel";
|
|
15
16
|
export { assertVoiceRealtimeProviderContractEvidence, buildVoiceRealtimeProviderContractMatrix, createVoiceRealtimeProviderContractMatrixPreset, createVoiceRealtimeProviderContractRoutes, evaluateVoiceRealtimeProviderContractEvidence, renderVoiceRealtimeProviderContractHTML, } from "./realtimeProviderContracts";
|
package/dist/index.js
CHANGED
|
@@ -11626,6 +11626,22 @@ var summarizeVoiceReconnectContractSnapshots = (events, options = {}) => events.
|
|
|
11626
11626
|
turnIds: Array.isArray(payload.turnIds) ? payload.turnIds.filter((turnId) => typeof turnId === "string") : undefined
|
|
11627
11627
|
};
|
|
11628
11628
|
}).sort((left, right) => left.at - right.at);
|
|
11629
|
+
var summarizeVoiceReconnectProofSessions = (sessions, options = {}) => sessions.map((session) => {
|
|
11630
|
+
const attempts = session.reconnect.attempts;
|
|
11631
|
+
const at = session.lastActivityAt ?? session.reconnect.lastDisconnectAt ?? session.createdAt;
|
|
11632
|
+
const status = session.status === "reconnecting" ? "reconnecting" : attempts > 0 && session.status === "completed" ? "resumed" : attempts > 0 && session.status === "failed" ? "exhausted" : "idle";
|
|
11633
|
+
return {
|
|
11634
|
+
at,
|
|
11635
|
+
reconnect: {
|
|
11636
|
+
attempts,
|
|
11637
|
+
lastDisconnectAt: session.reconnect.lastDisconnectAt,
|
|
11638
|
+
lastResumedAt: status === "resumed" && session.lastActivityAt ? session.lastActivityAt : undefined,
|
|
11639
|
+
maxAttempts: options.maxAttempts ?? attempts,
|
|
11640
|
+
status
|
|
11641
|
+
},
|
|
11642
|
+
turnIds: session.committedTurnIds.length > 0 ? session.committedTurnIds : session.turns.map((turn) => turn.id)
|
|
11643
|
+
};
|
|
11644
|
+
}).sort((left, right) => left.at - right.at);
|
|
11629
11645
|
var findDuplicateTurnIds = (snapshots) => {
|
|
11630
11646
|
const duplicates = new Set;
|
|
11631
11647
|
for (const snapshot of snapshots) {
|
|
@@ -11665,7 +11681,7 @@ var runVoiceReconnectContract = (options) => {
|
|
|
11665
11681
|
const requireReconnect = options.requireReconnect ?? true;
|
|
11666
11682
|
const requireResume = options.requireResume ?? true;
|
|
11667
11683
|
const requireReplayProtection = options.requireReplayProtection ?? true;
|
|
11668
|
-
if (snapshots.length === 0) {
|
|
11684
|
+
if (snapshots.length === 0 && !options.allowNoSnapshots) {
|
|
11669
11685
|
issues.push({
|
|
11670
11686
|
code: "reconnect.no_snapshots",
|
|
11671
11687
|
message: "No reconnect snapshots were provided.",
|
|
@@ -11728,6 +11744,62 @@ var runVoiceReconnectContract = (options) => {
|
|
|
11728
11744
|
}
|
|
11729
11745
|
};
|
|
11730
11746
|
};
|
|
11747
|
+
var buildVoiceReconnectProofReport = (options = {}) => {
|
|
11748
|
+
const sessionSnapshots = options.sessions ? summarizeVoiceReconnectProofSessions(options.sessions, {
|
|
11749
|
+
maxAttempts: options.maxAttempts
|
|
11750
|
+
}) : [];
|
|
11751
|
+
const snapshots = [...sessionSnapshots, ...options.snapshots ?? []].sort((left, right) => left.at - right.at);
|
|
11752
|
+
const requireObservedReconnect = options.requireObservedReconnect ?? false;
|
|
11753
|
+
const contract = runVoiceReconnectContract({
|
|
11754
|
+
allowNoSnapshots: true,
|
|
11755
|
+
requireReconnect: requireObservedReconnect,
|
|
11756
|
+
requireReplayProtection: options.requireReplayProtection ?? true,
|
|
11757
|
+
requireResume: options.requireResumeAfterReconnect ?? requireObservedReconnect,
|
|
11758
|
+
snapshots
|
|
11759
|
+
});
|
|
11760
|
+
const errorCount = contract.issues.filter((issue) => issue.severity === "error").length;
|
|
11761
|
+
const warningCount = contract.issues.filter((issue) => issue.severity === "warning").length;
|
|
11762
|
+
const status = errorCount > 0 ? "fail" : warningCount > 0 ? "warn" : "pass";
|
|
11763
|
+
const sessionCount = options.completedSessionCount ?? options.sessions?.length ?? 0;
|
|
11764
|
+
const summary = snapshots.length === 0 ? `Checked ${sessionCount} completed session(s). Reconnect proof is enabled; no reconnect cycle was observed.` : contract.summary.resumed ? `Checked ${sessionCount} completed session(s) and ${snapshots.length} reconnect snapshot(s). Resume was observed without replay duplicates.` : contract.summary.reconnected ? `Checked ${sessionCount} completed session(s) and ${snapshots.length} reconnect snapshot(s). Reconnect was observed.` : `Checked ${sessionCount} completed session(s) and ${snapshots.length} reconnect snapshot(s). No reconnect was required.`;
|
|
11765
|
+
return {
|
|
11766
|
+
checkedAt: contract.checkedAt,
|
|
11767
|
+
contract,
|
|
11768
|
+
generatedAt: new Date(contract.checkedAt).toISOString(),
|
|
11769
|
+
ok: status !== "fail",
|
|
11770
|
+
reconnectAware: true,
|
|
11771
|
+
sessionCount,
|
|
11772
|
+
snapshotCount: snapshots.length,
|
|
11773
|
+
status,
|
|
11774
|
+
summary
|
|
11775
|
+
};
|
|
11776
|
+
};
|
|
11777
|
+
var getSessionsFromStore = async (store) => {
|
|
11778
|
+
const summaries = await store.list();
|
|
11779
|
+
const sessions = await Promise.all(summaries.map((summary) => store.get(summary.id)));
|
|
11780
|
+
return sessions.filter((session) => session !== undefined);
|
|
11781
|
+
};
|
|
11782
|
+
var createVoiceReconnectProofRoutes = (options = {}) => {
|
|
11783
|
+
const path = options.path ?? "/api/voice/reconnect-proof";
|
|
11784
|
+
const buildReport = async () => buildVoiceReconnectProofReport({
|
|
11785
|
+
completedSessionCount: options.getCompletedSessionCount ? await options.getCompletedSessionCount() : undefined,
|
|
11786
|
+
maxAttempts: options.maxAttempts,
|
|
11787
|
+
requireObservedReconnect: options.requireObservedReconnect,
|
|
11788
|
+
requireReplayProtection: options.requireReplayProtection,
|
|
11789
|
+
requireResumeAfterReconnect: options.requireResumeAfterReconnect,
|
|
11790
|
+
sessions: options.getSessions ? await options.getSessions() : options.store ? await getSessionsFromStore(options.store) : undefined,
|
|
11791
|
+
snapshots: options.getSnapshots ? await options.getSnapshots() : undefined
|
|
11792
|
+
});
|
|
11793
|
+
const respond = async () => new Response(JSON.stringify(await buildReport()), {
|
|
11794
|
+
headers: {
|
|
11795
|
+
"content-type": "application/json; charset=utf-8",
|
|
11796
|
+
...options.headers
|
|
11797
|
+
}
|
|
11798
|
+
});
|
|
11799
|
+
return new Elysia9({
|
|
11800
|
+
name: options.name ?? "absolutejs-voice-reconnect-proof"
|
|
11801
|
+
}).get(path, respond).post(path, respond);
|
|
11802
|
+
};
|
|
11731
11803
|
var renderVoiceReconnectContractHTML = (report) => {
|
|
11732
11804
|
const issues = report.issues.map((issue) => `<li class="${escapeHtml12(issue.severity)}"><strong>${escapeHtml12(issue.code)}</strong>: ${escapeHtml12(issue.message)}</li>`).join("");
|
|
11733
11805
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>Voice Reconnect Contract</title><style>body{background:#0d1117;color:#f8fafc;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:980px;padding:32px}.hero,.card{background:#151b23;border:1px solid #30363d;border-radius:18px;margin-bottom:16px;padding:20px}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.25rem,7vw,4.5rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0d1117;border:1px solid #30363d;border-radius:999px;padding:7px 10px}.pass{color:#86efac}.fail,.error{color:#fca5a5}.warning{color:#fde68a}li{margin:8px 0}</style></head><body><main><section class="hero"><p class="eyebrow">Reconnect Resume Proof</p><h1>Voice reconnect contract</h1><div class="summary"><span class="pill ${report.pass ? "pass" : "fail"}">${report.pass ? "pass" : "fail"}</span><span class="pill">${String(report.snapshotCount)} snapshots</span><span class="pill">${String(report.summary.attempts)} attempts</span><span class="pill">statuses ${escapeHtml12(report.statuses.join(", ") || "none")}</span></div></section><section class="card"><h2>Summary</h2><p>reconnected ${String(report.summary.reconnected)} \xB7 resumed ${String(report.summary.resumed)} \xB7 exhausted ${String(report.summary.exhausted)} \xB7 duplicate turns ${String(report.summary.duplicateTurnIds.length)}</p></section><section class="card"><h2>Issues</h2>${issues ? `<ul>${issues}</ul>` : '<p class="pass">No contract issues.</p>'}</section></main></body></html>`;
|
|
@@ -16604,6 +16676,9 @@ var readRealCallProfileTraceSurfaces = (events) => {
|
|
|
16604
16676
|
if (event.type === "client.barge_in") {
|
|
16605
16677
|
surfaces.add("barge-in");
|
|
16606
16678
|
}
|
|
16679
|
+
if (event.type === "client.reconnect") {
|
|
16680
|
+
surfaces.add("reconnect");
|
|
16681
|
+
}
|
|
16607
16682
|
}
|
|
16608
16683
|
return [...surfaces].sort();
|
|
16609
16684
|
};
|
|
@@ -17045,7 +17120,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
|
|
|
17045
17120
|
warnings.push(`Required real-call profile ${profileId} has ${String(summaryProfile?.sessionCount ?? 0)} session(s), expected at least ${String(options.minProfileSessions)}.`);
|
|
17046
17121
|
}
|
|
17047
17122
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
17048
|
-
const requiredSurfaces =
|
|
17123
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
17049
17124
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
17050
17125
|
for (const surface of requiredSurfaces) {
|
|
17051
17126
|
if (!observedSurfaces.has(surface)) {
|
|
@@ -17084,6 +17159,16 @@ var appendRealCallRecoveryActionQuery = (href, query) => {
|
|
|
17084
17159
|
const search = new URLSearchParams(entries).toString();
|
|
17085
17160
|
return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
|
|
17086
17161
|
};
|
|
17162
|
+
var resolveRequiredRealCallProfileSurfaces = (requiredProfileSurfaces, profileId) => {
|
|
17163
|
+
if (requiredProfileSurfaces === undefined) {
|
|
17164
|
+
return [];
|
|
17165
|
+
}
|
|
17166
|
+
if (Array.isArray(requiredProfileSurfaces)) {
|
|
17167
|
+
return requiredProfileSurfaces;
|
|
17168
|
+
}
|
|
17169
|
+
const requiredSurfacesByProfile = requiredProfileSurfaces;
|
|
17170
|
+
return requiredSurfacesByProfile[profileId] ?? [];
|
|
17171
|
+
};
|
|
17087
17172
|
var sleepVoiceRealCallProfileRecoveryLoop = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
17088
17173
|
var describeVoiceRealCallProfileRecoveryLoopAction = (action) => [
|
|
17089
17174
|
action.label ?? action.id ?? "recovery action",
|
|
@@ -17356,10 +17441,16 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
17356
17441
|
return true;
|
|
17357
17442
|
}
|
|
17358
17443
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
17359
|
-
const requiredSurfaces =
|
|
17444
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
17360
17445
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
17361
17446
|
return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
|
|
17362
17447
|
});
|
|
17448
|
+
const resolveRequiredProfileSurfaces = (profileId) => {
|
|
17449
|
+
if (typeof profileId !== "string") {
|
|
17450
|
+
return [];
|
|
17451
|
+
}
|
|
17452
|
+
return resolveRequiredRealCallProfileSurfaces(options.requiredProfileSurfaces, profileId);
|
|
17453
|
+
};
|
|
17363
17454
|
const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
|
|
17364
17455
|
const needsProfileProof = missingProfiles.length > 0 || warningProfiles.length > 0 || missingRoleProfiles.length > 0 || missingDepthProfiles.length > 0 || options.minCycles !== undefined && (report.summary.cycles ?? 0) < options.minCycles || options.minActionableProfiles !== undefined && report.defaults.summary.actionableProfiles < options.minActionableProfiles;
|
|
17365
17456
|
if (needsProfileProof) {
|
|
@@ -17382,6 +17473,19 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
17382
17473
|
method: "POST",
|
|
17383
17474
|
profileId
|
|
17384
17475
|
});
|
|
17476
|
+
const requiredSurfaces = resolveRequiredProfileSurfaces(profileId);
|
|
17477
|
+
const summaryProfile = typeof profileId === "string" ? summariesByProfile.get(profileId) : undefined;
|
|
17478
|
+
const observedSurfaces = new Set((summaryProfile?.surfaces ?? []).filter((value) => typeof value === "string"));
|
|
17479
|
+
if (requiredSurfaces.includes("reconnect") && !observedSurfaces.has("reconnect")) {
|
|
17480
|
+
actions.push({
|
|
17481
|
+
description: profileId ? `Run reconnect profile proof for ${profileId} when reconnect stability is required for this profile.` : "Run reconnect profile proof when required profiles depend on reconnect stability evidence.",
|
|
17482
|
+
href: appendRealCallRecoveryActionQuery(options.reconnectProofHref ?? "/api/voice/reconnect-proof", { profileId }),
|
|
17483
|
+
id: "collect-reconnect-proof",
|
|
17484
|
+
label: profileId ? `Run reconnect profile proof for ${profileId}` : "Run reconnect profile proof",
|
|
17485
|
+
method: "POST",
|
|
17486
|
+
profileId
|
|
17487
|
+
});
|
|
17488
|
+
}
|
|
17385
17489
|
}
|
|
17386
17490
|
}
|
|
17387
17491
|
if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
|
|
@@ -18207,6 +18311,7 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
18207
18311
|
var realCallProfileActionPaths = {
|
|
18208
18312
|
"collect-browser-proof": "/collect-browser-proof",
|
|
18209
18313
|
"collect-phone-proof": "/collect-phone-proof",
|
|
18314
|
+
"collect-reconnect-proof": "/collect-reconnect-proof",
|
|
18210
18315
|
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
18211
18316
|
refresh: "/refresh"
|
|
18212
18317
|
};
|
|
@@ -18232,11 +18337,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
|
18232
18337
|
...options,
|
|
18233
18338
|
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
18234
18339
|
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
18340
|
+
reconnectProofHref: options.reconnectProofHref ?? actionPath("collect-reconnect-proof"),
|
|
18235
18341
|
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
18236
18342
|
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
18237
18343
|
}).map((action) => ({
|
|
18238
18344
|
...action,
|
|
18239
|
-
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
18345
|
+
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-reconnect-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-reconnect-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
18240
18346
|
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
18241
18347
|
}));
|
|
18242
18348
|
return { actions, generatedAt: new Date().toISOString(), report };
|
|
@@ -41883,6 +41989,7 @@ export {
|
|
|
41883
41989
|
summarizeVoiceSessionReplay,
|
|
41884
41990
|
summarizeVoiceRoutingSessions,
|
|
41885
41991
|
summarizeVoiceRoutingDecision,
|
|
41992
|
+
summarizeVoiceReconnectProofSessions,
|
|
41886
41993
|
summarizeVoiceReconnectContractSnapshots,
|
|
41887
41994
|
summarizeVoiceProviderHealth,
|
|
41888
41995
|
summarizeVoiceProviderFallbackRecovery,
|
|
@@ -42239,6 +42346,7 @@ export {
|
|
|
42239
42346
|
createVoiceRedisTaskLeaseCoordinator,
|
|
42240
42347
|
createVoiceRedisPlivoWebhookNonceStore,
|
|
42241
42348
|
createVoiceRedisIdempotencyStore,
|
|
42349
|
+
createVoiceReconnectProofRoutes,
|
|
42242
42350
|
createVoiceReconnectContractRoutes,
|
|
42243
42351
|
createVoiceRealtimeProviderContractRoutes,
|
|
42244
42352
|
createVoiceRealtimeProviderContractMatrixPreset,
|
|
@@ -42477,6 +42585,7 @@ export {
|
|
|
42477
42585
|
buildVoiceSloCalibrationReport,
|
|
42478
42586
|
buildVoiceSessionSnapshotStatus,
|
|
42479
42587
|
buildVoiceSessionSnapshot,
|
|
42588
|
+
buildVoiceReconnectProofReport,
|
|
42480
42589
|
buildVoiceRealtimeProviderContractMatrix,
|
|
42481
42590
|
buildVoiceRealtimeChannelRuntimeSamplesFromTrace,
|
|
42482
42591
|
buildVoiceRealtimeChannelReport,
|
package/dist/proofTrends.d.ts
CHANGED
|
@@ -375,7 +375,7 @@ export type VoiceRealCallProfileHistoryRoutesOptions = Omit<VoiceRealCallProfile
|
|
|
375
375
|
source?: (() => Promise<VoiceRealCallProfileHistoryOptions> | VoiceRealCallProfileHistoryOptions) | VoiceRealCallProfileHistoryOptions;
|
|
376
376
|
title?: string;
|
|
377
377
|
};
|
|
378
|
-
export type VoiceRealCallProfileRecoveryActionId = "collect-browser-proof" | "collect-phone-proof" | "collect-provider-role-evidence" | "refresh";
|
|
378
|
+
export type VoiceRealCallProfileRecoveryActionId = "collect-browser-proof" | "collect-phone-proof" | "collect-reconnect-proof" | "collect-provider-role-evidence" | "refresh";
|
|
379
379
|
export type VoiceRealCallProfileRecoveryAction = VoiceProductionReadinessAction & {
|
|
380
380
|
id: VoiceRealCallProfileRecoveryActionId;
|
|
381
381
|
profileId?: string;
|
|
@@ -383,6 +383,7 @@ export type VoiceRealCallProfileRecoveryAction = VoiceProductionReadinessAction
|
|
|
383
383
|
export type VoiceRealCallProfileReadinessCheckOptions = {
|
|
384
384
|
browserProofHref?: string;
|
|
385
385
|
failOnWarnings?: boolean;
|
|
386
|
+
reconnectProofHref?: string;
|
|
386
387
|
href?: string;
|
|
387
388
|
label?: string;
|
|
388
389
|
maxAgeMs?: number;
|
package/dist/react/index.js
CHANGED
|
@@ -3608,6 +3608,9 @@ var readRealCallProfileTraceSurfaces = (events) => {
|
|
|
3608
3608
|
if (event.type === "client.barge_in") {
|
|
3609
3609
|
surfaces.add("barge-in");
|
|
3610
3610
|
}
|
|
3611
|
+
if (event.type === "client.reconnect") {
|
|
3612
|
+
surfaces.add("reconnect");
|
|
3613
|
+
}
|
|
3611
3614
|
}
|
|
3612
3615
|
return [...surfaces].sort();
|
|
3613
3616
|
};
|
|
@@ -4049,7 +4052,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
|
|
|
4049
4052
|
warnings.push(`Required real-call profile ${profileId} has ${String(summaryProfile?.sessionCount ?? 0)} session(s), expected at least ${String(options.minProfileSessions)}.`);
|
|
4050
4053
|
}
|
|
4051
4054
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
4052
|
-
const requiredSurfaces =
|
|
4055
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
4053
4056
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
4054
4057
|
for (const surface of requiredSurfaces) {
|
|
4055
4058
|
if (!observedSurfaces.has(surface)) {
|
|
@@ -4088,6 +4091,16 @@ var appendRealCallRecoveryActionQuery = (href, query) => {
|
|
|
4088
4091
|
const search = new URLSearchParams(entries).toString();
|
|
4089
4092
|
return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
|
|
4090
4093
|
};
|
|
4094
|
+
var resolveRequiredRealCallProfileSurfaces = (requiredProfileSurfaces, profileId) => {
|
|
4095
|
+
if (requiredProfileSurfaces === undefined) {
|
|
4096
|
+
return [];
|
|
4097
|
+
}
|
|
4098
|
+
if (Array.isArray(requiredProfileSurfaces)) {
|
|
4099
|
+
return requiredProfileSurfaces;
|
|
4100
|
+
}
|
|
4101
|
+
const requiredSurfacesByProfile = requiredProfileSurfaces;
|
|
4102
|
+
return requiredSurfacesByProfile[profileId] ?? [];
|
|
4103
|
+
};
|
|
4091
4104
|
var sleepVoiceRealCallProfileRecoveryLoop = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
4092
4105
|
var describeVoiceRealCallProfileRecoveryLoopAction = (action) => [
|
|
4093
4106
|
action.label ?? action.id ?? "recovery action",
|
|
@@ -4360,10 +4373,16 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4360
4373
|
return true;
|
|
4361
4374
|
}
|
|
4362
4375
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
4363
|
-
const requiredSurfaces =
|
|
4376
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
4364
4377
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
4365
4378
|
return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
|
|
4366
4379
|
});
|
|
4380
|
+
const resolveRequiredProfileSurfaces = (profileId) => {
|
|
4381
|
+
if (typeof profileId !== "string") {
|
|
4382
|
+
return [];
|
|
4383
|
+
}
|
|
4384
|
+
return resolveRequiredRealCallProfileSurfaces(options.requiredProfileSurfaces, profileId);
|
|
4385
|
+
};
|
|
4367
4386
|
const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
|
|
4368
4387
|
const needsProfileProof = missingProfiles.length > 0 || warningProfiles.length > 0 || missingRoleProfiles.length > 0 || missingDepthProfiles.length > 0 || options.minCycles !== undefined && (report.summary.cycles ?? 0) < options.minCycles || options.minActionableProfiles !== undefined && report.defaults.summary.actionableProfiles < options.minActionableProfiles;
|
|
4369
4388
|
if (needsProfileProof) {
|
|
@@ -4386,6 +4405,19 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4386
4405
|
method: "POST",
|
|
4387
4406
|
profileId
|
|
4388
4407
|
});
|
|
4408
|
+
const requiredSurfaces = resolveRequiredProfileSurfaces(profileId);
|
|
4409
|
+
const summaryProfile = typeof profileId === "string" ? summariesByProfile.get(profileId) : undefined;
|
|
4410
|
+
const observedSurfaces = new Set((summaryProfile?.surfaces ?? []).filter((value) => typeof value === "string"));
|
|
4411
|
+
if (requiredSurfaces.includes("reconnect") && !observedSurfaces.has("reconnect")) {
|
|
4412
|
+
actions.push({
|
|
4413
|
+
description: profileId ? `Run reconnect profile proof for ${profileId} when reconnect stability is required for this profile.` : "Run reconnect profile proof when required profiles depend on reconnect stability evidence.",
|
|
4414
|
+
href: appendRealCallRecoveryActionQuery(options.reconnectProofHref ?? "/api/voice/reconnect-proof", { profileId }),
|
|
4415
|
+
id: "collect-reconnect-proof",
|
|
4416
|
+
label: profileId ? `Run reconnect profile proof for ${profileId}` : "Run reconnect profile proof",
|
|
4417
|
+
method: "POST",
|
|
4418
|
+
profileId
|
|
4419
|
+
});
|
|
4420
|
+
}
|
|
4389
4421
|
}
|
|
4390
4422
|
}
|
|
4391
4423
|
if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
|
|
@@ -5211,6 +5243,7 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
5211
5243
|
var realCallProfileActionPaths = {
|
|
5212
5244
|
"collect-browser-proof": "/collect-browser-proof",
|
|
5213
5245
|
"collect-phone-proof": "/collect-phone-proof",
|
|
5246
|
+
"collect-reconnect-proof": "/collect-reconnect-proof",
|
|
5214
5247
|
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
5215
5248
|
refresh: "/refresh"
|
|
5216
5249
|
};
|
|
@@ -5236,11 +5269,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
|
5236
5269
|
...options,
|
|
5237
5270
|
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
5238
5271
|
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
5272
|
+
reconnectProofHref: options.reconnectProofHref ?? actionPath("collect-reconnect-proof"),
|
|
5239
5273
|
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
5240
5274
|
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
5241
5275
|
}).map((action) => ({
|
|
5242
5276
|
...action,
|
|
5243
|
-
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
5277
|
+
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-reconnect-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-reconnect-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
5244
5278
|
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
5245
5279
|
}));
|
|
5246
5280
|
return { actions, generatedAt: new Date().toISOString(), report };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Elysia } from "elysia";
|
|
2
|
-
import type { VoiceReconnectClientState } from "./types";
|
|
2
|
+
import type { VoiceReconnectClientState, VoiceSessionRecord, VoiceSessionStore } from "./types";
|
|
3
3
|
import type { StoredVoiceTraceEvent } from "./trace";
|
|
4
4
|
export type VoiceReconnectContractSnapshot = {
|
|
5
5
|
at: number;
|
|
@@ -28,11 +28,42 @@ export type VoiceReconnectContractReport = {
|
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
30
|
export type VoiceReconnectContractOptions = {
|
|
31
|
+
allowNoSnapshots?: boolean;
|
|
31
32
|
requireReconnect?: boolean;
|
|
32
33
|
requireResume?: boolean;
|
|
33
34
|
requireReplayProtection?: boolean;
|
|
34
35
|
snapshots: readonly VoiceReconnectContractSnapshot[];
|
|
35
36
|
};
|
|
37
|
+
export type VoiceReconnectProofStatus = "fail" | "pass" | "warn";
|
|
38
|
+
export type VoiceReconnectProofReport = {
|
|
39
|
+
checkedAt: number;
|
|
40
|
+
contract: VoiceReconnectContractReport;
|
|
41
|
+
generatedAt: string;
|
|
42
|
+
ok: boolean;
|
|
43
|
+
reconnectAware: true;
|
|
44
|
+
sessionCount: number;
|
|
45
|
+
snapshotCount: number;
|
|
46
|
+
status: VoiceReconnectProofStatus;
|
|
47
|
+
summary: string;
|
|
48
|
+
};
|
|
49
|
+
export type VoiceReconnectProofOptions = {
|
|
50
|
+
completedSessionCount?: number;
|
|
51
|
+
maxAttempts?: number;
|
|
52
|
+
requireObservedReconnect?: boolean;
|
|
53
|
+
requireReplayProtection?: boolean;
|
|
54
|
+
requireResumeAfterReconnect?: boolean;
|
|
55
|
+
sessions?: readonly VoiceSessionRecord[];
|
|
56
|
+
snapshots?: readonly VoiceReconnectContractSnapshot[];
|
|
57
|
+
};
|
|
58
|
+
export type VoiceReconnectProofRoutesOptions = Omit<VoiceReconnectProofOptions, "completedSessionCount" | "sessions" | "snapshots"> & {
|
|
59
|
+
getCompletedSessionCount?: () => number | Promise<number>;
|
|
60
|
+
getSessions?: () => readonly VoiceSessionRecord[] | Promise<readonly VoiceSessionRecord[]>;
|
|
61
|
+
getSnapshots?: () => readonly VoiceReconnectContractSnapshot[] | Promise<readonly VoiceReconnectContractSnapshot[]>;
|
|
62
|
+
headers?: HeadersInit;
|
|
63
|
+
name?: string;
|
|
64
|
+
path?: string;
|
|
65
|
+
store?: VoiceSessionStore;
|
|
66
|
+
};
|
|
36
67
|
export type VoiceReconnectContractRoutesOptions = Omit<VoiceReconnectContractOptions, "snapshots"> & {
|
|
37
68
|
getSnapshots: () => readonly VoiceReconnectContractSnapshot[] | Promise<readonly VoiceReconnectContractSnapshot[]>;
|
|
38
69
|
headers?: HeadersInit;
|
|
@@ -44,7 +75,63 @@ export type VoiceReconnectContractRoutesOptions = Omit<VoiceReconnectContractOpt
|
|
|
44
75
|
export declare const summarizeVoiceReconnectContractSnapshots: (events: readonly StoredVoiceTraceEvent[], options?: {
|
|
45
76
|
sessionId?: string;
|
|
46
77
|
}) => VoiceReconnectContractSnapshot[];
|
|
78
|
+
export declare const summarizeVoiceReconnectProofSessions: (sessions: readonly VoiceSessionRecord[], options?: {
|
|
79
|
+
maxAttempts?: number;
|
|
80
|
+
}) => VoiceReconnectContractSnapshot[];
|
|
47
81
|
export declare const runVoiceReconnectContract: (options: VoiceReconnectContractOptions) => VoiceReconnectContractReport;
|
|
82
|
+
export declare const buildVoiceReconnectProofReport: (options?: VoiceReconnectProofOptions) => VoiceReconnectProofReport;
|
|
83
|
+
export declare const createVoiceReconnectProofRoutes: (options?: VoiceReconnectProofRoutesOptions) => Elysia<"", {
|
|
84
|
+
decorator: {};
|
|
85
|
+
store: {};
|
|
86
|
+
derive: {};
|
|
87
|
+
resolve: {};
|
|
88
|
+
}, {
|
|
89
|
+
typebox: {};
|
|
90
|
+
error: {};
|
|
91
|
+
}, {
|
|
92
|
+
schema: {};
|
|
93
|
+
standaloneSchema: {};
|
|
94
|
+
macro: {};
|
|
95
|
+
macroFn: {};
|
|
96
|
+
parser: {};
|
|
97
|
+
response: {};
|
|
98
|
+
}, {
|
|
99
|
+
[x: string]: {
|
|
100
|
+
get: {
|
|
101
|
+
body: unknown;
|
|
102
|
+
params: {};
|
|
103
|
+
query: unknown;
|
|
104
|
+
headers: unknown;
|
|
105
|
+
response: {
|
|
106
|
+
200: Response;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
} & {
|
|
111
|
+
[x: string]: {
|
|
112
|
+
post: {
|
|
113
|
+
body: unknown;
|
|
114
|
+
params: {};
|
|
115
|
+
query: unknown;
|
|
116
|
+
headers: unknown;
|
|
117
|
+
response: {
|
|
118
|
+
200: Response;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
}, {
|
|
123
|
+
derive: {};
|
|
124
|
+
resolve: {};
|
|
125
|
+
schema: {};
|
|
126
|
+
standaloneSchema: {};
|
|
127
|
+
response: {};
|
|
128
|
+
}, {
|
|
129
|
+
derive: {};
|
|
130
|
+
resolve: {};
|
|
131
|
+
schema: {};
|
|
132
|
+
standaloneSchema: {};
|
|
133
|
+
response: {};
|
|
134
|
+
}>;
|
|
48
135
|
export declare const renderVoiceReconnectContractHTML: (report: VoiceReconnectContractReport) => string;
|
|
49
136
|
export declare const createVoiceReconnectContractRoutes: (options: VoiceReconnectContractRoutesOptions) => Elysia<"", {
|
|
50
137
|
decorator: {};
|
package/dist/vue/index.js
CHANGED
|
@@ -3529,6 +3529,9 @@ var readRealCallProfileTraceSurfaces = (events) => {
|
|
|
3529
3529
|
if (event.type === "client.barge_in") {
|
|
3530
3530
|
surfaces.add("barge-in");
|
|
3531
3531
|
}
|
|
3532
|
+
if (event.type === "client.reconnect") {
|
|
3533
|
+
surfaces.add("reconnect");
|
|
3534
|
+
}
|
|
3532
3535
|
}
|
|
3533
3536
|
return [...surfaces].sort();
|
|
3534
3537
|
};
|
|
@@ -3970,7 +3973,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
|
|
|
3970
3973
|
warnings.push(`Required real-call profile ${profileId} has ${String(summaryProfile?.sessionCount ?? 0)} session(s), expected at least ${String(options.minProfileSessions)}.`);
|
|
3971
3974
|
}
|
|
3972
3975
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
3973
|
-
const requiredSurfaces =
|
|
3976
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
3974
3977
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
3975
3978
|
for (const surface of requiredSurfaces) {
|
|
3976
3979
|
if (!observedSurfaces.has(surface)) {
|
|
@@ -4009,6 +4012,16 @@ var appendRealCallRecoveryActionQuery = (href, query) => {
|
|
|
4009
4012
|
const search = new URLSearchParams(entries).toString();
|
|
4010
4013
|
return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
|
|
4011
4014
|
};
|
|
4015
|
+
var resolveRequiredRealCallProfileSurfaces = (requiredProfileSurfaces, profileId) => {
|
|
4016
|
+
if (requiredProfileSurfaces === undefined) {
|
|
4017
|
+
return [];
|
|
4018
|
+
}
|
|
4019
|
+
if (Array.isArray(requiredProfileSurfaces)) {
|
|
4020
|
+
return requiredProfileSurfaces;
|
|
4021
|
+
}
|
|
4022
|
+
const requiredSurfacesByProfile = requiredProfileSurfaces;
|
|
4023
|
+
return requiredSurfacesByProfile[profileId] ?? [];
|
|
4024
|
+
};
|
|
4012
4025
|
var sleepVoiceRealCallProfileRecoveryLoop = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
4013
4026
|
var describeVoiceRealCallProfileRecoveryLoopAction = (action) => [
|
|
4014
4027
|
action.label ?? action.id ?? "recovery action",
|
|
@@ -4281,10 +4294,16 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4281
4294
|
return true;
|
|
4282
4295
|
}
|
|
4283
4296
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
4284
|
-
const requiredSurfaces =
|
|
4297
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
4285
4298
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
4286
4299
|
return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
|
|
4287
4300
|
});
|
|
4301
|
+
const resolveRequiredProfileSurfaces = (profileId) => {
|
|
4302
|
+
if (typeof profileId !== "string") {
|
|
4303
|
+
return [];
|
|
4304
|
+
}
|
|
4305
|
+
return resolveRequiredRealCallProfileSurfaces(options.requiredProfileSurfaces, profileId);
|
|
4306
|
+
};
|
|
4288
4307
|
const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
|
|
4289
4308
|
const needsProfileProof = missingProfiles.length > 0 || warningProfiles.length > 0 || missingRoleProfiles.length > 0 || missingDepthProfiles.length > 0 || options.minCycles !== undefined && (report.summary.cycles ?? 0) < options.minCycles || options.minActionableProfiles !== undefined && report.defaults.summary.actionableProfiles < options.minActionableProfiles;
|
|
4290
4309
|
if (needsProfileProof) {
|
|
@@ -4307,6 +4326,19 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4307
4326
|
method: "POST",
|
|
4308
4327
|
profileId
|
|
4309
4328
|
});
|
|
4329
|
+
const requiredSurfaces = resolveRequiredProfileSurfaces(profileId);
|
|
4330
|
+
const summaryProfile = typeof profileId === "string" ? summariesByProfile.get(profileId) : undefined;
|
|
4331
|
+
const observedSurfaces = new Set((summaryProfile?.surfaces ?? []).filter((value) => typeof value === "string"));
|
|
4332
|
+
if (requiredSurfaces.includes("reconnect") && !observedSurfaces.has("reconnect")) {
|
|
4333
|
+
actions.push({
|
|
4334
|
+
description: profileId ? `Run reconnect profile proof for ${profileId} when reconnect stability is required for this profile.` : "Run reconnect profile proof when required profiles depend on reconnect stability evidence.",
|
|
4335
|
+
href: appendRealCallRecoveryActionQuery(options.reconnectProofHref ?? "/api/voice/reconnect-proof", { profileId }),
|
|
4336
|
+
id: "collect-reconnect-proof",
|
|
4337
|
+
label: profileId ? `Run reconnect profile proof for ${profileId}` : "Run reconnect profile proof",
|
|
4338
|
+
method: "POST",
|
|
4339
|
+
profileId
|
|
4340
|
+
});
|
|
4341
|
+
}
|
|
4310
4342
|
}
|
|
4311
4343
|
}
|
|
4312
4344
|
if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
|
|
@@ -5132,6 +5164,7 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
5132
5164
|
var realCallProfileActionPaths = {
|
|
5133
5165
|
"collect-browser-proof": "/collect-browser-proof",
|
|
5134
5166
|
"collect-phone-proof": "/collect-phone-proof",
|
|
5167
|
+
"collect-reconnect-proof": "/collect-reconnect-proof",
|
|
5135
5168
|
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
5136
5169
|
refresh: "/refresh"
|
|
5137
5170
|
};
|
|
@@ -5157,11 +5190,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
|
5157
5190
|
...options,
|
|
5158
5191
|
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
5159
5192
|
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
5193
|
+
reconnectProofHref: options.reconnectProofHref ?? actionPath("collect-reconnect-proof"),
|
|
5160
5194
|
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
5161
5195
|
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
5162
5196
|
}).map((action) => ({
|
|
5163
5197
|
...action,
|
|
5164
|
-
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
5198
|
+
href: action.id === "collect-browser-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-browser-proof"), { profileId: action.profileId }) : action.id === "collect-phone-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-phone-proof"), { profileId: action.profileId }) : action.id === "collect-reconnect-proof" ? appendRealCallRecoveryActionQuery(actionPath("collect-reconnect-proof"), { profileId: action.profileId }) : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
|
|
5165
5199
|
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
5166
5200
|
}));
|
|
5167
5201
|
return { actions, generatedAt: new Date().toISOString(), report };
|