@absolutejs/voice 0.0.22-beta.443 → 0.0.22-beta.445
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 +134 -4
- package/dist/proofTrends.d.ts +2 -1
- package/dist/react/index.js +37 -3
- package/dist/reconnectContract.d.ts +89 -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,83 @@ 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 collectedSnapshots = [];
|
|
11785
|
+
const maxCollectedSnapshots = options.maxCollectedSnapshots ?? 500;
|
|
11786
|
+
const buildReport = async () => buildVoiceReconnectProofReport({
|
|
11787
|
+
completedSessionCount: options.getCompletedSessionCount ? await options.getCompletedSessionCount() : undefined,
|
|
11788
|
+
maxAttempts: options.maxAttempts,
|
|
11789
|
+
requireObservedReconnect: options.requireObservedReconnect,
|
|
11790
|
+
requireReplayProtection: options.requireReplayProtection,
|
|
11791
|
+
requireResumeAfterReconnect: options.requireResumeAfterReconnect,
|
|
11792
|
+
sessions: options.getSessions ? await options.getSessions() : options.store ? await getSessionsFromStore(options.store) : undefined,
|
|
11793
|
+
snapshots: [
|
|
11794
|
+
...collectedSnapshots,
|
|
11795
|
+
...options.getSnapshots ? await options.getSnapshots() : []
|
|
11796
|
+
]
|
|
11797
|
+
});
|
|
11798
|
+
const respond = async () => new Response(JSON.stringify(await buildReport()), {
|
|
11799
|
+
headers: {
|
|
11800
|
+
"content-type": "application/json; charset=utf-8",
|
|
11801
|
+
...options.headers
|
|
11802
|
+
}
|
|
11803
|
+
});
|
|
11804
|
+
const collectSnapshot = (body) => {
|
|
11805
|
+
if (!isReconnectPayload(body)) {
|
|
11806
|
+
return;
|
|
11807
|
+
}
|
|
11808
|
+
collectedSnapshots.push({
|
|
11809
|
+
at: body.at,
|
|
11810
|
+
reconnect: body.reconnect,
|
|
11811
|
+
turnIds: Array.isArray(body.turnIds) ? body.turnIds.filter((turnId) => typeof turnId === "string") : undefined
|
|
11812
|
+
});
|
|
11813
|
+
if (collectedSnapshots.length > maxCollectedSnapshots) {
|
|
11814
|
+
collectedSnapshots.splice(0, collectedSnapshots.length - maxCollectedSnapshots);
|
|
11815
|
+
}
|
|
11816
|
+
};
|
|
11817
|
+
return new Elysia9({
|
|
11818
|
+
name: options.name ?? "absolutejs-voice-reconnect-proof"
|
|
11819
|
+
}).get(path, respond).post(path, async ({ body }) => {
|
|
11820
|
+
collectSnapshot(body);
|
|
11821
|
+
return respond();
|
|
11822
|
+
});
|
|
11823
|
+
};
|
|
11731
11824
|
var renderVoiceReconnectContractHTML = (report) => {
|
|
11732
11825
|
const issues = report.issues.map((issue) => `<li class="${escapeHtml12(issue.severity)}"><strong>${escapeHtml12(issue.code)}</strong>: ${escapeHtml12(issue.message)}</li>`).join("");
|
|
11733
11826
|
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 +16697,9 @@ var readRealCallProfileTraceSurfaces = (events) => {
|
|
|
16604
16697
|
if (event.type === "client.barge_in") {
|
|
16605
16698
|
surfaces.add("barge-in");
|
|
16606
16699
|
}
|
|
16700
|
+
if (event.type === "client.reconnect") {
|
|
16701
|
+
surfaces.add("reconnect");
|
|
16702
|
+
}
|
|
16607
16703
|
}
|
|
16608
16704
|
return [...surfaces].sort();
|
|
16609
16705
|
};
|
|
@@ -17045,7 +17141,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
|
|
|
17045
17141
|
warnings.push(`Required real-call profile ${profileId} has ${String(summaryProfile?.sessionCount ?? 0)} session(s), expected at least ${String(options.minProfileSessions)}.`);
|
|
17046
17142
|
}
|
|
17047
17143
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
17048
|
-
const requiredSurfaces =
|
|
17144
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
17049
17145
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
17050
17146
|
for (const surface of requiredSurfaces) {
|
|
17051
17147
|
if (!observedSurfaces.has(surface)) {
|
|
@@ -17084,6 +17180,16 @@ var appendRealCallRecoveryActionQuery = (href, query) => {
|
|
|
17084
17180
|
const search = new URLSearchParams(entries).toString();
|
|
17085
17181
|
return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
|
|
17086
17182
|
};
|
|
17183
|
+
var resolveRequiredRealCallProfileSurfaces = (requiredProfileSurfaces, profileId) => {
|
|
17184
|
+
if (requiredProfileSurfaces === undefined) {
|
|
17185
|
+
return [];
|
|
17186
|
+
}
|
|
17187
|
+
if (Array.isArray(requiredProfileSurfaces)) {
|
|
17188
|
+
return requiredProfileSurfaces;
|
|
17189
|
+
}
|
|
17190
|
+
const requiredSurfacesByProfile = requiredProfileSurfaces;
|
|
17191
|
+
return requiredSurfacesByProfile[profileId] ?? [];
|
|
17192
|
+
};
|
|
17087
17193
|
var sleepVoiceRealCallProfileRecoveryLoop = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
17088
17194
|
var describeVoiceRealCallProfileRecoveryLoopAction = (action) => [
|
|
17089
17195
|
action.label ?? action.id ?? "recovery action",
|
|
@@ -17356,10 +17462,16 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
17356
17462
|
return true;
|
|
17357
17463
|
}
|
|
17358
17464
|
const requiredProfileSurfaces = options.requiredProfileSurfaces;
|
|
17359
|
-
const requiredSurfaces =
|
|
17465
|
+
const requiredSurfaces = resolveRequiredRealCallProfileSurfaces(requiredProfileSurfaces, profileId);
|
|
17360
17466
|
const observedSurfaces = new Set(summaryProfile?.surfaces ?? []);
|
|
17361
17467
|
return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
|
|
17362
17468
|
});
|
|
17469
|
+
const resolveRequiredProfileSurfaces = (profileId) => {
|
|
17470
|
+
if (typeof profileId !== "string") {
|
|
17471
|
+
return [];
|
|
17472
|
+
}
|
|
17473
|
+
return resolveRequiredRealCallProfileSurfaces(options.requiredProfileSurfaces, profileId);
|
|
17474
|
+
};
|
|
17363
17475
|
const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
|
|
17364
17476
|
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
17477
|
if (needsProfileProof) {
|
|
@@ -17382,6 +17494,19 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
17382
17494
|
method: "POST",
|
|
17383
17495
|
profileId
|
|
17384
17496
|
});
|
|
17497
|
+
const requiredSurfaces = resolveRequiredProfileSurfaces(profileId);
|
|
17498
|
+
const summaryProfile = typeof profileId === "string" ? summariesByProfile.get(profileId) : undefined;
|
|
17499
|
+
const observedSurfaces = new Set((summaryProfile?.surfaces ?? []).filter((value) => typeof value === "string"));
|
|
17500
|
+
if (requiredSurfaces.includes("reconnect") && !observedSurfaces.has("reconnect")) {
|
|
17501
|
+
actions.push({
|
|
17502
|
+
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.",
|
|
17503
|
+
href: appendRealCallRecoveryActionQuery(options.reconnectProofHref ?? "/api/voice/reconnect-proof", { profileId }),
|
|
17504
|
+
id: "collect-reconnect-proof",
|
|
17505
|
+
label: profileId ? `Run reconnect profile proof for ${profileId}` : "Run reconnect profile proof",
|
|
17506
|
+
method: "POST",
|
|
17507
|
+
profileId
|
|
17508
|
+
});
|
|
17509
|
+
}
|
|
17385
17510
|
}
|
|
17386
17511
|
}
|
|
17387
17512
|
if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
|
|
@@ -18207,6 +18332,7 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
18207
18332
|
var realCallProfileActionPaths = {
|
|
18208
18333
|
"collect-browser-proof": "/collect-browser-proof",
|
|
18209
18334
|
"collect-phone-proof": "/collect-phone-proof",
|
|
18335
|
+
"collect-reconnect-proof": "/collect-reconnect-proof",
|
|
18210
18336
|
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
18211
18337
|
refresh: "/refresh"
|
|
18212
18338
|
};
|
|
@@ -18232,11 +18358,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
|
18232
18358
|
...options,
|
|
18233
18359
|
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
18234
18360
|
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
18361
|
+
reconnectProofHref: options.reconnectProofHref ?? actionPath("collect-reconnect-proof"),
|
|
18235
18362
|
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
18236
18363
|
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
18237
18364
|
}).map((action) => ({
|
|
18238
18365
|
...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,
|
|
18366
|
+
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
18367
|
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
18241
18368
|
}));
|
|
18242
18369
|
return { actions, generatedAt: new Date().toISOString(), report };
|
|
@@ -41883,6 +42010,7 @@ export {
|
|
|
41883
42010
|
summarizeVoiceSessionReplay,
|
|
41884
42011
|
summarizeVoiceRoutingSessions,
|
|
41885
42012
|
summarizeVoiceRoutingDecision,
|
|
42013
|
+
summarizeVoiceReconnectProofSessions,
|
|
41886
42014
|
summarizeVoiceReconnectContractSnapshots,
|
|
41887
42015
|
summarizeVoiceProviderHealth,
|
|
41888
42016
|
summarizeVoiceProviderFallbackRecovery,
|
|
@@ -42239,6 +42367,7 @@ export {
|
|
|
42239
42367
|
createVoiceRedisTaskLeaseCoordinator,
|
|
42240
42368
|
createVoiceRedisPlivoWebhookNonceStore,
|
|
42241
42369
|
createVoiceRedisIdempotencyStore,
|
|
42370
|
+
createVoiceReconnectProofRoutes,
|
|
42242
42371
|
createVoiceReconnectContractRoutes,
|
|
42243
42372
|
createVoiceRealtimeProviderContractRoutes,
|
|
42244
42373
|
createVoiceRealtimeProviderContractMatrixPreset,
|
|
@@ -42477,6 +42606,7 @@ export {
|
|
|
42477
42606
|
buildVoiceSloCalibrationReport,
|
|
42478
42607
|
buildVoiceSessionSnapshotStatus,
|
|
42479
42608
|
buildVoiceSessionSnapshot,
|
|
42609
|
+
buildVoiceReconnectProofReport,
|
|
42480
42610
|
buildVoiceRealtimeProviderContractMatrix,
|
|
42481
42611
|
buildVoiceRealtimeChannelRuntimeSamplesFromTrace,
|
|
42482
42612
|
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,43 @@ 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
|
+
maxCollectedSnapshots?: number;
|
|
64
|
+
name?: string;
|
|
65
|
+
path?: string;
|
|
66
|
+
store?: VoiceSessionStore;
|
|
67
|
+
};
|
|
36
68
|
export type VoiceReconnectContractRoutesOptions = Omit<VoiceReconnectContractOptions, "snapshots"> & {
|
|
37
69
|
getSnapshots: () => readonly VoiceReconnectContractSnapshot[] | Promise<readonly VoiceReconnectContractSnapshot[]>;
|
|
38
70
|
headers?: HeadersInit;
|
|
@@ -44,7 +76,63 @@ export type VoiceReconnectContractRoutesOptions = Omit<VoiceReconnectContractOpt
|
|
|
44
76
|
export declare const summarizeVoiceReconnectContractSnapshots: (events: readonly StoredVoiceTraceEvent[], options?: {
|
|
45
77
|
sessionId?: string;
|
|
46
78
|
}) => VoiceReconnectContractSnapshot[];
|
|
79
|
+
export declare const summarizeVoiceReconnectProofSessions: (sessions: readonly VoiceSessionRecord[], options?: {
|
|
80
|
+
maxAttempts?: number;
|
|
81
|
+
}) => VoiceReconnectContractSnapshot[];
|
|
47
82
|
export declare const runVoiceReconnectContract: (options: VoiceReconnectContractOptions) => VoiceReconnectContractReport;
|
|
83
|
+
export declare const buildVoiceReconnectProofReport: (options?: VoiceReconnectProofOptions) => VoiceReconnectProofReport;
|
|
84
|
+
export declare const createVoiceReconnectProofRoutes: (options?: VoiceReconnectProofRoutesOptions) => Elysia<"", {
|
|
85
|
+
decorator: {};
|
|
86
|
+
store: {};
|
|
87
|
+
derive: {};
|
|
88
|
+
resolve: {};
|
|
89
|
+
}, {
|
|
90
|
+
typebox: {};
|
|
91
|
+
error: {};
|
|
92
|
+
}, {
|
|
93
|
+
schema: {};
|
|
94
|
+
standaloneSchema: {};
|
|
95
|
+
macro: {};
|
|
96
|
+
macroFn: {};
|
|
97
|
+
parser: {};
|
|
98
|
+
response: {};
|
|
99
|
+
}, {
|
|
100
|
+
[x: string]: {
|
|
101
|
+
get: {
|
|
102
|
+
body: unknown;
|
|
103
|
+
params: {};
|
|
104
|
+
query: unknown;
|
|
105
|
+
headers: unknown;
|
|
106
|
+
response: {
|
|
107
|
+
200: Response;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
} & {
|
|
112
|
+
[x: string]: {
|
|
113
|
+
post: {
|
|
114
|
+
body: unknown;
|
|
115
|
+
params: {};
|
|
116
|
+
query: unknown;
|
|
117
|
+
headers: unknown;
|
|
118
|
+
response: {
|
|
119
|
+
200: Response;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
}, {
|
|
124
|
+
derive: {};
|
|
125
|
+
resolve: {};
|
|
126
|
+
schema: {};
|
|
127
|
+
standaloneSchema: {};
|
|
128
|
+
response: {};
|
|
129
|
+
}, {
|
|
130
|
+
derive: {};
|
|
131
|
+
resolve: {};
|
|
132
|
+
schema: {};
|
|
133
|
+
standaloneSchema: {};
|
|
134
|
+
response: {};
|
|
135
|
+
}>;
|
|
48
136
|
export declare const renderVoiceReconnectContractHTML: (report: VoiceReconnectContractReport) => string;
|
|
49
137
|
export declare const createVoiceReconnectContractRoutes: (options: VoiceReconnectContractRoutesOptions) => Elysia<"", {
|
|
50
138
|
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 };
|