@absolutejs/voice 0.0.22-beta.381 → 0.0.22-beta.382

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.
@@ -4668,7 +4668,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
4668
4668
  var uniqueRealCallProfileActions = (actions) => {
4669
4669
  const seen = new Set;
4670
4670
  return actions.filter((action) => {
4671
- const key = `${action.method ?? "GET"}:${action.href}:${action.label}`;
4671
+ const key = `${action.method ?? "GET"}:${action.href}:${action.label}:${action.profileId ?? ""}`;
4672
4672
  if (seen.has(key)) {
4673
4673
  return false;
4674
4674
  }
@@ -4676,6 +4676,16 @@ var uniqueRealCallProfileActions = (actions) => {
4676
4676
  return true;
4677
4677
  });
4678
4678
  };
4679
+ var appendRealCallRecoveryActionQuery = (href, query) => {
4680
+ const entries = Object.entries(query).filter((entry) => entry[1] !== undefined);
4681
+ if (entries.length === 0) {
4682
+ return href;
4683
+ }
4684
+ const [base = href, hash = ""] = href.split("#");
4685
+ const separator = base.includes("?") ? "&" : "?";
4686
+ const search = new URLSearchParams(entries).toString();
4687
+ return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
4688
+ };
4679
4689
  var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
4680
4690
  const actions = [
4681
4691
  {
@@ -4711,19 +4721,26 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
4711
4721
  return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
4712
4722
  });
4713
4723
  const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
4714
- if (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) {
4715
- actions.push({
4716
- description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
4717
- href: options.browserProofHref ?? "/voice/browser-call-profiles",
4718
- id: "collect-browser-proof",
4719
- label: "Run browser profile proof"
4720
- });
4721
- actions.push({
4722
- description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
4723
- href: options.phoneProofHref ?? "/api/voice/phone/smoke",
4724
- id: "collect-phone-proof",
4725
- label: "Run phone profile proof"
4726
- });
4724
+ 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;
4725
+ if (needsProfileProof) {
4726
+ const targetProfileIds = missingProfiles.length > 0 || missingDepthProfiles.length > 0 ? [...new Set([...missingProfiles, ...missingDepthProfiles])] : [...requiredProfiles];
4727
+ const targets = targetProfileIds.length > 0 ? targetProfileIds : [undefined];
4728
+ for (const profileId of targets) {
4729
+ actions.push({
4730
+ description: profileId ? `Run browser profile proof for ${profileId} to collect microphone, WebSocket, live-latency, and provider traces.` : "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
4731
+ href: appendRealCallRecoveryActionQuery(options.browserProofHref ?? "/voice/browser-call-profiles", { profileId }),
4732
+ id: "collect-browser-proof",
4733
+ label: profileId ? `Run browser profile proof for ${profileId}` : "Run browser profile proof",
4734
+ profileId
4735
+ });
4736
+ actions.push({
4737
+ description: profileId ? `Run phone profile proof for ${profileId} when the profile depends on carrier, telephony media, or noisy-call evidence.` : "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
4738
+ href: appendRealCallRecoveryActionQuery(options.phoneProofHref ?? "/api/voice/phone/smoke", { profileId }),
4739
+ id: "collect-phone-proof",
4740
+ label: profileId ? `Run phone profile proof for ${profileId}` : "Run phone profile proof",
4741
+ profileId
4742
+ });
4743
+ }
4727
4744
  }
4728
4745
  if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
4729
4746
  actions.push({
@@ -5573,22 +5590,22 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
5573
5590
  productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
5574
5591
  }).map((action) => ({
5575
5592
  ...action,
5576
- href: action.id === "collect-browser-proof" ? actionPath("collect-browser-proof") : action.id === "collect-phone-proof" ? actionPath("collect-phone-proof") : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
5593
+ 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,
5577
5594
  method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
5578
5595
  }));
5579
5596
  return { actions, generatedAt: new Date().toISOString(), report };
5580
5597
  };
5581
- const runActionHandler = async (actionId, report) => {
5598
+ const runActionHandler = async (actionId, report, profileId) => {
5582
5599
  const handler = options.handlers?.[actionId];
5583
5600
  if (!handler) {
5584
5601
  return;
5585
5602
  }
5586
- return await handler({ actionId, report });
5603
+ return await handler({ actionId, profileId, report });
5587
5604
  };
5588
- const runActionAsJob = async (actionId, report) => {
5605
+ const runActionAsJob = async (actionId, report, profileId) => {
5589
5606
  const job = await options.jobStore?.create({
5590
5607
  actionId,
5591
- message: `Queued real-call profile recovery action: ${actionId}.`,
5608
+ message: `Queued real-call profile recovery action: ${actionId}${profileId ? ` for ${profileId}` : ""}.`,
5592
5609
  status: "queued"
5593
5610
  });
5594
5611
  if (!job) {
@@ -5604,7 +5621,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
5604
5621
  updatedAt: startedAt
5605
5622
  });
5606
5623
  try {
5607
- const result = await runActionHandler(actionId, report);
5624
+ const result = await runActionHandler(actionId, report, profileId);
5608
5625
  const completedAt = new Date().toISOString();
5609
5626
  const ok = result?.ok ?? true;
5610
5627
  const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
@@ -5639,7 +5656,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
5639
5656
  status: "pass"
5640
5657
  };
5641
5658
  };
5642
- const runAction = async (actionId) => {
5659
+ const runAction = async (actionId, profileId) => {
5643
5660
  const report = await loadReport();
5644
5661
  const handler = options.handlers?.[actionId];
5645
5662
  if (!handler) {
@@ -5652,12 +5669,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
5652
5669
  };
5653
5670
  }
5654
5671
  if (options.jobStore && asyncActionIds.has(actionId)) {
5655
- const queued = await runActionAsJob(actionId, report);
5672
+ const queued = await runActionAsJob(actionId, report, profileId);
5656
5673
  if (queued) {
5657
5674
  return queued;
5658
5675
  }
5659
5676
  }
5660
- const result = await runActionHandler(actionId, report);
5677
+ const result = await runActionHandler(actionId, report, profileId);
5661
5678
  return {
5662
5679
  actionId,
5663
5680
  generatedAt: new Date().toISOString(),
@@ -5716,8 +5733,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
5716
5733
  });
5717
5734
  });
5718
5735
  for (const actionId of Object.keys(realCallProfileActionPaths)) {
5719
- routes.post(actionPath(actionId), async ({ set }) => {
5720
- const result = await runAction(actionId);
5736
+ routes.post(actionPath(actionId), async ({
5737
+ query,
5738
+ set
5739
+ }) => {
5740
+ const profileId = query.profileId?.trim() || undefined;
5741
+ const result = await runAction(actionId, profileId);
5721
5742
  if (!result.ok) {
5722
5743
  set.status = 501;
5723
5744
  }
package/dist/index.js CHANGED
@@ -16137,7 +16137,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
16137
16137
  var uniqueRealCallProfileActions = (actions) => {
16138
16138
  const seen = new Set;
16139
16139
  return actions.filter((action) => {
16140
- const key = `${action.method ?? "GET"}:${action.href}:${action.label}`;
16140
+ const key = `${action.method ?? "GET"}:${action.href}:${action.label}:${action.profileId ?? ""}`;
16141
16141
  if (seen.has(key)) {
16142
16142
  return false;
16143
16143
  }
@@ -16145,6 +16145,16 @@ var uniqueRealCallProfileActions = (actions) => {
16145
16145
  return true;
16146
16146
  });
16147
16147
  };
16148
+ var appendRealCallRecoveryActionQuery = (href, query) => {
16149
+ const entries = Object.entries(query).filter((entry) => entry[1] !== undefined);
16150
+ if (entries.length === 0) {
16151
+ return href;
16152
+ }
16153
+ const [base = href, hash = ""] = href.split("#");
16154
+ const separator = base.includes("?") ? "&" : "?";
16155
+ const search = new URLSearchParams(entries).toString();
16156
+ return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
16157
+ };
16148
16158
  var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
16149
16159
  const actions = [
16150
16160
  {
@@ -16180,19 +16190,26 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
16180
16190
  return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
16181
16191
  });
16182
16192
  const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
16183
- if (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) {
16184
- actions.push({
16185
- description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
16186
- href: options.browserProofHref ?? "/voice/browser-call-profiles",
16187
- id: "collect-browser-proof",
16188
- label: "Run browser profile proof"
16189
- });
16190
- actions.push({
16191
- description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
16192
- href: options.phoneProofHref ?? "/api/voice/phone/smoke",
16193
- id: "collect-phone-proof",
16194
- label: "Run phone profile proof"
16195
- });
16193
+ 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;
16194
+ if (needsProfileProof) {
16195
+ const targetProfileIds = missingProfiles.length > 0 || missingDepthProfiles.length > 0 ? [...new Set([...missingProfiles, ...missingDepthProfiles])] : [...requiredProfiles];
16196
+ const targets = targetProfileIds.length > 0 ? targetProfileIds : [undefined];
16197
+ for (const profileId of targets) {
16198
+ actions.push({
16199
+ description: profileId ? `Run browser profile proof for ${profileId} to collect microphone, WebSocket, live-latency, and provider traces.` : "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
16200
+ href: appendRealCallRecoveryActionQuery(options.browserProofHref ?? "/voice/browser-call-profiles", { profileId }),
16201
+ id: "collect-browser-proof",
16202
+ label: profileId ? `Run browser profile proof for ${profileId}` : "Run browser profile proof",
16203
+ profileId
16204
+ });
16205
+ actions.push({
16206
+ description: profileId ? `Run phone profile proof for ${profileId} when the profile depends on carrier, telephony media, or noisy-call evidence.` : "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
16207
+ href: appendRealCallRecoveryActionQuery(options.phoneProofHref ?? "/api/voice/phone/smoke", { profileId }),
16208
+ id: "collect-phone-proof",
16209
+ label: profileId ? `Run phone profile proof for ${profileId}` : "Run phone profile proof",
16210
+ profileId
16211
+ });
16212
+ }
16196
16213
  }
16197
16214
  if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
16198
16215
  actions.push({
@@ -17042,22 +17059,22 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
17042
17059
  productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
17043
17060
  }).map((action) => ({
17044
17061
  ...action,
17045
- href: action.id === "collect-browser-proof" ? actionPath("collect-browser-proof") : action.id === "collect-phone-proof" ? actionPath("collect-phone-proof") : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
17062
+ 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,
17046
17063
  method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
17047
17064
  }));
17048
17065
  return { actions, generatedAt: new Date().toISOString(), report };
17049
17066
  };
17050
- const runActionHandler = async (actionId, report) => {
17067
+ const runActionHandler = async (actionId, report, profileId) => {
17051
17068
  const handler = options.handlers?.[actionId];
17052
17069
  if (!handler) {
17053
17070
  return;
17054
17071
  }
17055
- return await handler({ actionId, report });
17072
+ return await handler({ actionId, profileId, report });
17056
17073
  };
17057
- const runActionAsJob = async (actionId, report) => {
17074
+ const runActionAsJob = async (actionId, report, profileId) => {
17058
17075
  const job = await options.jobStore?.create({
17059
17076
  actionId,
17060
- message: `Queued real-call profile recovery action: ${actionId}.`,
17077
+ message: `Queued real-call profile recovery action: ${actionId}${profileId ? ` for ${profileId}` : ""}.`,
17061
17078
  status: "queued"
17062
17079
  });
17063
17080
  if (!job) {
@@ -17073,7 +17090,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
17073
17090
  updatedAt: startedAt
17074
17091
  });
17075
17092
  try {
17076
- const result = await runActionHandler(actionId, report);
17093
+ const result = await runActionHandler(actionId, report, profileId);
17077
17094
  const completedAt = new Date().toISOString();
17078
17095
  const ok = result?.ok ?? true;
17079
17096
  const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
@@ -17108,7 +17125,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
17108
17125
  status: "pass"
17109
17126
  };
17110
17127
  };
17111
- const runAction = async (actionId) => {
17128
+ const runAction = async (actionId, profileId) => {
17112
17129
  const report = await loadReport();
17113
17130
  const handler = options.handlers?.[actionId];
17114
17131
  if (!handler) {
@@ -17121,12 +17138,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
17121
17138
  };
17122
17139
  }
17123
17140
  if (options.jobStore && asyncActionIds.has(actionId)) {
17124
- const queued = await runActionAsJob(actionId, report);
17141
+ const queued = await runActionAsJob(actionId, report, profileId);
17125
17142
  if (queued) {
17126
17143
  return queued;
17127
17144
  }
17128
17145
  }
17129
- const result = await runActionHandler(actionId, report);
17146
+ const result = await runActionHandler(actionId, report, profileId);
17130
17147
  return {
17131
17148
  actionId,
17132
17149
  generatedAt: new Date().toISOString(),
@@ -17185,8 +17202,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
17185
17202
  });
17186
17203
  });
17187
17204
  for (const actionId of Object.keys(realCallProfileActionPaths)) {
17188
- routes.post(actionPath(actionId), async ({ set }) => {
17189
- const result = await runAction(actionId);
17205
+ routes.post(actionPath(actionId), async ({
17206
+ query,
17207
+ set
17208
+ }) => {
17209
+ const profileId = query.profileId?.trim() || undefined;
17210
+ const result = await runAction(actionId, profileId);
17190
17211
  if (!result.ok) {
17191
17212
  set.status = 501;
17192
17213
  }
@@ -377,6 +377,7 @@ export type VoiceRealCallProfileHistoryRoutesOptions = Omit<VoiceRealCallProfile
377
377
  export type VoiceRealCallProfileRecoveryActionId = 'collect-browser-proof' | 'collect-phone-proof' | 'collect-provider-role-evidence' | 'refresh';
378
378
  export type VoiceRealCallProfileRecoveryAction = VoiceProductionReadinessAction & {
379
379
  id: VoiceRealCallProfileRecoveryActionId;
380
+ profileId?: string;
380
381
  };
381
382
  export type VoiceRealCallProfileReadinessCheckOptions = {
382
383
  browserProofHref?: string;
@@ -409,6 +410,7 @@ export type VoiceRealCallProfileRecoveryJobHistoryCheckOptions = {
409
410
  };
410
411
  export type VoiceRealCallProfileRecoveryActionHandlerInput = {
411
412
  actionId: VoiceRealCallProfileRecoveryActionId;
413
+ profileId?: string;
412
414
  report: VoiceRealCallProfileHistoryReport;
413
415
  };
414
416
  export type VoiceRealCallProfileRecoveryActionResult = {
@@ -2255,7 +2255,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
2255
2255
  var uniqueRealCallProfileActions = (actions) => {
2256
2256
  const seen = new Set;
2257
2257
  return actions.filter((action) => {
2258
- const key = `${action.method ?? "GET"}:${action.href}:${action.label}`;
2258
+ const key = `${action.method ?? "GET"}:${action.href}:${action.label}:${action.profileId ?? ""}`;
2259
2259
  if (seen.has(key)) {
2260
2260
  return false;
2261
2261
  }
@@ -2263,6 +2263,16 @@ var uniqueRealCallProfileActions = (actions) => {
2263
2263
  return true;
2264
2264
  });
2265
2265
  };
2266
+ var appendRealCallRecoveryActionQuery = (href, query) => {
2267
+ const entries = Object.entries(query).filter((entry) => entry[1] !== undefined);
2268
+ if (entries.length === 0) {
2269
+ return href;
2270
+ }
2271
+ const [base = href, hash = ""] = href.split("#");
2272
+ const separator = base.includes("?") ? "&" : "?";
2273
+ const search = new URLSearchParams(entries).toString();
2274
+ return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
2275
+ };
2266
2276
  var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
2267
2277
  const actions = [
2268
2278
  {
@@ -2298,19 +2308,26 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
2298
2308
  return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
2299
2309
  });
2300
2310
  const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
2301
- if (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) {
2302
- actions.push({
2303
- description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
2304
- href: options.browserProofHref ?? "/voice/browser-call-profiles",
2305
- id: "collect-browser-proof",
2306
- label: "Run browser profile proof"
2307
- });
2308
- actions.push({
2309
- description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
2310
- href: options.phoneProofHref ?? "/api/voice/phone/smoke",
2311
- id: "collect-phone-proof",
2312
- label: "Run phone profile proof"
2313
- });
2311
+ 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;
2312
+ if (needsProfileProof) {
2313
+ const targetProfileIds = missingProfiles.length > 0 || missingDepthProfiles.length > 0 ? [...new Set([...missingProfiles, ...missingDepthProfiles])] : [...requiredProfiles];
2314
+ const targets = targetProfileIds.length > 0 ? targetProfileIds : [undefined];
2315
+ for (const profileId of targets) {
2316
+ actions.push({
2317
+ description: profileId ? `Run browser profile proof for ${profileId} to collect microphone, WebSocket, live-latency, and provider traces.` : "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
2318
+ href: appendRealCallRecoveryActionQuery(options.browserProofHref ?? "/voice/browser-call-profiles", { profileId }),
2319
+ id: "collect-browser-proof",
2320
+ label: profileId ? `Run browser profile proof for ${profileId}` : "Run browser profile proof",
2321
+ profileId
2322
+ });
2323
+ actions.push({
2324
+ description: profileId ? `Run phone profile proof for ${profileId} when the profile depends on carrier, telephony media, or noisy-call evidence.` : "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
2325
+ href: appendRealCallRecoveryActionQuery(options.phoneProofHref ?? "/api/voice/phone/smoke", { profileId }),
2326
+ id: "collect-phone-proof",
2327
+ label: profileId ? `Run phone profile proof for ${profileId}` : "Run phone profile proof",
2328
+ profileId
2329
+ });
2330
+ }
2314
2331
  }
2315
2332
  if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
2316
2333
  actions.push({
@@ -3160,22 +3177,22 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3160
3177
  productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
3161
3178
  }).map((action) => ({
3162
3179
  ...action,
3163
- href: action.id === "collect-browser-proof" ? actionPath("collect-browser-proof") : action.id === "collect-phone-proof" ? actionPath("collect-phone-proof") : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
3180
+ 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,
3164
3181
  method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
3165
3182
  }));
3166
3183
  return { actions, generatedAt: new Date().toISOString(), report };
3167
3184
  };
3168
- const runActionHandler = async (actionId, report) => {
3185
+ const runActionHandler = async (actionId, report, profileId) => {
3169
3186
  const handler = options.handlers?.[actionId];
3170
3187
  if (!handler) {
3171
3188
  return;
3172
3189
  }
3173
- return await handler({ actionId, report });
3190
+ return await handler({ actionId, profileId, report });
3174
3191
  };
3175
- const runActionAsJob = async (actionId, report) => {
3192
+ const runActionAsJob = async (actionId, report, profileId) => {
3176
3193
  const job = await options.jobStore?.create({
3177
3194
  actionId,
3178
- message: `Queued real-call profile recovery action: ${actionId}.`,
3195
+ message: `Queued real-call profile recovery action: ${actionId}${profileId ? ` for ${profileId}` : ""}.`,
3179
3196
  status: "queued"
3180
3197
  });
3181
3198
  if (!job) {
@@ -3191,7 +3208,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3191
3208
  updatedAt: startedAt
3192
3209
  });
3193
3210
  try {
3194
- const result = await runActionHandler(actionId, report);
3211
+ const result = await runActionHandler(actionId, report, profileId);
3195
3212
  const completedAt = new Date().toISOString();
3196
3213
  const ok = result?.ok ?? true;
3197
3214
  const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
@@ -3226,7 +3243,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3226
3243
  status: "pass"
3227
3244
  };
3228
3245
  };
3229
- const runAction = async (actionId) => {
3246
+ const runAction = async (actionId, profileId) => {
3230
3247
  const report = await loadReport();
3231
3248
  const handler = options.handlers?.[actionId];
3232
3249
  if (!handler) {
@@ -3239,12 +3256,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3239
3256
  };
3240
3257
  }
3241
3258
  if (options.jobStore && asyncActionIds.has(actionId)) {
3242
- const queued = await runActionAsJob(actionId, report);
3259
+ const queued = await runActionAsJob(actionId, report, profileId);
3243
3260
  if (queued) {
3244
3261
  return queued;
3245
3262
  }
3246
3263
  }
3247
- const result = await runActionHandler(actionId, report);
3264
+ const result = await runActionHandler(actionId, report, profileId);
3248
3265
  return {
3249
3266
  actionId,
3250
3267
  generatedAt: new Date().toISOString(),
@@ -3303,8 +3320,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3303
3320
  });
3304
3321
  });
3305
3322
  for (const actionId of Object.keys(realCallProfileActionPaths)) {
3306
- routes.post(actionPath(actionId), async ({ set }) => {
3307
- const result = await runAction(actionId);
3323
+ routes.post(actionPath(actionId), async ({
3324
+ query,
3325
+ set
3326
+ }) => {
3327
+ const profileId = query.profileId?.trim() || undefined;
3328
+ const result = await runAction(actionId, profileId);
3308
3329
  if (!result.ok) {
3309
3330
  set.status = 501;
3310
3331
  }
package/dist/vue/index.js CHANGED
@@ -2176,7 +2176,7 @@ var buildRealCallProfileReadinessIssues = (report, options) => {
2176
2176
  var uniqueRealCallProfileActions = (actions) => {
2177
2177
  const seen = new Set;
2178
2178
  return actions.filter((action) => {
2179
- const key = `${action.method ?? "GET"}:${action.href}:${action.label}`;
2179
+ const key = `${action.method ?? "GET"}:${action.href}:${action.label}:${action.profileId ?? ""}`;
2180
2180
  if (seen.has(key)) {
2181
2181
  return false;
2182
2182
  }
@@ -2184,6 +2184,16 @@ var uniqueRealCallProfileActions = (actions) => {
2184
2184
  return true;
2185
2185
  });
2186
2186
  };
2187
+ var appendRealCallRecoveryActionQuery = (href, query) => {
2188
+ const entries = Object.entries(query).filter((entry) => entry[1] !== undefined);
2189
+ if (entries.length === 0) {
2190
+ return href;
2191
+ }
2192
+ const [base = href, hash = ""] = href.split("#");
2193
+ const separator = base.includes("?") ? "&" : "?";
2194
+ const search = new URLSearchParams(entries).toString();
2195
+ return `${base}${separator}${search}${hash ? `#${hash}` : ""}`;
2196
+ };
2187
2197
  var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
2188
2198
  const actions = [
2189
2199
  {
@@ -2219,19 +2229,26 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
2219
2229
  return requiredSurfaces.some((surface) => !observedSurfaces.has(surface));
2220
2230
  });
2221
2231
  const ageMs = report.trend.ageMs ?? (report.generatedAt ? Date.now() - new Date(report.generatedAt).getTime() : undefined);
2222
- if (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) {
2223
- actions.push({
2224
- description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
2225
- href: options.browserProofHref ?? "/voice/browser-call-profiles",
2226
- id: "collect-browser-proof",
2227
- label: "Run browser profile proof"
2228
- });
2229
- actions.push({
2230
- description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
2231
- href: options.phoneProofHref ?? "/api/voice/phone/smoke",
2232
- id: "collect-phone-proof",
2233
- label: "Run phone profile proof"
2234
- });
2232
+ 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;
2233
+ if (needsProfileProof) {
2234
+ const targetProfileIds = missingProfiles.length > 0 || missingDepthProfiles.length > 0 ? [...new Set([...missingProfiles, ...missingDepthProfiles])] : [...requiredProfiles];
2235
+ const targets = targetProfileIds.length > 0 ? targetProfileIds : [undefined];
2236
+ for (const profileId of targets) {
2237
+ actions.push({
2238
+ description: profileId ? `Run browser profile proof for ${profileId} to collect microphone, WebSocket, live-latency, and provider traces.` : "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
2239
+ href: appendRealCallRecoveryActionQuery(options.browserProofHref ?? "/voice/browser-call-profiles", { profileId }),
2240
+ id: "collect-browser-proof",
2241
+ label: profileId ? `Run browser profile proof for ${profileId}` : "Run browser profile proof",
2242
+ profileId
2243
+ });
2244
+ actions.push({
2245
+ description: profileId ? `Run phone profile proof for ${profileId} when the profile depends on carrier, telephony media, or noisy-call evidence.` : "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
2246
+ href: appendRealCallRecoveryActionQuery(options.phoneProofHref ?? "/api/voice/phone/smoke", { profileId }),
2247
+ id: "collect-phone-proof",
2248
+ label: profileId ? `Run phone profile proof for ${profileId}` : "Run phone profile proof",
2249
+ profileId
2250
+ });
2251
+ }
2235
2252
  }
2236
2253
  if (options.maxAgeMs !== undefined && (ageMs === undefined || ageMs > options.maxAgeMs)) {
2237
2254
  actions.push({
@@ -3081,22 +3098,22 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3081
3098
  productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
3082
3099
  }).map((action) => ({
3083
3100
  ...action,
3084
- href: action.id === "collect-browser-proof" ? actionPath("collect-browser-proof") : action.id === "collect-phone-proof" ? actionPath("collect-phone-proof") : action.id === "collect-provider-role-evidence" ? actionPath("collect-provider-role-evidence") : action.href,
3101
+ 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,
3085
3102
  method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
3086
3103
  }));
3087
3104
  return { actions, generatedAt: new Date().toISOString(), report };
3088
3105
  };
3089
- const runActionHandler = async (actionId, report) => {
3106
+ const runActionHandler = async (actionId, report, profileId) => {
3090
3107
  const handler = options.handlers?.[actionId];
3091
3108
  if (!handler) {
3092
3109
  return;
3093
3110
  }
3094
- return await handler({ actionId, report });
3111
+ return await handler({ actionId, profileId, report });
3095
3112
  };
3096
- const runActionAsJob = async (actionId, report) => {
3113
+ const runActionAsJob = async (actionId, report, profileId) => {
3097
3114
  const job = await options.jobStore?.create({
3098
3115
  actionId,
3099
- message: `Queued real-call profile recovery action: ${actionId}.`,
3116
+ message: `Queued real-call profile recovery action: ${actionId}${profileId ? ` for ${profileId}` : ""}.`,
3100
3117
  status: "queued"
3101
3118
  });
3102
3119
  if (!job) {
@@ -3112,7 +3129,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3112
3129
  updatedAt: startedAt
3113
3130
  });
3114
3131
  try {
3115
- const result = await runActionHandler(actionId, report);
3132
+ const result = await runActionHandler(actionId, report, profileId);
3116
3133
  const completedAt = new Date().toISOString();
3117
3134
  const ok = result?.ok ?? true;
3118
3135
  const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
@@ -3147,7 +3164,7 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3147
3164
  status: "pass"
3148
3165
  };
3149
3166
  };
3150
- const runAction = async (actionId) => {
3167
+ const runAction = async (actionId, profileId) => {
3151
3168
  const report = await loadReport();
3152
3169
  const handler = options.handlers?.[actionId];
3153
3170
  if (!handler) {
@@ -3160,12 +3177,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3160
3177
  };
3161
3178
  }
3162
3179
  if (options.jobStore && asyncActionIds.has(actionId)) {
3163
- const queued = await runActionAsJob(actionId, report);
3180
+ const queued = await runActionAsJob(actionId, report, profileId);
3164
3181
  if (queued) {
3165
3182
  return queued;
3166
3183
  }
3167
3184
  }
3168
- const result = await runActionHandler(actionId, report);
3185
+ const result = await runActionHandler(actionId, report, profileId);
3169
3186
  return {
3170
3187
  actionId,
3171
3188
  generatedAt: new Date().toISOString(),
@@ -3224,8 +3241,12 @@ var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
3224
3241
  });
3225
3242
  });
3226
3243
  for (const actionId of Object.keys(realCallProfileActionPaths)) {
3227
- routes.post(actionPath(actionId), async ({ set }) => {
3228
- const result = await runAction(actionId);
3244
+ routes.post(actionPath(actionId), async ({
3245
+ query,
3246
+ set
3247
+ }) => {
3248
+ const profileId = query.profileId?.trim() || undefined;
3249
+ const result = await runAction(actionId, profileId);
3229
3250
  if (!result.ok) {
3230
3251
  set.status = 501;
3231
3252
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.381",
3
+ "version": "0.0.22-beta.382",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",