@absolutejs/voice 0.0.22-beta.442 → 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.
@@ -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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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,
@@ -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;
@@ -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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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 = requiredProfileSurfaces === undefined ? [] : Array.isArray(requiredProfileSurfaces) ? requiredProfileSurfaces : requiredProfileSurfaces[profileId] ?? [];
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.442",
3
+ "version": "0.0.22-beta.444",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",