@absolutejs/voice 0.0.22-beta.371 → 0.0.22-beta.373
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/README.md +33 -0
- package/dist/client/index.js +202 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +204 -0
- package/dist/proofTrends.d.ts +84 -1
- package/dist/react/index.js +202 -0
- package/dist/vue/index.js +202 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1504,6 +1504,39 @@ createVoiceProductionReadinessRoutes({
|
|
|
1504
1504
|
|
|
1505
1505
|
The readiness check includes recovery actions from `buildVoiceRealCallProfileRecoveryActions(...)`, so failed gates can point operators at the profile history report, browser/phone proof, missing provider-role evidence, operations records, and production-readiness refresh instead of only saying "failed."
|
|
1506
1506
|
|
|
1507
|
+
Mount `createVoiceRealCallProfileRecoveryActionRoutes(...)` when those actions should be executable. The package owns the route contract and result shape; the app supplies safe handlers:
|
|
1508
|
+
|
|
1509
|
+
```ts
|
|
1510
|
+
app.use(
|
|
1511
|
+
createVoiceRealCallProfileRecoveryActionRoutes({
|
|
1512
|
+
handlers: {
|
|
1513
|
+
'collect-browser-proof': async () => runBrowserProfileProof(),
|
|
1514
|
+
'collect-phone-proof': async () => runPhoneProfileProof(),
|
|
1515
|
+
refresh: async () => refreshReadinessProof()
|
|
1516
|
+
},
|
|
1517
|
+
source: buildRealCallHistory
|
|
1518
|
+
})
|
|
1519
|
+
);
|
|
1520
|
+
```
|
|
1521
|
+
|
|
1522
|
+
For longer-running proof collection, add a job store and mark selected actions async. The POST returns a `jobId` with `jobStatus: "queued"`, and the app can poll `${path}/actions/:jobId`:
|
|
1523
|
+
|
|
1524
|
+
```ts
|
|
1525
|
+
const recoveryJobs = createVoiceInMemoryRealCallProfileRecoveryJobStore();
|
|
1526
|
+
|
|
1527
|
+
app.use(
|
|
1528
|
+
createVoiceRealCallProfileRecoveryActionRoutes({
|
|
1529
|
+
asyncActionIds: ['collect-browser-proof', 'collect-phone-proof'],
|
|
1530
|
+
handlers: {
|
|
1531
|
+
'collect-browser-proof': async () => runBrowserProfileProof(),
|
|
1532
|
+
'collect-phone-proof': async () => runPhoneProfileProof()
|
|
1533
|
+
},
|
|
1534
|
+
jobStore: recoveryJobs,
|
|
1535
|
+
source: buildRealCallHistory
|
|
1536
|
+
})
|
|
1537
|
+
);
|
|
1538
|
+
```
|
|
1539
|
+
|
|
1507
1540
|
Use `createVoiceProfileTraceTagger(...)` when the app already has a trace store and needs every appended trace to carry a benchmark profile label. It wraps any `VoiceTraceEventStore`, preserves the underlying store behavior, and adds `profileId`/`benchmarkProfileId` metadata and payload fields that real-call profile history can ingest later.
|
|
1508
1541
|
|
|
1509
1542
|
```ts
|
package/dist/client/index.js
CHANGED
|
@@ -4571,11 +4571,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4571
4571
|
{
|
|
4572
4572
|
description: "Open the current real-call profile history report and profile defaults.",
|
|
4573
4573
|
href: options.href ?? "/voice/real-call-profile-history",
|
|
4574
|
+
id: "refresh",
|
|
4574
4575
|
label: "Open real-call profile history"
|
|
4575
4576
|
},
|
|
4576
4577
|
{
|
|
4577
4578
|
description: "Refresh production readiness after collecting or replaying profile evidence.",
|
|
4578
4579
|
href: options.productionReadinessHref ?? "/production-readiness",
|
|
4580
|
+
id: "refresh",
|
|
4579
4581
|
label: "Refresh production readiness"
|
|
4580
4582
|
}
|
|
4581
4583
|
];
|
|
@@ -4589,11 +4591,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4589
4591
|
actions.push({
|
|
4590
4592
|
description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
|
|
4591
4593
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
4594
|
+
id: "collect-browser-proof",
|
|
4592
4595
|
label: "Run browser profile proof"
|
|
4593
4596
|
});
|
|
4594
4597
|
actions.push({
|
|
4595
4598
|
description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
|
|
4596
4599
|
href: options.phoneProofHref ?? "/api/voice/phone/smoke",
|
|
4600
|
+
id: "collect-phone-proof",
|
|
4597
4601
|
label: "Run phone profile proof"
|
|
4598
4602
|
});
|
|
4599
4603
|
}
|
|
@@ -4601,6 +4605,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4601
4605
|
actions.push({
|
|
4602
4606
|
description: "Collect fresh real-call profile traces because the current history artifact is stale.",
|
|
4603
4607
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
4608
|
+
id: "collect-browser-proof",
|
|
4604
4609
|
label: "Collect fresh profile evidence"
|
|
4605
4610
|
});
|
|
4606
4611
|
}
|
|
@@ -4608,6 +4613,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4608
4613
|
actions.push({
|
|
4609
4614
|
description: "Collect missing LLM/STT/TTS provider-role evidence so profile defaults can become actionable.",
|
|
4610
4615
|
href: options.sourceHref ?? "/api/voice/real-call-profile-history",
|
|
4616
|
+
id: "collect-provider-role-evidence",
|
|
4611
4617
|
label: "Collect missing provider-role evidence"
|
|
4612
4618
|
});
|
|
4613
4619
|
}
|
|
@@ -4615,11 +4621,48 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
4615
4621
|
actions.push({
|
|
4616
4622
|
description: "Open operations records to inspect the sessions behind failing or warning profile evidence.",
|
|
4617
4623
|
href: options.operationsRecordsHref ?? "/voice-operations",
|
|
4624
|
+
id: "refresh",
|
|
4618
4625
|
label: "Open operations records"
|
|
4619
4626
|
});
|
|
4620
4627
|
}
|
|
4621
4628
|
return uniqueRealCallProfileActions(actions);
|
|
4622
4629
|
};
|
|
4630
|
+
var createVoiceInMemoryRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
4631
|
+
const jobs = new Map;
|
|
4632
|
+
const now = () => (options.now ?? (() => new Date))().toISOString();
|
|
4633
|
+
const createId = () => `${options.idPrefix ?? "voice-recovery-job"}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
4634
|
+
return {
|
|
4635
|
+
create(input) {
|
|
4636
|
+
const createdAt = input.createdAt ?? now();
|
|
4637
|
+
const job = {
|
|
4638
|
+
actionId: input.actionId,
|
|
4639
|
+
createdAt,
|
|
4640
|
+
id: input.id ?? createId(),
|
|
4641
|
+
message: input.message,
|
|
4642
|
+
status: input.status ?? "queued",
|
|
4643
|
+
updatedAt: createdAt
|
|
4644
|
+
};
|
|
4645
|
+
jobs.set(job.id, job);
|
|
4646
|
+
return job;
|
|
4647
|
+
},
|
|
4648
|
+
get(id) {
|
|
4649
|
+
return jobs.get(id);
|
|
4650
|
+
},
|
|
4651
|
+
update(id, update) {
|
|
4652
|
+
const existing = jobs.get(id);
|
|
4653
|
+
if (!existing) {
|
|
4654
|
+
return;
|
|
4655
|
+
}
|
|
4656
|
+
const next = {
|
|
4657
|
+
...existing,
|
|
4658
|
+
...update,
|
|
4659
|
+
updatedAt: update.updatedAt ?? now()
|
|
4660
|
+
};
|
|
4661
|
+
jobs.set(id, next);
|
|
4662
|
+
return next;
|
|
4663
|
+
}
|
|
4664
|
+
};
|
|
4665
|
+
};
|
|
4623
4666
|
var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
4624
4667
|
const { issues, warnings } = buildRealCallProfileReadinessIssues(report, options);
|
|
4625
4668
|
const status = issues.length > 0 ? "fail" : warnings.length > 0 && options.failOnWarnings === true ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
@@ -5217,6 +5260,165 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
5217
5260
|
}
|
|
5218
5261
|
return routes;
|
|
5219
5262
|
};
|
|
5263
|
+
var realCallProfileActionPaths = {
|
|
5264
|
+
"collect-browser-proof": "/collect-browser-proof",
|
|
5265
|
+
"collect-phone-proof": "/collect-phone-proof",
|
|
5266
|
+
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
5267
|
+
refresh: "/refresh"
|
|
5268
|
+
};
|
|
5269
|
+
var loadVoiceRealCallProfileHistoryRouteReport = async (options) => {
|
|
5270
|
+
const { source, ...routeOptions } = options;
|
|
5271
|
+
const sourceOptions = source === undefined ? routeOptions : typeof source === "function" ? await source() : source;
|
|
5272
|
+
return buildVoiceRealCallProfileHistoryReport({
|
|
5273
|
+
...routeOptions,
|
|
5274
|
+
...sourceOptions
|
|
5275
|
+
});
|
|
5276
|
+
};
|
|
5277
|
+
var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
5278
|
+
const path = options.path ?? "/api/voice/real-call-profile-history";
|
|
5279
|
+
const routes = new Elysia({
|
|
5280
|
+
name: options.name ?? "absolutejs-voice-real-call-profile-recovery-actions"
|
|
5281
|
+
});
|
|
5282
|
+
const actionPath = (actionId) => `${path}${realCallProfileActionPaths[actionId]}`;
|
|
5283
|
+
const loadReport = () => loadVoiceRealCallProfileHistoryRouteReport(options);
|
|
5284
|
+
const asyncActionIds = new Set(options.asyncActionIds ?? []);
|
|
5285
|
+
const listActions = async () => {
|
|
5286
|
+
const report = await loadReport();
|
|
5287
|
+
const actions = buildVoiceRealCallProfileRecoveryActions(report, {
|
|
5288
|
+
...options,
|
|
5289
|
+
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
5290
|
+
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
5291
|
+
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
5292
|
+
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
5293
|
+
}).map((action) => ({
|
|
5294
|
+
...action,
|
|
5295
|
+
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,
|
|
5296
|
+
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
5297
|
+
}));
|
|
5298
|
+
return { actions, generatedAt: new Date().toISOString(), report };
|
|
5299
|
+
};
|
|
5300
|
+
const runActionHandler = async (actionId, report) => {
|
|
5301
|
+
const handler = options.handlers?.[actionId];
|
|
5302
|
+
if (!handler) {
|
|
5303
|
+
return;
|
|
5304
|
+
}
|
|
5305
|
+
return await handler({ actionId, report });
|
|
5306
|
+
};
|
|
5307
|
+
const runActionAsJob = async (actionId, report) => {
|
|
5308
|
+
const job = await options.jobStore?.create({
|
|
5309
|
+
actionId,
|
|
5310
|
+
message: `Queued real-call profile recovery action: ${actionId}.`,
|
|
5311
|
+
status: "queued"
|
|
5312
|
+
});
|
|
5313
|
+
if (!job) {
|
|
5314
|
+
return;
|
|
5315
|
+
}
|
|
5316
|
+
queueMicrotask(() => {
|
|
5317
|
+
(async () => {
|
|
5318
|
+
const startedAt = new Date().toISOString();
|
|
5319
|
+
await options.jobStore?.update(job.id, {
|
|
5320
|
+
message: `Running real-call profile recovery action: ${actionId}.`,
|
|
5321
|
+
startedAt,
|
|
5322
|
+
status: "running",
|
|
5323
|
+
updatedAt: startedAt
|
|
5324
|
+
});
|
|
5325
|
+
try {
|
|
5326
|
+
const result = await runActionHandler(actionId, report);
|
|
5327
|
+
const completedAt = new Date().toISOString();
|
|
5328
|
+
const ok = result?.ok ?? true;
|
|
5329
|
+
const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
|
|
5330
|
+
await options.jobStore?.update(job.id, {
|
|
5331
|
+
completedAt,
|
|
5332
|
+
message: result?.message ?? `Completed real-call profile recovery action: ${actionId}.`,
|
|
5333
|
+
ok,
|
|
5334
|
+
report: result?.report,
|
|
5335
|
+
status,
|
|
5336
|
+
updatedAt: completedAt
|
|
5337
|
+
});
|
|
5338
|
+
} catch (error) {
|
|
5339
|
+
const completedAt = new Date().toISOString();
|
|
5340
|
+
await options.jobStore?.update(job.id, {
|
|
5341
|
+
completedAt,
|
|
5342
|
+
message: error instanceof Error ? error.message : `Failed real-call profile recovery action: ${actionId}.`,
|
|
5343
|
+
ok: false,
|
|
5344
|
+
status: "fail",
|
|
5345
|
+
updatedAt: completedAt
|
|
5346
|
+
});
|
|
5347
|
+
}
|
|
5348
|
+
})();
|
|
5349
|
+
});
|
|
5350
|
+
return {
|
|
5351
|
+
actionId,
|
|
5352
|
+
generatedAt: new Date().toISOString(),
|
|
5353
|
+
job,
|
|
5354
|
+
jobId: job.id,
|
|
5355
|
+
jobStatus: job.status,
|
|
5356
|
+
message: job.message,
|
|
5357
|
+
ok: true,
|
|
5358
|
+
status: "pass"
|
|
5359
|
+
};
|
|
5360
|
+
};
|
|
5361
|
+
const runAction = async (actionId) => {
|
|
5362
|
+
const report = await loadReport();
|
|
5363
|
+
const handler = options.handlers?.[actionId];
|
|
5364
|
+
if (!handler) {
|
|
5365
|
+
return {
|
|
5366
|
+
actionId,
|
|
5367
|
+
generatedAt: new Date().toISOString(),
|
|
5368
|
+
message: `No handler configured for real-call profile recovery action: ${actionId}.`,
|
|
5369
|
+
ok: false,
|
|
5370
|
+
status: "fail"
|
|
5371
|
+
};
|
|
5372
|
+
}
|
|
5373
|
+
if (options.jobStore && asyncActionIds.has(actionId)) {
|
|
5374
|
+
const queued = await runActionAsJob(actionId, report);
|
|
5375
|
+
if (queued) {
|
|
5376
|
+
return queued;
|
|
5377
|
+
}
|
|
5378
|
+
}
|
|
5379
|
+
const result = await runActionHandler(actionId, report);
|
|
5380
|
+
return {
|
|
5381
|
+
actionId,
|
|
5382
|
+
generatedAt: new Date().toISOString(),
|
|
5383
|
+
job: result?.job,
|
|
5384
|
+
jobId: result?.jobId,
|
|
5385
|
+
jobStatus: result?.jobStatus,
|
|
5386
|
+
message: result?.message,
|
|
5387
|
+
ok: result?.ok ?? true,
|
|
5388
|
+
report: result?.report,
|
|
5389
|
+
status: result?.status ?? "pass"
|
|
5390
|
+
};
|
|
5391
|
+
};
|
|
5392
|
+
routes.get(`${path}/actions`, async () => Response.json(await listActions(), { headers: options.headers }));
|
|
5393
|
+
routes.get(`${path}/actions/:jobId`, async ({
|
|
5394
|
+
params,
|
|
5395
|
+
set
|
|
5396
|
+
}) => {
|
|
5397
|
+
const jobId = params.jobId ?? "";
|
|
5398
|
+
const job = await options.jobStore?.get(jobId);
|
|
5399
|
+
if (!job) {
|
|
5400
|
+
set.status = 404;
|
|
5401
|
+
return Response.json({
|
|
5402
|
+
jobId,
|
|
5403
|
+
message: `No real-call profile recovery job found for id: ${jobId}.`,
|
|
5404
|
+
ok: false
|
|
5405
|
+
}, { headers: options.headers });
|
|
5406
|
+
}
|
|
5407
|
+
return Response.json({ job, ok: job.ok ?? job.status !== "fail" }, {
|
|
5408
|
+
headers: options.headers
|
|
5409
|
+
});
|
|
5410
|
+
});
|
|
5411
|
+
for (const actionId of Object.keys(realCallProfileActionPaths)) {
|
|
5412
|
+
routes.post(actionPath(actionId), async ({ set }) => {
|
|
5413
|
+
const result = await runAction(actionId);
|
|
5414
|
+
if (!result.ok) {
|
|
5415
|
+
set.status = 501;
|
|
5416
|
+
}
|
|
5417
|
+
return Response.json(result, { headers: options.headers });
|
|
5418
|
+
});
|
|
5419
|
+
}
|
|
5420
|
+
return routes;
|
|
5421
|
+
};
|
|
5220
5422
|
var createVoiceProofTrendRoutes = (options) => {
|
|
5221
5423
|
const path = options.path ?? "/api/voice/proof-trends";
|
|
5222
5424
|
const routes = new Elysia({
|
package/dist/index.d.ts
CHANGED
|
@@ -30,12 +30,12 @@ export { assertVoicePlatformCoverage, buildVoicePlatformCoverageSummary, createV
|
|
|
30
30
|
export { assertVoiceCompetitiveCoverage, buildVoiceCompetitiveCoverageReport, createVoiceCompetitiveCoverageRoutes, evaluateVoiceCompetitiveCoverage, renderVoiceCompetitiveCoverageHTML, renderVoiceCompetitiveCoverageMarkdown } from './competitiveCoverage';
|
|
31
31
|
export type { VoiceCompetitiveCoverageAssertionInput, VoiceCompetitiveCoverageAssertionReport, VoiceCompetitiveCoverageIssue, VoiceCompetitiveCoverageLevel, VoiceCompetitiveCoverageReport, VoiceCompetitiveCoverageReportInput, VoiceCompetitiveCoverageRoutesOptions, VoiceCompetitiveCoverageStatus, VoiceCompetitiveCoverageSummary, VoiceCompetitiveDepthLevel, VoiceCompetitiveEvidence, VoiceCompetitiveSurface } from './competitiveCoverage';
|
|
32
32
|
export type { VoicePlatformCoverageAssertionInput, VoicePlatformCoverageAssertionReport, VoicePlatformCoverageEvidence, VoicePlatformCoverageRoutesOptions, VoicePlatformCoverageStatus, VoicePlatformCoverageSummary, VoicePlatformCoverageSummaryInput, VoicePlatformCoverageSurface } from './platformCoverage';
|
|
33
|
-
export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReportFromRealCallProfiles, buildVoiceProofTrendReport, buildVoiceRealCallProfileEvidenceFromTraceEvents, buildVoiceRealCallProfileDefaults, buildVoiceRealCallProfileHistoryReport, buildVoiceRealCallProfileReadinessCheck, buildVoiceRealCallProfileRecoveryActions, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, createVoiceRealCallProfileHistoryRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, loadVoiceRealCallProfileEvidenceFromTraceStore, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown, renderVoiceRealCallProfileHistoryHTML, renderVoiceRealCallProfileHistoryMarkdown, resolveVoiceRealCallProfileProviderRoute } from './proofTrends';
|
|
33
|
+
export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReportFromRealCallProfiles, buildVoiceProofTrendReport, buildVoiceRealCallProfileEvidenceFromTraceEvents, buildVoiceRealCallProfileDefaults, buildVoiceRealCallProfileHistoryReport, buildVoiceRealCallProfileReadinessCheck, buildVoiceRealCallProfileRecoveryActions, createVoiceInMemoryRealCallProfileRecoveryJobStore, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, createVoiceRealCallProfileHistoryRoutes, createVoiceRealCallProfileRecoveryActionRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, loadVoiceRealCallProfileEvidenceFromTraceStore, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown, renderVoiceRealCallProfileHistoryHTML, renderVoiceRealCallProfileHistoryMarkdown, resolveVoiceRealCallProfileProviderRoute } from './proofTrends';
|
|
34
34
|
export { applyVoiceProfileSwitchGuard, buildVoiceProfileSwitchReadinessReport, buildVoiceProfileSwitchLiveDecisionReport, createVoiceProfileSwitchLiveDecisionRoutes, createVoiceProfileSwitchPolicyProofRoutes, createVoiceProfileSwitchReadinessRoutes, recommendVoiceProfileSwitch, renderVoiceProfileSwitchLiveDecisionHTML, renderVoiceProfileSwitchPolicyProofHTML, renderVoiceProfileSwitchReadinessHTML, runVoiceProfileSwitchPolicyProof } from './profileSwitchRecommendation';
|
|
35
35
|
export type { VoiceProfileSwitchGuardAction, VoiceProfileSwitchGuardDecision, VoiceProfileSwitchGuardMode, VoiceProfileSwitchGuardOptions, VoiceProfileSwitchObservedSignals, VoiceProfileSwitchLiveDecisionEvidence, VoiceProfileSwitchLiveDecisionReport, VoiceProfileSwitchLiveDecisionReportOptions, VoiceProfileSwitchLiveDecisionRoutesOptions, VoiceProfileSwitchLiveDecisionSession, VoiceProfileSwitchPolicyProofCase, VoiceProfileSwitchPolicyProofCaseResult, VoiceProfileSwitchPolicyProofOptions, VoiceProfileSwitchPolicyProofReport, VoiceProfileSwitchPolicyProofRoutesOptions, VoiceProfileSwitchReadinessIssue, VoiceProfileSwitchReadinessOptions, VoiceProfileSwitchReadinessReport, VoiceProfileSwitchReadinessRoutesOptions, VoiceProfileSwitchReadinessStatus, VoiceProfileSwitchRecommendation, VoiceProfileSwitchRecommendationOptions } from './profileSwitchRecommendation';
|
|
36
36
|
export { buildVoiceProviderDecisionTraceReport, createVoiceProviderDecisionTraceEvent, createVoiceProviderDecisionTraceRoutes, listVoiceProviderDecisionTraces, renderVoiceProviderDecisionTraceHTML, renderVoiceProviderDecisionTraceMarkdown } from './providerDecisionTraces';
|
|
37
37
|
export type { VoiceProviderDecisionStatus, VoiceProviderDecisionSurfaceReport, VoiceProviderDecisionTrace, VoiceProviderDecisionTraceInput, VoiceProviderDecisionTraceIssue, VoiceProviderDecisionTraceReport, VoiceProviderDecisionTraceReportOptions, VoiceProviderDecisionTraceRoutesOptions } from './providerDecisionTraces';
|
|
38
|
-
export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendRealCallProfileEvidence, VoiceProofTrendRealCallProfileReportOptions, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendRuntimeChannelSummary, VoiceProofTrendStatus, VoiceProofTrendSummary, VoiceRealCallProfileDefault, VoiceRealCallProfileDefaultsOptions, VoiceRealCallProfileDefaultsReport, VoiceRealCallProfileHistoryOptions, VoiceRealCallProfileHistoryReport, VoiceRealCallProfileHistoryRoutesOptions, VoiceRealCallProfileProviderRouteOptions, VoiceRealCallProfileReadinessCheckOptions, VoiceRealCallProfileRecoveryActionOptions, VoiceRealCallProfileTraceEvidenceOptions, VoiceRealCallProfileTraceStoreEvidenceOptions } from './proofTrends';
|
|
38
|
+
export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendRealCallProfileEvidence, VoiceProofTrendRealCallProfileReportOptions, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendRuntimeChannelSummary, VoiceProofTrendStatus, VoiceProofTrendSummary, VoiceRealCallProfileDefault, VoiceRealCallProfileDefaultsOptions, VoiceRealCallProfileDefaultsReport, VoiceRealCallProfileHistoryOptions, VoiceRealCallProfileHistoryReport, VoiceRealCallProfileHistoryRoutesOptions, VoiceRealCallProfileProviderRouteOptions, VoiceRealCallProfileReadinessCheckOptions, VoiceRealCallProfileRecoveryActionOptions, VoiceRealCallProfileRecoveryAction, VoiceRealCallProfileRecoveryActionHandler, VoiceRealCallProfileRecoveryActionHandlerInput, VoiceRealCallProfileRecoveryActionId, VoiceRealCallProfileRecoveryActionResult, VoiceRealCallProfileRecoveryActionRoutesOptions, VoiceRealCallProfileRecoveryJob, VoiceRealCallProfileRecoveryJobCreateInput, VoiceRealCallProfileRecoveryJobStatus, VoiceRealCallProfileRecoveryJobStore, VoiceRealCallProfileRecoveryJobUpdate, VoiceRealCallProfileTraceEvidenceOptions, VoiceRealCallProfileTraceStoreEvidenceOptions } from './proofTrends';
|
|
39
39
|
export { assertVoiceSloCalibration, buildVoiceSloCalibrationReport, buildVoiceSloReadinessThresholdReport, createVoiceSloReadinessThresholdOptions, createVoiceSloReadinessThresholdRoutes, createVoiceSloThresholdProfile, createVoiceSloCalibrationRoutes, renderVoiceSloCalibrationMarkdown, renderVoiceSloReadinessThresholdHTML, renderVoiceSloReadinessThresholdMarkdown } from './sloCalibration';
|
|
40
40
|
export type { VoiceSloCalibrationMetricKey, VoiceSloCalibrationOptions, VoiceSloCalibrationReport, VoiceSloCalibrationRoutesOptions, VoiceSloCalibrationSample, VoiceSloCalibrationStatus, VoiceSloCalibrationThreshold, VoiceSloCalibrationThresholds, VoiceSloReadinessThresholdReport, VoiceSloReadinessThresholdReportOptions, VoiceSloReadinessThresholdOptions, VoiceSloReadinessThresholdRoutesOptions, VoiceSloThresholdProfile } from './sloCalibration';
|
|
41
41
|
export { assertVoiceLiveOpsControlEvidence, assertVoiceLiveOpsEvidence, buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, evaluateVoiceLiveOpsControlEvidence, evaluateVoiceLiveOpsEvidence, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
|
package/dist/index.js
CHANGED
|
@@ -16040,11 +16040,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
16040
16040
|
{
|
|
16041
16041
|
description: "Open the current real-call profile history report and profile defaults.",
|
|
16042
16042
|
href: options.href ?? "/voice/real-call-profile-history",
|
|
16043
|
+
id: "refresh",
|
|
16043
16044
|
label: "Open real-call profile history"
|
|
16044
16045
|
},
|
|
16045
16046
|
{
|
|
16046
16047
|
description: "Refresh production readiness after collecting or replaying profile evidence.",
|
|
16047
16048
|
href: options.productionReadinessHref ?? "/production-readiness",
|
|
16049
|
+
id: "refresh",
|
|
16048
16050
|
label: "Refresh production readiness"
|
|
16049
16051
|
}
|
|
16050
16052
|
];
|
|
@@ -16058,11 +16060,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
16058
16060
|
actions.push({
|
|
16059
16061
|
description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
|
|
16060
16062
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
16063
|
+
id: "collect-browser-proof",
|
|
16061
16064
|
label: "Run browser profile proof"
|
|
16062
16065
|
});
|
|
16063
16066
|
actions.push({
|
|
16064
16067
|
description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
|
|
16065
16068
|
href: options.phoneProofHref ?? "/api/voice/phone/smoke",
|
|
16069
|
+
id: "collect-phone-proof",
|
|
16066
16070
|
label: "Run phone profile proof"
|
|
16067
16071
|
});
|
|
16068
16072
|
}
|
|
@@ -16070,6 +16074,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
16070
16074
|
actions.push({
|
|
16071
16075
|
description: "Collect fresh real-call profile traces because the current history artifact is stale.",
|
|
16072
16076
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
16077
|
+
id: "collect-browser-proof",
|
|
16073
16078
|
label: "Collect fresh profile evidence"
|
|
16074
16079
|
});
|
|
16075
16080
|
}
|
|
@@ -16077,6 +16082,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
16077
16082
|
actions.push({
|
|
16078
16083
|
description: "Collect missing LLM/STT/TTS provider-role evidence so profile defaults can become actionable.",
|
|
16079
16084
|
href: options.sourceHref ?? "/api/voice/real-call-profile-history",
|
|
16085
|
+
id: "collect-provider-role-evidence",
|
|
16080
16086
|
label: "Collect missing provider-role evidence"
|
|
16081
16087
|
});
|
|
16082
16088
|
}
|
|
@@ -16084,11 +16090,48 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
16084
16090
|
actions.push({
|
|
16085
16091
|
description: "Open operations records to inspect the sessions behind failing or warning profile evidence.",
|
|
16086
16092
|
href: options.operationsRecordsHref ?? "/voice-operations",
|
|
16093
|
+
id: "refresh",
|
|
16087
16094
|
label: "Open operations records"
|
|
16088
16095
|
});
|
|
16089
16096
|
}
|
|
16090
16097
|
return uniqueRealCallProfileActions(actions);
|
|
16091
16098
|
};
|
|
16099
|
+
var createVoiceInMemoryRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
16100
|
+
const jobs = new Map;
|
|
16101
|
+
const now = () => (options.now ?? (() => new Date))().toISOString();
|
|
16102
|
+
const createId3 = () => `${options.idPrefix ?? "voice-recovery-job"}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
16103
|
+
return {
|
|
16104
|
+
create(input) {
|
|
16105
|
+
const createdAt = input.createdAt ?? now();
|
|
16106
|
+
const job = {
|
|
16107
|
+
actionId: input.actionId,
|
|
16108
|
+
createdAt,
|
|
16109
|
+
id: input.id ?? createId3(),
|
|
16110
|
+
message: input.message,
|
|
16111
|
+
status: input.status ?? "queued",
|
|
16112
|
+
updatedAt: createdAt
|
|
16113
|
+
};
|
|
16114
|
+
jobs.set(job.id, job);
|
|
16115
|
+
return job;
|
|
16116
|
+
},
|
|
16117
|
+
get(id) {
|
|
16118
|
+
return jobs.get(id);
|
|
16119
|
+
},
|
|
16120
|
+
update(id, update) {
|
|
16121
|
+
const existing = jobs.get(id);
|
|
16122
|
+
if (!existing) {
|
|
16123
|
+
return;
|
|
16124
|
+
}
|
|
16125
|
+
const next = {
|
|
16126
|
+
...existing,
|
|
16127
|
+
...update,
|
|
16128
|
+
updatedAt: update.updatedAt ?? now()
|
|
16129
|
+
};
|
|
16130
|
+
jobs.set(id, next);
|
|
16131
|
+
return next;
|
|
16132
|
+
}
|
|
16133
|
+
};
|
|
16134
|
+
};
|
|
16092
16135
|
var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
16093
16136
|
const { issues, warnings } = buildRealCallProfileReadinessIssues(report, options);
|
|
16094
16137
|
const status = issues.length > 0 ? "fail" : warnings.length > 0 && options.failOnWarnings === true ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
@@ -16686,6 +16729,165 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
16686
16729
|
}
|
|
16687
16730
|
return routes;
|
|
16688
16731
|
};
|
|
16732
|
+
var realCallProfileActionPaths = {
|
|
16733
|
+
"collect-browser-proof": "/collect-browser-proof",
|
|
16734
|
+
"collect-phone-proof": "/collect-phone-proof",
|
|
16735
|
+
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
16736
|
+
refresh: "/refresh"
|
|
16737
|
+
};
|
|
16738
|
+
var loadVoiceRealCallProfileHistoryRouteReport = async (options) => {
|
|
16739
|
+
const { source, ...routeOptions } = options;
|
|
16740
|
+
const sourceOptions = source === undefined ? routeOptions : typeof source === "function" ? await source() : source;
|
|
16741
|
+
return buildVoiceRealCallProfileHistoryReport({
|
|
16742
|
+
...routeOptions,
|
|
16743
|
+
...sourceOptions
|
|
16744
|
+
});
|
|
16745
|
+
};
|
|
16746
|
+
var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
16747
|
+
const path = options.path ?? "/api/voice/real-call-profile-history";
|
|
16748
|
+
const routes = new Elysia22({
|
|
16749
|
+
name: options.name ?? "absolutejs-voice-real-call-profile-recovery-actions"
|
|
16750
|
+
});
|
|
16751
|
+
const actionPath = (actionId) => `${path}${realCallProfileActionPaths[actionId]}`;
|
|
16752
|
+
const loadReport = () => loadVoiceRealCallProfileHistoryRouteReport(options);
|
|
16753
|
+
const asyncActionIds = new Set(options.asyncActionIds ?? []);
|
|
16754
|
+
const listActions = async () => {
|
|
16755
|
+
const report = await loadReport();
|
|
16756
|
+
const actions = buildVoiceRealCallProfileRecoveryActions(report, {
|
|
16757
|
+
...options,
|
|
16758
|
+
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
16759
|
+
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
16760
|
+
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
16761
|
+
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
16762
|
+
}).map((action) => ({
|
|
16763
|
+
...action,
|
|
16764
|
+
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,
|
|
16765
|
+
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
16766
|
+
}));
|
|
16767
|
+
return { actions, generatedAt: new Date().toISOString(), report };
|
|
16768
|
+
};
|
|
16769
|
+
const runActionHandler = async (actionId, report) => {
|
|
16770
|
+
const handler = options.handlers?.[actionId];
|
|
16771
|
+
if (!handler) {
|
|
16772
|
+
return;
|
|
16773
|
+
}
|
|
16774
|
+
return await handler({ actionId, report });
|
|
16775
|
+
};
|
|
16776
|
+
const runActionAsJob = async (actionId, report) => {
|
|
16777
|
+
const job = await options.jobStore?.create({
|
|
16778
|
+
actionId,
|
|
16779
|
+
message: `Queued real-call profile recovery action: ${actionId}.`,
|
|
16780
|
+
status: "queued"
|
|
16781
|
+
});
|
|
16782
|
+
if (!job) {
|
|
16783
|
+
return;
|
|
16784
|
+
}
|
|
16785
|
+
queueMicrotask(() => {
|
|
16786
|
+
(async () => {
|
|
16787
|
+
const startedAt = new Date().toISOString();
|
|
16788
|
+
await options.jobStore?.update(job.id, {
|
|
16789
|
+
message: `Running real-call profile recovery action: ${actionId}.`,
|
|
16790
|
+
startedAt,
|
|
16791
|
+
status: "running",
|
|
16792
|
+
updatedAt: startedAt
|
|
16793
|
+
});
|
|
16794
|
+
try {
|
|
16795
|
+
const result = await runActionHandler(actionId, report);
|
|
16796
|
+
const completedAt = new Date().toISOString();
|
|
16797
|
+
const ok = result?.ok ?? true;
|
|
16798
|
+
const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
|
|
16799
|
+
await options.jobStore?.update(job.id, {
|
|
16800
|
+
completedAt,
|
|
16801
|
+
message: result?.message ?? `Completed real-call profile recovery action: ${actionId}.`,
|
|
16802
|
+
ok,
|
|
16803
|
+
report: result?.report,
|
|
16804
|
+
status,
|
|
16805
|
+
updatedAt: completedAt
|
|
16806
|
+
});
|
|
16807
|
+
} catch (error) {
|
|
16808
|
+
const completedAt = new Date().toISOString();
|
|
16809
|
+
await options.jobStore?.update(job.id, {
|
|
16810
|
+
completedAt,
|
|
16811
|
+
message: error instanceof Error ? error.message : `Failed real-call profile recovery action: ${actionId}.`,
|
|
16812
|
+
ok: false,
|
|
16813
|
+
status: "fail",
|
|
16814
|
+
updatedAt: completedAt
|
|
16815
|
+
});
|
|
16816
|
+
}
|
|
16817
|
+
})();
|
|
16818
|
+
});
|
|
16819
|
+
return {
|
|
16820
|
+
actionId,
|
|
16821
|
+
generatedAt: new Date().toISOString(),
|
|
16822
|
+
job,
|
|
16823
|
+
jobId: job.id,
|
|
16824
|
+
jobStatus: job.status,
|
|
16825
|
+
message: job.message,
|
|
16826
|
+
ok: true,
|
|
16827
|
+
status: "pass"
|
|
16828
|
+
};
|
|
16829
|
+
};
|
|
16830
|
+
const runAction = async (actionId) => {
|
|
16831
|
+
const report = await loadReport();
|
|
16832
|
+
const handler = options.handlers?.[actionId];
|
|
16833
|
+
if (!handler) {
|
|
16834
|
+
return {
|
|
16835
|
+
actionId,
|
|
16836
|
+
generatedAt: new Date().toISOString(),
|
|
16837
|
+
message: `No handler configured for real-call profile recovery action: ${actionId}.`,
|
|
16838
|
+
ok: false,
|
|
16839
|
+
status: "fail"
|
|
16840
|
+
};
|
|
16841
|
+
}
|
|
16842
|
+
if (options.jobStore && asyncActionIds.has(actionId)) {
|
|
16843
|
+
const queued = await runActionAsJob(actionId, report);
|
|
16844
|
+
if (queued) {
|
|
16845
|
+
return queued;
|
|
16846
|
+
}
|
|
16847
|
+
}
|
|
16848
|
+
const result = await runActionHandler(actionId, report);
|
|
16849
|
+
return {
|
|
16850
|
+
actionId,
|
|
16851
|
+
generatedAt: new Date().toISOString(),
|
|
16852
|
+
job: result?.job,
|
|
16853
|
+
jobId: result?.jobId,
|
|
16854
|
+
jobStatus: result?.jobStatus,
|
|
16855
|
+
message: result?.message,
|
|
16856
|
+
ok: result?.ok ?? true,
|
|
16857
|
+
report: result?.report,
|
|
16858
|
+
status: result?.status ?? "pass"
|
|
16859
|
+
};
|
|
16860
|
+
};
|
|
16861
|
+
routes.get(`${path}/actions`, async () => Response.json(await listActions(), { headers: options.headers }));
|
|
16862
|
+
routes.get(`${path}/actions/:jobId`, async ({
|
|
16863
|
+
params,
|
|
16864
|
+
set
|
|
16865
|
+
}) => {
|
|
16866
|
+
const jobId = params.jobId ?? "";
|
|
16867
|
+
const job = await options.jobStore?.get(jobId);
|
|
16868
|
+
if (!job) {
|
|
16869
|
+
set.status = 404;
|
|
16870
|
+
return Response.json({
|
|
16871
|
+
jobId,
|
|
16872
|
+
message: `No real-call profile recovery job found for id: ${jobId}.`,
|
|
16873
|
+
ok: false
|
|
16874
|
+
}, { headers: options.headers });
|
|
16875
|
+
}
|
|
16876
|
+
return Response.json({ job, ok: job.ok ?? job.status !== "fail" }, {
|
|
16877
|
+
headers: options.headers
|
|
16878
|
+
});
|
|
16879
|
+
});
|
|
16880
|
+
for (const actionId of Object.keys(realCallProfileActionPaths)) {
|
|
16881
|
+
routes.post(actionPath(actionId), async ({ set }) => {
|
|
16882
|
+
const result = await runAction(actionId);
|
|
16883
|
+
if (!result.ok) {
|
|
16884
|
+
set.status = 501;
|
|
16885
|
+
}
|
|
16886
|
+
return Response.json(result, { headers: options.headers });
|
|
16887
|
+
});
|
|
16888
|
+
}
|
|
16889
|
+
return routes;
|
|
16890
|
+
};
|
|
16689
16891
|
var createVoiceProofTrendRoutes = (options) => {
|
|
16690
16892
|
const path = options.path ?? "/api/voice/proof-trends";
|
|
16691
16893
|
const routes = new Elysia22({
|
|
@@ -38757,6 +38959,7 @@ export {
|
|
|
38757
38959
|
createVoiceRealtimeProviderContractRoutes,
|
|
38758
38960
|
createVoiceRealtimeProviderContractMatrixPreset,
|
|
38759
38961
|
createVoiceRealtimeChannelRoutes,
|
|
38962
|
+
createVoiceRealCallProfileRecoveryActionRoutes,
|
|
38760
38963
|
createVoiceRealCallProfileHistoryRoutes,
|
|
38761
38964
|
createVoiceReadinessProfile,
|
|
38762
38965
|
createVoiceQualityRoutes,
|
|
@@ -38854,6 +39057,7 @@ export {
|
|
|
38854
39057
|
createVoiceIntegrationHTTPSink,
|
|
38855
39058
|
createVoiceIntegrationEvent,
|
|
38856
39059
|
createVoiceIncidentBundleRoutes,
|
|
39060
|
+
createVoiceInMemoryRealCallProfileRecoveryJobStore,
|
|
38857
39061
|
createVoiceHubSpotTaskUpdateSink,
|
|
38858
39062
|
createVoiceHubSpotTaskSyncSinks,
|
|
38859
39063
|
createVoiceHubSpotTaskSink,
|
package/dist/proofTrends.d.ts
CHANGED
|
@@ -356,6 +356,10 @@ export type VoiceRealCallProfileHistoryRoutesOptions = Omit<VoiceRealCallProfile
|
|
|
356
356
|
source?: (() => Promise<VoiceRealCallProfileHistoryOptions> | VoiceRealCallProfileHistoryOptions) | VoiceRealCallProfileHistoryOptions;
|
|
357
357
|
title?: string;
|
|
358
358
|
};
|
|
359
|
+
export type VoiceRealCallProfileRecoveryActionId = 'collect-browser-proof' | 'collect-phone-proof' | 'collect-provider-role-evidence' | 'refresh';
|
|
360
|
+
export type VoiceRealCallProfileRecoveryAction = VoiceProductionReadinessAction & {
|
|
361
|
+
id: VoiceRealCallProfileRecoveryActionId;
|
|
362
|
+
};
|
|
359
363
|
export type VoiceRealCallProfileReadinessCheckOptions = {
|
|
360
364
|
browserProofHref?: string;
|
|
361
365
|
failOnWarnings?: boolean;
|
|
@@ -373,6 +377,53 @@ export type VoiceRealCallProfileReadinessCheckOptions = {
|
|
|
373
377
|
sourceHref?: string;
|
|
374
378
|
};
|
|
375
379
|
export type VoiceRealCallProfileRecoveryActionOptions = VoiceRealCallProfileReadinessCheckOptions;
|
|
380
|
+
export type VoiceRealCallProfileRecoveryActionHandlerInput = {
|
|
381
|
+
actionId: VoiceRealCallProfileRecoveryActionId;
|
|
382
|
+
report: VoiceRealCallProfileHistoryReport;
|
|
383
|
+
};
|
|
384
|
+
export type VoiceRealCallProfileRecoveryActionResult = {
|
|
385
|
+
actionId: VoiceRealCallProfileRecoveryActionId;
|
|
386
|
+
generatedAt: string;
|
|
387
|
+
job?: VoiceRealCallProfileRecoveryJob;
|
|
388
|
+
jobId?: string;
|
|
389
|
+
jobStatus?: VoiceRealCallProfileRecoveryJobStatus;
|
|
390
|
+
message?: string;
|
|
391
|
+
ok: boolean;
|
|
392
|
+
report?: VoiceRealCallProfileHistoryReport;
|
|
393
|
+
status: VoiceProofTrendStatus;
|
|
394
|
+
};
|
|
395
|
+
export type VoiceRealCallProfileRecoveryJobStatus = 'fail' | 'pass' | 'queued' | 'running';
|
|
396
|
+
export type VoiceRealCallProfileRecoveryJob = {
|
|
397
|
+
actionId: VoiceRealCallProfileRecoveryActionId;
|
|
398
|
+
completedAt?: string;
|
|
399
|
+
createdAt: string;
|
|
400
|
+
id: string;
|
|
401
|
+
message?: string;
|
|
402
|
+
ok?: boolean;
|
|
403
|
+
report?: VoiceRealCallProfileHistoryReport;
|
|
404
|
+
startedAt?: string;
|
|
405
|
+
status: VoiceRealCallProfileRecoveryJobStatus;
|
|
406
|
+
updatedAt: string;
|
|
407
|
+
};
|
|
408
|
+
export type VoiceRealCallProfileRecoveryJobCreateInput = {
|
|
409
|
+
actionId: VoiceRealCallProfileRecoveryActionId;
|
|
410
|
+
createdAt?: string;
|
|
411
|
+
id?: string;
|
|
412
|
+
message?: string;
|
|
413
|
+
status?: VoiceRealCallProfileRecoveryJobStatus;
|
|
414
|
+
};
|
|
415
|
+
export type VoiceRealCallProfileRecoveryJobUpdate = Partial<Pick<VoiceRealCallProfileRecoveryJob, 'completedAt' | 'message' | 'ok' | 'report' | 'startedAt' | 'status' | 'updatedAt'>>;
|
|
416
|
+
export type VoiceRealCallProfileRecoveryJobStore = {
|
|
417
|
+
create(input: VoiceRealCallProfileRecoveryJobCreateInput): Promise<VoiceRealCallProfileRecoveryJob> | VoiceRealCallProfileRecoveryJob;
|
|
418
|
+
get(id: string): Promise<VoiceRealCallProfileRecoveryJob | undefined> | VoiceRealCallProfileRecoveryJob | undefined;
|
|
419
|
+
update(id: string, update: VoiceRealCallProfileRecoveryJobUpdate): Promise<VoiceRealCallProfileRecoveryJob | undefined> | VoiceRealCallProfileRecoveryJob | undefined;
|
|
420
|
+
};
|
|
421
|
+
export type VoiceRealCallProfileRecoveryActionHandler = (input: VoiceRealCallProfileRecoveryActionHandlerInput) => Promise<Partial<VoiceRealCallProfileRecoveryActionResult> | void> | Partial<VoiceRealCallProfileRecoveryActionResult> | void;
|
|
422
|
+
export type VoiceRealCallProfileRecoveryActionRoutesOptions = VoiceRealCallProfileRecoveryActionOptions & Omit<VoiceRealCallProfileHistoryRoutesOptions, 'htmlPath' | 'markdownPath'> & {
|
|
423
|
+
asyncActionIds?: readonly VoiceRealCallProfileRecoveryActionId[];
|
|
424
|
+
handlers?: Partial<Record<VoiceRealCallProfileRecoveryActionId, VoiceRealCallProfileRecoveryActionHandler>>;
|
|
425
|
+
jobStore?: VoiceRealCallProfileRecoveryJobStore;
|
|
426
|
+
};
|
|
376
427
|
export declare const DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS: number;
|
|
377
428
|
export declare const DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS: ({
|
|
378
429
|
description: string;
|
|
@@ -406,7 +457,11 @@ export declare const loadVoiceRealCallProfileEvidenceFromTraceStore: (options: V
|
|
|
406
457
|
export declare const buildVoiceProofTrendProfileSummaries: (input: VoiceProofTrendReport | readonly VoiceProofTrendReport[], options?: VoiceProofTrendProfileSummaryOptions) => VoiceProofTrendProfileSummary[];
|
|
407
458
|
export declare const buildVoiceProofTrendReportFromRealCallProfiles: (options: VoiceProofTrendRealCallProfileReportOptions) => VoiceProofTrendReport;
|
|
408
459
|
export declare const buildVoiceRealCallProfileDefaults: (input: VoiceRealCallProfileHistoryReport | VoiceProofTrendReport, options?: VoiceRealCallProfileDefaultsOptions) => VoiceRealCallProfileDefaultsReport;
|
|
409
|
-
export declare const buildVoiceRealCallProfileRecoveryActions: (report: VoiceRealCallProfileHistoryReport, options?: VoiceRealCallProfileRecoveryActionOptions) =>
|
|
460
|
+
export declare const buildVoiceRealCallProfileRecoveryActions: (report: VoiceRealCallProfileHistoryReport, options?: VoiceRealCallProfileRecoveryActionOptions) => VoiceRealCallProfileRecoveryAction[];
|
|
461
|
+
export declare const createVoiceInMemoryRealCallProfileRecoveryJobStore: (options?: {
|
|
462
|
+
idPrefix?: string;
|
|
463
|
+
now?: () => Date;
|
|
464
|
+
}) => VoiceRealCallProfileRecoveryJobStore;
|
|
410
465
|
export declare const buildVoiceRealCallProfileReadinessCheck: (report: VoiceRealCallProfileHistoryReport, options?: VoiceRealCallProfileReadinessCheckOptions) => VoiceProductionReadinessCheck;
|
|
411
466
|
export declare const resolveVoiceRealCallProfileProviderRoute: <TProvider extends string = string>(options: VoiceRealCallProfileProviderRouteOptions<TProvider>) => TProvider | undefined;
|
|
412
467
|
export declare const buildVoiceRealCallProfileHistoryReport: (options?: VoiceRealCallProfileHistoryOptions) => VoiceRealCallProfileHistoryReport;
|
|
@@ -473,6 +528,34 @@ export declare const createVoiceRealCallProfileHistoryRoutes: (options?: VoiceRe
|
|
|
473
528
|
standaloneSchema: {};
|
|
474
529
|
response: {};
|
|
475
530
|
}>;
|
|
531
|
+
export declare const createVoiceRealCallProfileRecoveryActionRoutes: (options?: VoiceRealCallProfileRecoveryActionRoutesOptions) => Elysia<"", {
|
|
532
|
+
decorator: {};
|
|
533
|
+
store: {};
|
|
534
|
+
derive: {};
|
|
535
|
+
resolve: {};
|
|
536
|
+
}, {
|
|
537
|
+
typebox: {};
|
|
538
|
+
error: {};
|
|
539
|
+
}, {
|
|
540
|
+
schema: {};
|
|
541
|
+
standaloneSchema: {};
|
|
542
|
+
macro: {};
|
|
543
|
+
macroFn: {};
|
|
544
|
+
parser: {};
|
|
545
|
+
response: {};
|
|
546
|
+
}, {}, {
|
|
547
|
+
derive: {};
|
|
548
|
+
resolve: {};
|
|
549
|
+
schema: {};
|
|
550
|
+
standaloneSchema: {};
|
|
551
|
+
response: {};
|
|
552
|
+
}, {
|
|
553
|
+
derive: {};
|
|
554
|
+
resolve: {};
|
|
555
|
+
schema: {};
|
|
556
|
+
standaloneSchema: {};
|
|
557
|
+
response: {};
|
|
558
|
+
}>;
|
|
476
559
|
export declare const createVoiceProofTrendRoutes: (options: VoiceProofTrendRoutesOptions) => Elysia<"", {
|
|
477
560
|
decorator: {};
|
|
478
561
|
store: {};
|
package/dist/react/index.js
CHANGED
|
@@ -2158,11 +2158,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2158
2158
|
{
|
|
2159
2159
|
description: "Open the current real-call profile history report and profile defaults.",
|
|
2160
2160
|
href: options.href ?? "/voice/real-call-profile-history",
|
|
2161
|
+
id: "refresh",
|
|
2161
2162
|
label: "Open real-call profile history"
|
|
2162
2163
|
},
|
|
2163
2164
|
{
|
|
2164
2165
|
description: "Refresh production readiness after collecting or replaying profile evidence.",
|
|
2165
2166
|
href: options.productionReadinessHref ?? "/production-readiness",
|
|
2167
|
+
id: "refresh",
|
|
2166
2168
|
label: "Refresh production readiness"
|
|
2167
2169
|
}
|
|
2168
2170
|
];
|
|
@@ -2176,11 +2178,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2176
2178
|
actions.push({
|
|
2177
2179
|
description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
|
|
2178
2180
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
2181
|
+
id: "collect-browser-proof",
|
|
2179
2182
|
label: "Run browser profile proof"
|
|
2180
2183
|
});
|
|
2181
2184
|
actions.push({
|
|
2182
2185
|
description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
|
|
2183
2186
|
href: options.phoneProofHref ?? "/api/voice/phone/smoke",
|
|
2187
|
+
id: "collect-phone-proof",
|
|
2184
2188
|
label: "Run phone profile proof"
|
|
2185
2189
|
});
|
|
2186
2190
|
}
|
|
@@ -2188,6 +2192,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2188
2192
|
actions.push({
|
|
2189
2193
|
description: "Collect fresh real-call profile traces because the current history artifact is stale.",
|
|
2190
2194
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
2195
|
+
id: "collect-browser-proof",
|
|
2191
2196
|
label: "Collect fresh profile evidence"
|
|
2192
2197
|
});
|
|
2193
2198
|
}
|
|
@@ -2195,6 +2200,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2195
2200
|
actions.push({
|
|
2196
2201
|
description: "Collect missing LLM/STT/TTS provider-role evidence so profile defaults can become actionable.",
|
|
2197
2202
|
href: options.sourceHref ?? "/api/voice/real-call-profile-history",
|
|
2203
|
+
id: "collect-provider-role-evidence",
|
|
2198
2204
|
label: "Collect missing provider-role evidence"
|
|
2199
2205
|
});
|
|
2200
2206
|
}
|
|
@@ -2202,11 +2208,48 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2202
2208
|
actions.push({
|
|
2203
2209
|
description: "Open operations records to inspect the sessions behind failing or warning profile evidence.",
|
|
2204
2210
|
href: options.operationsRecordsHref ?? "/voice-operations",
|
|
2211
|
+
id: "refresh",
|
|
2205
2212
|
label: "Open operations records"
|
|
2206
2213
|
});
|
|
2207
2214
|
}
|
|
2208
2215
|
return uniqueRealCallProfileActions(actions);
|
|
2209
2216
|
};
|
|
2217
|
+
var createVoiceInMemoryRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
2218
|
+
const jobs = new Map;
|
|
2219
|
+
const now = () => (options.now ?? (() => new Date))().toISOString();
|
|
2220
|
+
const createId = () => `${options.idPrefix ?? "voice-recovery-job"}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
2221
|
+
return {
|
|
2222
|
+
create(input) {
|
|
2223
|
+
const createdAt = input.createdAt ?? now();
|
|
2224
|
+
const job = {
|
|
2225
|
+
actionId: input.actionId,
|
|
2226
|
+
createdAt,
|
|
2227
|
+
id: input.id ?? createId(),
|
|
2228
|
+
message: input.message,
|
|
2229
|
+
status: input.status ?? "queued",
|
|
2230
|
+
updatedAt: createdAt
|
|
2231
|
+
};
|
|
2232
|
+
jobs.set(job.id, job);
|
|
2233
|
+
return job;
|
|
2234
|
+
},
|
|
2235
|
+
get(id) {
|
|
2236
|
+
return jobs.get(id);
|
|
2237
|
+
},
|
|
2238
|
+
update(id, update) {
|
|
2239
|
+
const existing = jobs.get(id);
|
|
2240
|
+
if (!existing) {
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
const next = {
|
|
2244
|
+
...existing,
|
|
2245
|
+
...update,
|
|
2246
|
+
updatedAt: update.updatedAt ?? now()
|
|
2247
|
+
};
|
|
2248
|
+
jobs.set(id, next);
|
|
2249
|
+
return next;
|
|
2250
|
+
}
|
|
2251
|
+
};
|
|
2252
|
+
};
|
|
2210
2253
|
var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
2211
2254
|
const { issues, warnings } = buildRealCallProfileReadinessIssues(report, options);
|
|
2212
2255
|
const status = issues.length > 0 ? "fail" : warnings.length > 0 && options.failOnWarnings === true ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
@@ -2804,6 +2847,165 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
2804
2847
|
}
|
|
2805
2848
|
return routes;
|
|
2806
2849
|
};
|
|
2850
|
+
var realCallProfileActionPaths = {
|
|
2851
|
+
"collect-browser-proof": "/collect-browser-proof",
|
|
2852
|
+
"collect-phone-proof": "/collect-phone-proof",
|
|
2853
|
+
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
2854
|
+
refresh: "/refresh"
|
|
2855
|
+
};
|
|
2856
|
+
var loadVoiceRealCallProfileHistoryRouteReport = async (options) => {
|
|
2857
|
+
const { source, ...routeOptions } = options;
|
|
2858
|
+
const sourceOptions = source === undefined ? routeOptions : typeof source === "function" ? await source() : source;
|
|
2859
|
+
return buildVoiceRealCallProfileHistoryReport({
|
|
2860
|
+
...routeOptions,
|
|
2861
|
+
...sourceOptions
|
|
2862
|
+
});
|
|
2863
|
+
};
|
|
2864
|
+
var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
2865
|
+
const path = options.path ?? "/api/voice/real-call-profile-history";
|
|
2866
|
+
const routes = new Elysia({
|
|
2867
|
+
name: options.name ?? "absolutejs-voice-real-call-profile-recovery-actions"
|
|
2868
|
+
});
|
|
2869
|
+
const actionPath = (actionId) => `${path}${realCallProfileActionPaths[actionId]}`;
|
|
2870
|
+
const loadReport = () => loadVoiceRealCallProfileHistoryRouteReport(options);
|
|
2871
|
+
const asyncActionIds = new Set(options.asyncActionIds ?? []);
|
|
2872
|
+
const listActions = async () => {
|
|
2873
|
+
const report = await loadReport();
|
|
2874
|
+
const actions = buildVoiceRealCallProfileRecoveryActions(report, {
|
|
2875
|
+
...options,
|
|
2876
|
+
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
2877
|
+
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
2878
|
+
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
2879
|
+
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
2880
|
+
}).map((action) => ({
|
|
2881
|
+
...action,
|
|
2882
|
+
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,
|
|
2883
|
+
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
2884
|
+
}));
|
|
2885
|
+
return { actions, generatedAt: new Date().toISOString(), report };
|
|
2886
|
+
};
|
|
2887
|
+
const runActionHandler = async (actionId, report) => {
|
|
2888
|
+
const handler = options.handlers?.[actionId];
|
|
2889
|
+
if (!handler) {
|
|
2890
|
+
return;
|
|
2891
|
+
}
|
|
2892
|
+
return await handler({ actionId, report });
|
|
2893
|
+
};
|
|
2894
|
+
const runActionAsJob = async (actionId, report) => {
|
|
2895
|
+
const job = await options.jobStore?.create({
|
|
2896
|
+
actionId,
|
|
2897
|
+
message: `Queued real-call profile recovery action: ${actionId}.`,
|
|
2898
|
+
status: "queued"
|
|
2899
|
+
});
|
|
2900
|
+
if (!job) {
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2903
|
+
queueMicrotask(() => {
|
|
2904
|
+
(async () => {
|
|
2905
|
+
const startedAt = new Date().toISOString();
|
|
2906
|
+
await options.jobStore?.update(job.id, {
|
|
2907
|
+
message: `Running real-call profile recovery action: ${actionId}.`,
|
|
2908
|
+
startedAt,
|
|
2909
|
+
status: "running",
|
|
2910
|
+
updatedAt: startedAt
|
|
2911
|
+
});
|
|
2912
|
+
try {
|
|
2913
|
+
const result = await runActionHandler(actionId, report);
|
|
2914
|
+
const completedAt = new Date().toISOString();
|
|
2915
|
+
const ok = result?.ok ?? true;
|
|
2916
|
+
const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
|
|
2917
|
+
await options.jobStore?.update(job.id, {
|
|
2918
|
+
completedAt,
|
|
2919
|
+
message: result?.message ?? `Completed real-call profile recovery action: ${actionId}.`,
|
|
2920
|
+
ok,
|
|
2921
|
+
report: result?.report,
|
|
2922
|
+
status,
|
|
2923
|
+
updatedAt: completedAt
|
|
2924
|
+
});
|
|
2925
|
+
} catch (error) {
|
|
2926
|
+
const completedAt = new Date().toISOString();
|
|
2927
|
+
await options.jobStore?.update(job.id, {
|
|
2928
|
+
completedAt,
|
|
2929
|
+
message: error instanceof Error ? error.message : `Failed real-call profile recovery action: ${actionId}.`,
|
|
2930
|
+
ok: false,
|
|
2931
|
+
status: "fail",
|
|
2932
|
+
updatedAt: completedAt
|
|
2933
|
+
});
|
|
2934
|
+
}
|
|
2935
|
+
})();
|
|
2936
|
+
});
|
|
2937
|
+
return {
|
|
2938
|
+
actionId,
|
|
2939
|
+
generatedAt: new Date().toISOString(),
|
|
2940
|
+
job,
|
|
2941
|
+
jobId: job.id,
|
|
2942
|
+
jobStatus: job.status,
|
|
2943
|
+
message: job.message,
|
|
2944
|
+
ok: true,
|
|
2945
|
+
status: "pass"
|
|
2946
|
+
};
|
|
2947
|
+
};
|
|
2948
|
+
const runAction = async (actionId) => {
|
|
2949
|
+
const report = await loadReport();
|
|
2950
|
+
const handler = options.handlers?.[actionId];
|
|
2951
|
+
if (!handler) {
|
|
2952
|
+
return {
|
|
2953
|
+
actionId,
|
|
2954
|
+
generatedAt: new Date().toISOString(),
|
|
2955
|
+
message: `No handler configured for real-call profile recovery action: ${actionId}.`,
|
|
2956
|
+
ok: false,
|
|
2957
|
+
status: "fail"
|
|
2958
|
+
};
|
|
2959
|
+
}
|
|
2960
|
+
if (options.jobStore && asyncActionIds.has(actionId)) {
|
|
2961
|
+
const queued = await runActionAsJob(actionId, report);
|
|
2962
|
+
if (queued) {
|
|
2963
|
+
return queued;
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
const result = await runActionHandler(actionId, report);
|
|
2967
|
+
return {
|
|
2968
|
+
actionId,
|
|
2969
|
+
generatedAt: new Date().toISOString(),
|
|
2970
|
+
job: result?.job,
|
|
2971
|
+
jobId: result?.jobId,
|
|
2972
|
+
jobStatus: result?.jobStatus,
|
|
2973
|
+
message: result?.message,
|
|
2974
|
+
ok: result?.ok ?? true,
|
|
2975
|
+
report: result?.report,
|
|
2976
|
+
status: result?.status ?? "pass"
|
|
2977
|
+
};
|
|
2978
|
+
};
|
|
2979
|
+
routes.get(`${path}/actions`, async () => Response.json(await listActions(), { headers: options.headers }));
|
|
2980
|
+
routes.get(`${path}/actions/:jobId`, async ({
|
|
2981
|
+
params,
|
|
2982
|
+
set
|
|
2983
|
+
}) => {
|
|
2984
|
+
const jobId = params.jobId ?? "";
|
|
2985
|
+
const job = await options.jobStore?.get(jobId);
|
|
2986
|
+
if (!job) {
|
|
2987
|
+
set.status = 404;
|
|
2988
|
+
return Response.json({
|
|
2989
|
+
jobId,
|
|
2990
|
+
message: `No real-call profile recovery job found for id: ${jobId}.`,
|
|
2991
|
+
ok: false
|
|
2992
|
+
}, { headers: options.headers });
|
|
2993
|
+
}
|
|
2994
|
+
return Response.json({ job, ok: job.ok ?? job.status !== "fail" }, {
|
|
2995
|
+
headers: options.headers
|
|
2996
|
+
});
|
|
2997
|
+
});
|
|
2998
|
+
for (const actionId of Object.keys(realCallProfileActionPaths)) {
|
|
2999
|
+
routes.post(actionPath(actionId), async ({ set }) => {
|
|
3000
|
+
const result = await runAction(actionId);
|
|
3001
|
+
if (!result.ok) {
|
|
3002
|
+
set.status = 501;
|
|
3003
|
+
}
|
|
3004
|
+
return Response.json(result, { headers: options.headers });
|
|
3005
|
+
});
|
|
3006
|
+
}
|
|
3007
|
+
return routes;
|
|
3008
|
+
};
|
|
2807
3009
|
var createVoiceProofTrendRoutes = (options) => {
|
|
2808
3010
|
const path = options.path ?? "/api/voice/proof-trends";
|
|
2809
3011
|
const routes = new Elysia({
|
package/dist/vue/index.js
CHANGED
|
@@ -2079,11 +2079,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2079
2079
|
{
|
|
2080
2080
|
description: "Open the current real-call profile history report and profile defaults.",
|
|
2081
2081
|
href: options.href ?? "/voice/real-call-profile-history",
|
|
2082
|
+
id: "refresh",
|
|
2082
2083
|
label: "Open real-call profile history"
|
|
2083
2084
|
},
|
|
2084
2085
|
{
|
|
2085
2086
|
description: "Refresh production readiness after collecting or replaying profile evidence.",
|
|
2086
2087
|
href: options.productionReadinessHref ?? "/production-readiness",
|
|
2088
|
+
id: "refresh",
|
|
2087
2089
|
label: "Refresh production readiness"
|
|
2088
2090
|
}
|
|
2089
2091
|
];
|
|
@@ -2097,11 +2099,13 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2097
2099
|
actions.push({
|
|
2098
2100
|
description: "Run browser profile proof to collect microphone, WebSocket, live-latency, and provider traces for missing profiles.",
|
|
2099
2101
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
2102
|
+
id: "collect-browser-proof",
|
|
2100
2103
|
label: "Run browser profile proof"
|
|
2101
2104
|
});
|
|
2102
2105
|
actions.push({
|
|
2103
2106
|
description: "Run phone profile proof when required profiles depend on carrier, telephony media, or noisy-call evidence.",
|
|
2104
2107
|
href: options.phoneProofHref ?? "/api/voice/phone/smoke",
|
|
2108
|
+
id: "collect-phone-proof",
|
|
2105
2109
|
label: "Run phone profile proof"
|
|
2106
2110
|
});
|
|
2107
2111
|
}
|
|
@@ -2109,6 +2113,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2109
2113
|
actions.push({
|
|
2110
2114
|
description: "Collect fresh real-call profile traces because the current history artifact is stale.",
|
|
2111
2115
|
href: options.browserProofHref ?? "/voice/browser-call-profiles",
|
|
2116
|
+
id: "collect-browser-proof",
|
|
2112
2117
|
label: "Collect fresh profile evidence"
|
|
2113
2118
|
});
|
|
2114
2119
|
}
|
|
@@ -2116,6 +2121,7 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2116
2121
|
actions.push({
|
|
2117
2122
|
description: "Collect missing LLM/STT/TTS provider-role evidence so profile defaults can become actionable.",
|
|
2118
2123
|
href: options.sourceHref ?? "/api/voice/real-call-profile-history",
|
|
2124
|
+
id: "collect-provider-role-evidence",
|
|
2119
2125
|
label: "Collect missing provider-role evidence"
|
|
2120
2126
|
});
|
|
2121
2127
|
}
|
|
@@ -2123,11 +2129,48 @@ var buildVoiceRealCallProfileRecoveryActions = (report, options = {}) => {
|
|
|
2123
2129
|
actions.push({
|
|
2124
2130
|
description: "Open operations records to inspect the sessions behind failing or warning profile evidence.",
|
|
2125
2131
|
href: options.operationsRecordsHref ?? "/voice-operations",
|
|
2132
|
+
id: "refresh",
|
|
2126
2133
|
label: "Open operations records"
|
|
2127
2134
|
});
|
|
2128
2135
|
}
|
|
2129
2136
|
return uniqueRealCallProfileActions(actions);
|
|
2130
2137
|
};
|
|
2138
|
+
var createVoiceInMemoryRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
2139
|
+
const jobs = new Map;
|
|
2140
|
+
const now = () => (options.now ?? (() => new Date))().toISOString();
|
|
2141
|
+
const createId = () => `${options.idPrefix ?? "voice-recovery-job"}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
2142
|
+
return {
|
|
2143
|
+
create(input) {
|
|
2144
|
+
const createdAt = input.createdAt ?? now();
|
|
2145
|
+
const job = {
|
|
2146
|
+
actionId: input.actionId,
|
|
2147
|
+
createdAt,
|
|
2148
|
+
id: input.id ?? createId(),
|
|
2149
|
+
message: input.message,
|
|
2150
|
+
status: input.status ?? "queued",
|
|
2151
|
+
updatedAt: createdAt
|
|
2152
|
+
};
|
|
2153
|
+
jobs.set(job.id, job);
|
|
2154
|
+
return job;
|
|
2155
|
+
},
|
|
2156
|
+
get(id) {
|
|
2157
|
+
return jobs.get(id);
|
|
2158
|
+
},
|
|
2159
|
+
update(id, update) {
|
|
2160
|
+
const existing = jobs.get(id);
|
|
2161
|
+
if (!existing) {
|
|
2162
|
+
return;
|
|
2163
|
+
}
|
|
2164
|
+
const next = {
|
|
2165
|
+
...existing,
|
|
2166
|
+
...update,
|
|
2167
|
+
updatedAt: update.updatedAt ?? now()
|
|
2168
|
+
};
|
|
2169
|
+
jobs.set(id, next);
|
|
2170
|
+
return next;
|
|
2171
|
+
}
|
|
2172
|
+
};
|
|
2173
|
+
};
|
|
2131
2174
|
var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
2132
2175
|
const { issues, warnings } = buildRealCallProfileReadinessIssues(report, options);
|
|
2133
2176
|
const status = issues.length > 0 ? "fail" : warnings.length > 0 && options.failOnWarnings === true ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
@@ -2725,6 +2768,165 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
2725
2768
|
}
|
|
2726
2769
|
return routes;
|
|
2727
2770
|
};
|
|
2771
|
+
var realCallProfileActionPaths = {
|
|
2772
|
+
"collect-browser-proof": "/collect-browser-proof",
|
|
2773
|
+
"collect-phone-proof": "/collect-phone-proof",
|
|
2774
|
+
"collect-provider-role-evidence": "/collect-provider-role-evidence",
|
|
2775
|
+
refresh: "/refresh"
|
|
2776
|
+
};
|
|
2777
|
+
var loadVoiceRealCallProfileHistoryRouteReport = async (options) => {
|
|
2778
|
+
const { source, ...routeOptions } = options;
|
|
2779
|
+
const sourceOptions = source === undefined ? routeOptions : typeof source === "function" ? await source() : source;
|
|
2780
|
+
return buildVoiceRealCallProfileHistoryReport({
|
|
2781
|
+
...routeOptions,
|
|
2782
|
+
...sourceOptions
|
|
2783
|
+
});
|
|
2784
|
+
};
|
|
2785
|
+
var createVoiceRealCallProfileRecoveryActionRoutes = (options = {}) => {
|
|
2786
|
+
const path = options.path ?? "/api/voice/real-call-profile-history";
|
|
2787
|
+
const routes = new Elysia({
|
|
2788
|
+
name: options.name ?? "absolutejs-voice-real-call-profile-recovery-actions"
|
|
2789
|
+
});
|
|
2790
|
+
const actionPath = (actionId) => `${path}${realCallProfileActionPaths[actionId]}`;
|
|
2791
|
+
const loadReport = () => loadVoiceRealCallProfileHistoryRouteReport(options);
|
|
2792
|
+
const asyncActionIds = new Set(options.asyncActionIds ?? []);
|
|
2793
|
+
const listActions = async () => {
|
|
2794
|
+
const report = await loadReport();
|
|
2795
|
+
const actions = buildVoiceRealCallProfileRecoveryActions(report, {
|
|
2796
|
+
...options,
|
|
2797
|
+
browserProofHref: options.browserProofHref ?? actionPath("collect-browser-proof"),
|
|
2798
|
+
phoneProofHref: options.phoneProofHref ?? actionPath("collect-phone-proof"),
|
|
2799
|
+
sourceHref: options.sourceHref ?? actionPath("collect-provider-role-evidence"),
|
|
2800
|
+
productionReadinessHref: options.productionReadinessHref ?? actionPath("refresh")
|
|
2801
|
+
}).map((action) => ({
|
|
2802
|
+
...action,
|
|
2803
|
+
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,
|
|
2804
|
+
method: action.id === "refresh" && (action.label === "Open real-call profile history" || action.label === "Open operations records") ? "GET" : "POST"
|
|
2805
|
+
}));
|
|
2806
|
+
return { actions, generatedAt: new Date().toISOString(), report };
|
|
2807
|
+
};
|
|
2808
|
+
const runActionHandler = async (actionId, report) => {
|
|
2809
|
+
const handler = options.handlers?.[actionId];
|
|
2810
|
+
if (!handler) {
|
|
2811
|
+
return;
|
|
2812
|
+
}
|
|
2813
|
+
return await handler({ actionId, report });
|
|
2814
|
+
};
|
|
2815
|
+
const runActionAsJob = async (actionId, report) => {
|
|
2816
|
+
const job = await options.jobStore?.create({
|
|
2817
|
+
actionId,
|
|
2818
|
+
message: `Queued real-call profile recovery action: ${actionId}.`,
|
|
2819
|
+
status: "queued"
|
|
2820
|
+
});
|
|
2821
|
+
if (!job) {
|
|
2822
|
+
return;
|
|
2823
|
+
}
|
|
2824
|
+
queueMicrotask(() => {
|
|
2825
|
+
(async () => {
|
|
2826
|
+
const startedAt = new Date().toISOString();
|
|
2827
|
+
await options.jobStore?.update(job.id, {
|
|
2828
|
+
message: `Running real-call profile recovery action: ${actionId}.`,
|
|
2829
|
+
startedAt,
|
|
2830
|
+
status: "running",
|
|
2831
|
+
updatedAt: startedAt
|
|
2832
|
+
});
|
|
2833
|
+
try {
|
|
2834
|
+
const result = await runActionHandler(actionId, report);
|
|
2835
|
+
const completedAt = new Date().toISOString();
|
|
2836
|
+
const ok = result?.ok ?? true;
|
|
2837
|
+
const status = result?.jobStatus ?? (result?.status === "fail" || ok === false ? "fail" : "pass");
|
|
2838
|
+
await options.jobStore?.update(job.id, {
|
|
2839
|
+
completedAt,
|
|
2840
|
+
message: result?.message ?? `Completed real-call profile recovery action: ${actionId}.`,
|
|
2841
|
+
ok,
|
|
2842
|
+
report: result?.report,
|
|
2843
|
+
status,
|
|
2844
|
+
updatedAt: completedAt
|
|
2845
|
+
});
|
|
2846
|
+
} catch (error) {
|
|
2847
|
+
const completedAt = new Date().toISOString();
|
|
2848
|
+
await options.jobStore?.update(job.id, {
|
|
2849
|
+
completedAt,
|
|
2850
|
+
message: error instanceof Error ? error.message : `Failed real-call profile recovery action: ${actionId}.`,
|
|
2851
|
+
ok: false,
|
|
2852
|
+
status: "fail",
|
|
2853
|
+
updatedAt: completedAt
|
|
2854
|
+
});
|
|
2855
|
+
}
|
|
2856
|
+
})();
|
|
2857
|
+
});
|
|
2858
|
+
return {
|
|
2859
|
+
actionId,
|
|
2860
|
+
generatedAt: new Date().toISOString(),
|
|
2861
|
+
job,
|
|
2862
|
+
jobId: job.id,
|
|
2863
|
+
jobStatus: job.status,
|
|
2864
|
+
message: job.message,
|
|
2865
|
+
ok: true,
|
|
2866
|
+
status: "pass"
|
|
2867
|
+
};
|
|
2868
|
+
};
|
|
2869
|
+
const runAction = async (actionId) => {
|
|
2870
|
+
const report = await loadReport();
|
|
2871
|
+
const handler = options.handlers?.[actionId];
|
|
2872
|
+
if (!handler) {
|
|
2873
|
+
return {
|
|
2874
|
+
actionId,
|
|
2875
|
+
generatedAt: new Date().toISOString(),
|
|
2876
|
+
message: `No handler configured for real-call profile recovery action: ${actionId}.`,
|
|
2877
|
+
ok: false,
|
|
2878
|
+
status: "fail"
|
|
2879
|
+
};
|
|
2880
|
+
}
|
|
2881
|
+
if (options.jobStore && asyncActionIds.has(actionId)) {
|
|
2882
|
+
const queued = await runActionAsJob(actionId, report);
|
|
2883
|
+
if (queued) {
|
|
2884
|
+
return queued;
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
const result = await runActionHandler(actionId, report);
|
|
2888
|
+
return {
|
|
2889
|
+
actionId,
|
|
2890
|
+
generatedAt: new Date().toISOString(),
|
|
2891
|
+
job: result?.job,
|
|
2892
|
+
jobId: result?.jobId,
|
|
2893
|
+
jobStatus: result?.jobStatus,
|
|
2894
|
+
message: result?.message,
|
|
2895
|
+
ok: result?.ok ?? true,
|
|
2896
|
+
report: result?.report,
|
|
2897
|
+
status: result?.status ?? "pass"
|
|
2898
|
+
};
|
|
2899
|
+
};
|
|
2900
|
+
routes.get(`${path}/actions`, async () => Response.json(await listActions(), { headers: options.headers }));
|
|
2901
|
+
routes.get(`${path}/actions/:jobId`, async ({
|
|
2902
|
+
params,
|
|
2903
|
+
set
|
|
2904
|
+
}) => {
|
|
2905
|
+
const jobId = params.jobId ?? "";
|
|
2906
|
+
const job = await options.jobStore?.get(jobId);
|
|
2907
|
+
if (!job) {
|
|
2908
|
+
set.status = 404;
|
|
2909
|
+
return Response.json({
|
|
2910
|
+
jobId,
|
|
2911
|
+
message: `No real-call profile recovery job found for id: ${jobId}.`,
|
|
2912
|
+
ok: false
|
|
2913
|
+
}, { headers: options.headers });
|
|
2914
|
+
}
|
|
2915
|
+
return Response.json({ job, ok: job.ok ?? job.status !== "fail" }, {
|
|
2916
|
+
headers: options.headers
|
|
2917
|
+
});
|
|
2918
|
+
});
|
|
2919
|
+
for (const actionId of Object.keys(realCallProfileActionPaths)) {
|
|
2920
|
+
routes.post(actionPath(actionId), async ({ set }) => {
|
|
2921
|
+
const result = await runAction(actionId);
|
|
2922
|
+
if (!result.ok) {
|
|
2923
|
+
set.status = 501;
|
|
2924
|
+
}
|
|
2925
|
+
return Response.json(result, { headers: options.headers });
|
|
2926
|
+
});
|
|
2927
|
+
}
|
|
2928
|
+
return routes;
|
|
2929
|
+
};
|
|
2728
2930
|
var createVoiceProofTrendRoutes = (options) => {
|
|
2729
2931
|
const path = options.path ?? "/api/voice/proof-trends";
|
|
2730
2932
|
const routes = new Elysia({
|