@absolutejs/voice 0.0.22-beta.527 → 0.0.22-beta.529
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular/index.js +3 -1
- package/dist/client/htmxBootstrap.js +3 -1
- package/dist/client/index.js +290 -304
- package/dist/embed/index.js +3 -1
- package/dist/embed/voice-widget.js +7 -7
- package/dist/index.d.ts +4 -6
- package/dist/index.js +525 -905
- package/dist/internal/html.d.ts +6 -0
- package/dist/internal/status.d.ts +9 -0
- package/dist/react/index.js +287 -300
- package/dist/svelte/index.js +181 -198
- package/dist/testing/index.js +69 -69
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/index.js +231 -239
- package/package.json +2 -3
- package/dist/generated/htmxBootstrapBundle.d.ts +0 -1
- package/fixtures/README.md +0 -57
- package/fixtures/manifest.json +0 -358
- package/fixtures/pcm/dialogue-three-clean.pcm +0 -0
- package/fixtures/pcm/dialogue-three-mixed.pcm +0 -0
- package/fixtures/pcm/dialogue-two-clean.pcm +0 -0
- package/fixtures/pcm/dialogue-two-noisy.pcm +0 -0
- package/fixtures/pcm/multiturn-three-mixed.pcm +0 -0
- package/fixtures/pcm/multiturn-two-clean.pcm +0 -0
- package/fixtures/pcm/quietly-alone-clean.pcm +0 -0
- package/fixtures/pcm/rainstorms-noisy.pcm +0 -0
- package/fixtures/pcm/stella-bulgaria-bulgarian20.pcm +0 -0
- package/fixtures/pcm/stella-ghana-english507.pcm +0 -0
- package/fixtures/pcm/stella-india-english37.pcm +0 -0
- package/fixtures/pcm/stella-jamaica-jamaican-creole-english1.pcm +0 -0
- package/fixtures/pcm/stella-liberia-liberian-pidgin-english2.pcm +0 -0
- package/fixtures/pcm/stella-pakistan-english519.pcm +0 -0
- package/fixtures/pcm/stella-sierra-leone-krio5.pcm +0 -0
- package/fixtures/pcm/stella-singapore-english655.pcm +0 -0
- package/fixtures/pcm/traveled-back-route-clean.pcm +0 -0
package/dist/vue/index.js
CHANGED
|
@@ -86,6 +86,9 @@ var __require = import.meta.require;
|
|
|
86
86
|
// src/vue/VoiceOpsStatus.ts
|
|
87
87
|
import { defineComponent, h } from "vue";
|
|
88
88
|
|
|
89
|
+
// src/internal/html.ts
|
|
90
|
+
var escapeHtml = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
91
|
+
|
|
89
92
|
// src/client/opsStatus.ts
|
|
90
93
|
var fetchVoiceOpsStatus = async (path = "/api/voice/ops-status", options = {}) => {
|
|
91
94
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -175,7 +178,6 @@ var SURFACE_LABELS = {
|
|
|
175
178
|
sessions: "Sessions",
|
|
176
179
|
workflows: "Workflows"
|
|
177
180
|
};
|
|
178
|
-
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
179
181
|
var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
|
|
180
182
|
var surfaceDetail = (surface) => {
|
|
181
183
|
const total = readNumber(surface, "total");
|
|
@@ -585,7 +587,6 @@ var createVoiceOpsActionCenterStore = (options = {}) => {
|
|
|
585
587
|
// src/client/opsActionCenterWidget.ts
|
|
586
588
|
var DEFAULT_TITLE2 = "Voice Ops Action Center";
|
|
587
589
|
var DEFAULT_DESCRIPTION2 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
588
|
-
var escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
589
590
|
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
590
591
|
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
591
592
|
return {
|
|
@@ -607,18 +608,18 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
|
607
608
|
};
|
|
608
609
|
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
609
610
|
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
610
|
-
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${
|
|
611
|
-
${
|
|
611
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
612
|
+
${escapeHtml(action.isRunning ? "Working..." : action.label)}
|
|
612
613
|
</button>`).join("");
|
|
613
|
-
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${
|
|
614
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml(model.status)}">
|
|
614
615
|
<header class="absolute-voice-ops-action-center__header">
|
|
615
|
-
<span class="absolute-voice-ops-action-center__eyebrow">${
|
|
616
|
-
<strong class="absolute-voice-ops-action-center__label">${
|
|
616
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml(model.title)}</span>
|
|
617
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml(model.label)}</strong>
|
|
617
618
|
</header>
|
|
618
|
-
<p class="absolute-voice-ops-action-center__description">${
|
|
619
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml(model.description)}</p>
|
|
619
620
|
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
620
|
-
<p class="absolute-voice-ops-action-center__result">${
|
|
621
|
-
${model.error ? `<p class="absolute-voice-ops-action-center__error">${
|
|
621
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml(model.lastResultLabel)}</p>
|
|
622
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml(model.error)}</p>` : ""}
|
|
622
623
|
</section>`;
|
|
623
624
|
};
|
|
624
625
|
var getVoiceOpsActionCenterCSS = () => `.absolute-voice-ops-action-center{border:1px solid #d5cbb8;border-radius:20px;background:#fffaf1;color:#17130b;padding:18px;box-shadow:0 18px 40px rgba(58,42,16,.12);font-family:inherit}.absolute-voice-ops-action-center--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-ops-action-center__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-center__eyebrow{color:#725d37;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-center__label{font-size:28px;line-height:1}.absolute-voice-ops-action-center__description,.absolute-voice-ops-action-center__result{color:#5b4b2f;margin:12px 0 0}.absolute-voice-ops-action-center__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-ops-action-center__actions button{background:#7c4a03;border:0;border-radius:999px;color:#fff8e8;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-ops-action-center__actions button:disabled{cursor:not-allowed;opacity:.5}.absolute-voice-ops-action-center__error{color:#9f1239;font-weight:700}`;
|
|
@@ -899,7 +900,6 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
899
900
|
// src/client/deliveryRuntimeWidget.ts
|
|
900
901
|
var DEFAULT_TITLE3 = "Voice Delivery Runtime";
|
|
901
902
|
var DEFAULT_DESCRIPTION3 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
902
|
-
var escapeHtml3 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
903
903
|
var createSurface = (id, summary) => {
|
|
904
904
|
if (!summary) {
|
|
905
905
|
return {
|
|
@@ -948,26 +948,26 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
948
948
|
};
|
|
949
949
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
950
950
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
951
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
952
|
-
<span>${
|
|
953
|
-
<strong>${
|
|
951
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml(surface.status)}">
|
|
952
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
953
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
954
954
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
955
955
|
</li>`).join("");
|
|
956
956
|
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
957
957
|
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
958
958
|
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
959
959
|
</div>`;
|
|
960
|
-
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
961
|
-
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${
|
|
960
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml(model.actionError)}</p>` : "";
|
|
961
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml(model.status)}">
|
|
962
962
|
<header class="absolute-voice-delivery-runtime__header">
|
|
963
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
964
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
963
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml(model.title)}</span>
|
|
964
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml(model.label)}</strong>
|
|
965
965
|
</header>
|
|
966
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
966
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml(model.description)}</p>
|
|
967
967
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
968
968
|
${actions}
|
|
969
969
|
${actionError}
|
|
970
|
-
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
970
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml(model.error)}</p>` : ""}
|
|
971
971
|
</section>`;
|
|
972
972
|
};
|
|
973
973
|
var getVoiceDeliveryRuntimeCSS = () => `.absolute-voice-delivery-runtime{border:1px solid #c9d8cf;border-radius:20px;background:#f6fff9;color:#0d1b12;padding:18px;box-shadow:0 18px 40px rgba(19,55,35,.12);font-family:inherit}.absolute-voice-delivery-runtime--warn,.absolute-voice-delivery-runtime--error{border-color:#f2b56b;background:#fff9ed}.absolute-voice-delivery-runtime__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-delivery-runtime__eyebrow{color:#4e6b59;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-delivery-runtime__label{font-size:28px;line-height:1}.absolute-voice-delivery-runtime__description{color:#33483b;margin:12px 0 0}.absolute-voice-delivery-runtime__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-delivery-runtime__surface{background:#fff;border:1px solid #d9eadf;border-radius:14px;display:grid;gap:4px;padding:10px 12px}.absolute-voice-delivery-runtime__surface--warn{border-color:#f2b56b}.absolute-voice-delivery-runtime__surface--disabled{opacity:.72}.absolute-voice-delivery-runtime__surface span,.absolute-voice-delivery-runtime__surface small{color:#587063}.absolute-voice-delivery-runtime__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-delivery-runtime__actions button{background:#134e2d;border:0;border-radius:999px;color:#f6fff9;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-delivery-runtime__actions button:disabled{cursor:not-allowed;opacity:.48}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
|
|
@@ -1266,7 +1266,6 @@ var DEFAULT_LINKS = [
|
|
|
1266
1266
|
{ href: "/switching-from-vapi", label: "Switching guide" },
|
|
1267
1267
|
{ href: "/api/voice/vapi-coverage", label: "Coverage JSON" }
|
|
1268
1268
|
];
|
|
1269
|
-
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1270
1269
|
var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1271
1270
|
var surfaceDetail2 = (surface) => {
|
|
1272
1271
|
if (surface.status === "pass") {
|
|
@@ -1303,24 +1302,24 @@ var createVoicePlatformCoverageViewModel = (snapshot, options = {}) => {
|
|
|
1303
1302
|
};
|
|
1304
1303
|
var renderVoicePlatformCoverageHTML = (snapshot, options = {}) => {
|
|
1305
1304
|
const model = createVoicePlatformCoverageViewModel(snapshot, options);
|
|
1306
|
-
const surfaces = model.surfaces.length ? `<div class="absolute-voice-platform-coverage__surfaces">${model.surfaces.map((surface) => `<article class="absolute-voice-platform-coverage__surface absolute-voice-platform-coverage__surface--${
|
|
1305
|
+
const surfaces = model.surfaces.length ? `<div class="absolute-voice-platform-coverage__surfaces">${model.surfaces.map((surface) => `<article class="absolute-voice-platform-coverage__surface absolute-voice-platform-coverage__surface--${escapeHtml(surface.status)}">
|
|
1307
1306
|
<header>
|
|
1308
|
-
<strong>${
|
|
1309
|
-
<span>${
|
|
1307
|
+
<strong>${escapeHtml(surface.label)}</strong>
|
|
1308
|
+
<span>${escapeHtml(formatStatus(surface.status))}</span>
|
|
1310
1309
|
</header>
|
|
1311
|
-
<p>${
|
|
1310
|
+
<p>${escapeHtml(surface.detail)}</p>
|
|
1312
1311
|
<small>${surface.evidence.filter((item) => item.ok).length}/${surface.evidence.length} evidence checks passing</small>
|
|
1313
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-platform-coverage__empty">${model.error ?
|
|
1314
|
-
const links = model.links.length ? `<p class="absolute-voice-platform-coverage__links">${model.links.map((link) => `<a href="${
|
|
1315
|
-
return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${
|
|
1312
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-platform-coverage__empty">${model.error ? escapeHtml(model.error) : "Run the proof pack to populate platform coverage evidence."}</p>`;
|
|
1313
|
+
const links = model.links.length ? `<p class="absolute-voice-platform-coverage__links">${model.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</p>` : "";
|
|
1314
|
+
return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${escapeHtml(model.status)}">
|
|
1316
1315
|
<header class="absolute-voice-platform-coverage__header">
|
|
1317
|
-
<span class="absolute-voice-platform-coverage__eyebrow">${
|
|
1318
|
-
<strong class="absolute-voice-platform-coverage__label">${
|
|
1316
|
+
<span class="absolute-voice-platform-coverage__eyebrow">${escapeHtml(model.title)}</span>
|
|
1317
|
+
<strong class="absolute-voice-platform-coverage__label">${escapeHtml(model.label)}</strong>
|
|
1319
1318
|
</header>
|
|
1320
|
-
<p class="absolute-voice-platform-coverage__description">${
|
|
1319
|
+
<p class="absolute-voice-platform-coverage__description">${escapeHtml(model.description)}</p>
|
|
1321
1320
|
${surfaces}
|
|
1322
1321
|
${links}
|
|
1323
|
-
${model.error ? `<p class="absolute-voice-platform-coverage__error">${
|
|
1322
|
+
${model.error ? `<p class="absolute-voice-platform-coverage__error">${escapeHtml(model.error)}</p>` : ""}
|
|
1324
1323
|
</section>`;
|
|
1325
1324
|
};
|
|
1326
1325
|
var getVoicePlatformCoverageCSS = () => `.absolute-voice-platform-coverage{border:1px solid #c7d2fe;border-radius:20px;background:#f8fbff;color:#111827;padding:18px;box-shadow:0 18px 40px rgba(30,64,175,.12);font-family:inherit}.absolute-voice-platform-coverage--warning,.absolute-voice-platform-coverage--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-platform-coverage__header,.absolute-voice-platform-coverage__surface header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-platform-coverage__eyebrow{color:#1d4ed8;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-platform-coverage__label{font-size:24px;line-height:1}.absolute-voice-platform-coverage__description,.absolute-voice-platform-coverage__surface p,.absolute-voice-platform-coverage__surface small,.absolute-voice-platform-coverage__empty{color:#475569}.absolute-voice-platform-coverage__surfaces{display:grid;gap:10px;margin-top:14px}.absolute-voice-platform-coverage__surface{background:#fff;border:1px solid #dbeafe;border-radius:16px;padding:12px}.absolute-voice-platform-coverage__surface--pass{border-color:#86efac}.absolute-voice-platform-coverage__surface--fail,.absolute-voice-platform-coverage__surface--missing,.absolute-voice-platform-coverage__surface--stale{border-color:#f2a7a7}.absolute-voice-platform-coverage__surface p{margin:8px 0}.absolute-voice-platform-coverage__surface span{text-transform:capitalize}.absolute-voice-platform-coverage__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-platform-coverage__links a{border:1px solid #bfdbfe;border-radius:999px;color:#1d4ed8;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-platform-coverage__error{color:#9f1239;font-weight:700}`;
|
|
@@ -1430,6 +1429,18 @@ import { defineComponent as defineComponent5, h as h5 } from "vue";
|
|
|
1430
1429
|
// src/proofTrends.ts
|
|
1431
1430
|
import { Elysia as Elysia4 } from "elysia";
|
|
1432
1431
|
|
|
1432
|
+
// src/internal/status.ts
|
|
1433
|
+
var voiceStatusRank = (status) => status === "fail" ? 2 : status === "warn" ? 1 : 0;
|
|
1434
|
+
var worstVoiceStatus = (statuses) => {
|
|
1435
|
+
let worst = "pass";
|
|
1436
|
+
for (const status of statuses) {
|
|
1437
|
+
if (voiceStatusRank(status) > voiceStatusRank(worst)) {
|
|
1438
|
+
worst = status;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
return worst;
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1433
1444
|
// src/providerDecisionTraces.ts
|
|
1434
1445
|
import { Elysia as Elysia3 } from "elysia";
|
|
1435
1446
|
|
|
@@ -1578,16 +1589,15 @@ var summarizeVoiceProviderHealth = async (input) => {
|
|
|
1578
1589
|
}
|
|
1579
1590
|
return summaries;
|
|
1580
1591
|
};
|
|
1581
|
-
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1582
1592
|
var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p class="voice-provider-empty">No provider status yet.</p>' : [
|
|
1583
1593
|
'<div class="voice-provider-health">',
|
|
1584
1594
|
...providers.map((provider) => {
|
|
1585
1595
|
const suppressionSeconds = typeof provider.suppressionRemainingMs === "number" ? Math.ceil(provider.suppressionRemainingMs / 1000) : undefined;
|
|
1586
1596
|
return [
|
|
1587
|
-
`<article class="voice-provider-card ${
|
|
1597
|
+
`<article class="voice-provider-card ${escapeHtml(provider.status)}">`,
|
|
1588
1598
|
'<div class="voice-provider-card-header">',
|
|
1589
|
-
`<strong>${
|
|
1590
|
-
`<span>${
|
|
1599
|
+
`<strong>${escapeHtml(provider.provider)}</strong>`,
|
|
1600
|
+
`<span>${escapeHtml(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>`,
|
|
1591
1601
|
"</div>",
|
|
1592
1602
|
"<dl>",
|
|
1593
1603
|
`<div><dt>Runs</dt><dd>${String(provider.runCount)}</dd></div>`,
|
|
@@ -1597,7 +1607,7 @@ var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p
|
|
|
1597
1607
|
`<div><dt>Fallbacks</dt><dd>${String(provider.fallbackCount)}</dd></div>`,
|
|
1598
1608
|
"</dl>",
|
|
1599
1609
|
suppressionSeconds ? `<p>Temporarily suppressed for ${String(suppressionSeconds)}s.</p>` : "",
|
|
1600
|
-
provider.lastError ? `<p>${
|
|
1610
|
+
provider.lastError ? `<p>${escapeHtml(provider.lastError)}</p>` : "",
|
|
1601
1611
|
"</article>"
|
|
1602
1612
|
].join("");
|
|
1603
1613
|
}),
|
|
@@ -1628,7 +1638,6 @@ var createVoiceProviderHealthRoutes = (options) => {
|
|
|
1628
1638
|
};
|
|
1629
1639
|
|
|
1630
1640
|
// src/resilienceRoutes.ts
|
|
1631
|
-
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1632
1641
|
var getString2 = (value) => typeof value === "string" ? value : undefined;
|
|
1633
1642
|
var getNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
1634
1643
|
var getBoolean = (value) => value === true;
|
|
@@ -1776,13 +1785,13 @@ var summarizeRoutingEvents = (events) => {
|
|
|
1776
1785
|
};
|
|
1777
1786
|
var renderProviderCards = (title, providers) => {
|
|
1778
1787
|
if (providers.length === 0) {
|
|
1779
|
-
return `<p class="muted">No ${
|
|
1788
|
+
return `<p class="muted">No ${escapeHtml(title)} provider health yet.</p>`;
|
|
1780
1789
|
}
|
|
1781
1790
|
return `<div class="provider-grid">${providers.map((provider) => `
|
|
1782
|
-
<article class="card provider ${
|
|
1791
|
+
<article class="card provider ${escapeHtml(provider.status)}">
|
|
1783
1792
|
<div class="card-header">
|
|
1784
|
-
<strong>${
|
|
1785
|
-
<span>${
|
|
1793
|
+
<strong>${escapeHtml(provider.provider)}</strong>
|
|
1794
|
+
<span>${escapeHtml(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
|
|
1786
1795
|
</div>
|
|
1787
1796
|
<dl>
|
|
1788
1797
|
<div><dt>Runs</dt><dd>${provider.runCount}</dd></div>
|
|
@@ -1791,7 +1800,7 @@ var renderProviderCards = (title, providers) => {
|
|
|
1791
1800
|
<div><dt>Timeouts</dt><dd>${provider.timeoutCount}</dd></div>
|
|
1792
1801
|
<div><dt>Fallbacks</dt><dd>${provider.fallbackCount}</dd></div>
|
|
1793
1802
|
</dl>
|
|
1794
|
-
${provider.lastError ? `<p class="muted">${
|
|
1803
|
+
${provider.lastError ? `<p class="muted">${escapeHtml(provider.lastError)}</p>` : ""}
|
|
1795
1804
|
</article>
|
|
1796
1805
|
`).join("")}</div>`;
|
|
1797
1806
|
};
|
|
@@ -1800,24 +1809,24 @@ var renderTimeline = (events) => {
|
|
|
1800
1809
|
return '<p class="muted">No provider routing events yet. Run the app or simulate provider failover.</p>';
|
|
1801
1810
|
}
|
|
1802
1811
|
return `<div class="timeline">${events.slice(0, 40).map((event) => `
|
|
1803
|
-
<article class="card event ${
|
|
1812
|
+
<article class="card event ${escapeHtml(event.status ?? "unknown")}">
|
|
1804
1813
|
<div class="card-header">
|
|
1805
|
-
<strong>${
|
|
1814
|
+
<strong>${escapeHtml(event.kind.toUpperCase())} ${escapeHtml(event.operation ?? "generate")}</strong>
|
|
1806
1815
|
<span>${new Date(event.at).toLocaleString()}</span>
|
|
1807
1816
|
</div>
|
|
1808
1817
|
<p>
|
|
1809
|
-
<span class="pill">${
|
|
1810
|
-
<span class="pill">provider: ${
|
|
1811
|
-
${event.fallbackProvider ? `<span class="pill">fallback: ${
|
|
1818
|
+
<span class="pill">${escapeHtml(event.status ?? "unknown")}</span>
|
|
1819
|
+
<span class="pill">provider: ${escapeHtml(event.provider ?? "unknown")}</span>
|
|
1820
|
+
${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml(event.fallbackProvider)}</span>` : ""}
|
|
1812
1821
|
${event.timedOut ? '<span class="pill danger">timed out</span>' : ""}
|
|
1813
1822
|
</p>
|
|
1814
1823
|
<dl>
|
|
1815
1824
|
<div><dt>Attempt</dt><dd>${event.attempt ?? 0}</dd></div>
|
|
1816
1825
|
<div><dt>Elapsed</dt><dd>${event.elapsedMs ?? 0}ms</dd></div>
|
|
1817
1826
|
<div><dt>Budget</dt><dd>${event.latencyBudgetMs ?? 0}ms</dd></div>
|
|
1818
|
-
<div><dt>Session</dt><dd>${
|
|
1827
|
+
<div><dt>Session</dt><dd>${escapeHtml(event.sessionId)}</dd></div>
|
|
1819
1828
|
</dl>
|
|
1820
|
-
${event.error ? `<p class="muted">${
|
|
1829
|
+
${event.error ? `<p class="muted">${escapeHtml(event.error)}</p>` : ""}
|
|
1821
1830
|
</article>
|
|
1822
1831
|
`).join("")}</div>`;
|
|
1823
1832
|
};
|
|
@@ -1827,9 +1836,9 @@ var renderSessionKind = (kind, summary) => {
|
|
|
1827
1836
|
const status = latest?.status ?? "idle";
|
|
1828
1837
|
const fallback = latest?.fallbackProvider && latest.fallbackProvider !== provider ? ` -> ${latest.fallbackProvider}` : "";
|
|
1829
1838
|
return `<div>
|
|
1830
|
-
<dt>${
|
|
1831
|
-
<dd>${
|
|
1832
|
-
<small>${
|
|
1839
|
+
<dt>${escapeHtml(kind.toUpperCase())}</dt>
|
|
1840
|
+
<dd>${escapeHtml(provider)}${escapeHtml(fallback)}</dd>
|
|
1841
|
+
<small>${escapeHtml(status)} \xB7 ${summary.runCount} event${summary.runCount === 1 ? "" : "s"} \xB7 ${summary.errorCount} error${summary.errorCount === 1 ? "" : "s"} \xB7 ${summary.fallbackCount} fallback${summary.fallbackCount === 1 ? "" : "s"}</small>
|
|
1833
1842
|
</div>`;
|
|
1834
1843
|
};
|
|
1835
1844
|
var renderSessionSummaries = (sessions) => {
|
|
@@ -1837,10 +1846,10 @@ var renderSessionSummaries = (sessions) => {
|
|
|
1837
1846
|
return '<p class="muted">No call-level routing summaries yet. Run a voice session or provider simulation.</p>';
|
|
1838
1847
|
}
|
|
1839
1848
|
return `<div class="session-grid">${sessions.slice(0, 12).map((session) => `
|
|
1840
|
-
<article class="card session ${
|
|
1849
|
+
<article class="card session ${escapeHtml(session.status)}">
|
|
1841
1850
|
<div class="card-header">
|
|
1842
|
-
<strong>${
|
|
1843
|
-
<span>${
|
|
1851
|
+
<strong>${escapeHtml(session.sessionId)}</strong>
|
|
1852
|
+
<span>${escapeHtml(session.status)}</span>
|
|
1844
1853
|
</div>
|
|
1845
1854
|
<p>
|
|
1846
1855
|
<span class="pill">${session.eventCount} routing events</span>
|
|
@@ -1867,21 +1876,21 @@ var renderSimulationControls = (kind, simulation) => {
|
|
|
1867
1876
|
const pathPrefix = simulation.pathPrefix ?? `/api/${kind}-simulate`;
|
|
1868
1877
|
const failureProviders = simulation.failureProviders ?? configuredProviders.map(({ provider }) => provider);
|
|
1869
1878
|
const canFail = (provider) => configuredProviders.some((entry) => entry.provider === provider) && (!simulation.fallbackRequiredProvider || configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider));
|
|
1870
|
-
return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${
|
|
1871
|
-
<p class="muted">${
|
|
1879
|
+
return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml(pathPrefix)}">
|
|
1880
|
+
<p class="muted">${escapeHtml(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
|
|
1872
1881
|
<div class="simulate-actions">
|
|
1873
|
-
${failureProviders.map((provider) => `<button type="button" data-provider-fail="${
|
|
1874
|
-
${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${
|
|
1882
|
+
${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
|
|
1883
|
+
${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml(provider.provider)}">Mark ${escapeHtml(provider.provider)} recovered</button>`).join("")}
|
|
1875
1884
|
</div>
|
|
1876
|
-
${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${
|
|
1885
|
+
${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
|
|
1877
1886
|
<pre class="simulate-output" hidden></pre>
|
|
1878
1887
|
</div>`;
|
|
1879
1888
|
};
|
|
1880
1889
|
var renderVoiceResilienceHTML = (input) => {
|
|
1881
1890
|
const summary = summarizeRoutingEvents(input.routingEvents);
|
|
1882
|
-
const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${
|
|
1883
|
-
const links = input.links?.length ? input.links.map((link) => `<a href="${
|
|
1884
|
-
const snippet =
|
|
1891
|
+
const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml(kind)}: ${String(count)}</span>`).join("");
|
|
1892
|
+
const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join(" \xB7 ") : "";
|
|
1893
|
+
const snippet = escapeHtml(`const sttSimulator = createVoiceIOProviderFailureSimulator({
|
|
1885
1894
|
kind: 'stt',
|
|
1886
1895
|
providers: ['deepgram', 'assemblyai'],
|
|
1887
1896
|
fallback: ['deepgram', 'assemblyai'],
|
|
@@ -1919,7 +1928,7 @@ app.use(
|
|
|
1919
1928
|
<head>
|
|
1920
1929
|
<meta charset="utf-8" />
|
|
1921
1930
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1922
|
-
<title>${
|
|
1931
|
+
<title>${escapeHtml(input.title ?? "AbsoluteJS Voice Resilience")}</title>
|
|
1923
1932
|
<style>
|
|
1924
1933
|
:root { color-scheme: dark; }
|
|
1925
1934
|
body { background: radial-gradient(circle at top left, #172554, #09090b 36%, #050505); color: #f4f4f5; font-family: ui-sans-serif, system-ui, sans-serif; margin: 0; padding: 24px; }
|
|
@@ -2112,7 +2121,6 @@ var createVoiceResilienceRoutes = (options) => {
|
|
|
2112
2121
|
};
|
|
2113
2122
|
|
|
2114
2123
|
// src/providerDecisionTraces.ts
|
|
2115
|
-
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2116
2124
|
var getString3 = (value) => typeof value === "string" ? value : undefined;
|
|
2117
2125
|
var getNumber3 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
2118
2126
|
var isDecisionTrace = (event) => Boolean(event && typeof event === "object" && "provider" in event && "reason" in event && "sessionId" in event && "status" in event && "surface" in event);
|
|
@@ -2127,8 +2135,7 @@ var surfaceForKind = (kind) => {
|
|
|
2127
2135
|
return "live-call";
|
|
2128
2136
|
}
|
|
2129
2137
|
};
|
|
2130
|
-
var
|
|
2131
|
-
var reportStatus = (issues) => issues.reduce((status, issue) => statusRank[issue.status] > statusRank[status] ? issue.status : status, "pass");
|
|
2138
|
+
var reportStatus = (issues) => worstVoiceStatus(issues.map((issue) => issue.status));
|
|
2132
2139
|
var uniqueSorted = (values) => [
|
|
2133
2140
|
...new Set(values.filter((value) => typeof value === "string"))
|
|
2134
2141
|
].sort();
|
|
@@ -2353,7 +2360,7 @@ var renderVoiceProviderDecisionTraceHTML = (report, title = "Provider Decision T
|
|
|
2353
2360
|
<head>
|
|
2354
2361
|
<meta charset="utf-8" />
|
|
2355
2362
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
2356
|
-
<title>${
|
|
2363
|
+
<title>${escapeHtml(title)}</title>
|
|
2357
2364
|
<style>
|
|
2358
2365
|
body{font-family:ui-sans-serif,system-ui,sans-serif;margin:0;background:#f8fafc;color:#0f172a}
|
|
2359
2366
|
main{max-width:1100px;margin:0 auto;padding:32px}
|
|
@@ -2367,8 +2374,8 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
|
|
|
2367
2374
|
</head>
|
|
2368
2375
|
<body>
|
|
2369
2376
|
<main>
|
|
2370
|
-
<p class="status ${report.status}">${
|
|
2371
|
-
<h1>${
|
|
2377
|
+
<p class="status ${report.status}">${escapeHtml(report.status)}</p>
|
|
2378
|
+
<h1>${escapeHtml(title)}</h1>
|
|
2372
2379
|
<p class="muted">Runtime proof for why providers were selected, skipped, failed, or recovered by fallback.</p>
|
|
2373
2380
|
<section class="grid">
|
|
2374
2381
|
<article class="card"><strong>${String(report.summary.decisions)}</strong><p>decisions</p></article>
|
|
@@ -2379,10 +2386,10 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
|
|
|
2379
2386
|
</section>
|
|
2380
2387
|
<section class="surfaces">
|
|
2381
2388
|
${report.surfaces.map((surface) => `<article class="surface">
|
|
2382
|
-
<header><strong>${
|
|
2389
|
+
<header><strong>${escapeHtml(surface.surface)}</strong> <span class="status ${surface.status}">${escapeHtml(surface.status)}</span></header>
|
|
2383
2390
|
<p>${String(surface.decisions)} decision(s), ${String(surface.fallbacks)} fallback(s), ${String(surface.degraded)} degraded decision(s), ${String(surface.errors)} error(s).</p>
|
|
2384
|
-
<p class="muted">Providers: ${
|
|
2385
|
-
<p>${surface.reasons.map((reason) => `<code>${
|
|
2391
|
+
<p class="muted">Providers: ${escapeHtml(surface.providers.join(", ") || "none")}</p>
|
|
2392
|
+
<p>${surface.reasons.map((reason) => `<code>${escapeHtml(reason)}</code>`).join(" ")}</p>
|
|
2386
2393
|
</article>`).join(`
|
|
2387
2394
|
`)}
|
|
2388
2395
|
</section>
|
|
@@ -2900,7 +2907,6 @@ var exportVoiceTrace = async (input) => {
|
|
|
2900
2907
|
};
|
|
2901
2908
|
};
|
|
2902
2909
|
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2903
|
-
var escapeHtml8 = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
2904
2910
|
var formatTraceValue = (value) => {
|
|
2905
2911
|
if (value === undefined || value === null) {
|
|
2906
2912
|
return "";
|
|
@@ -3184,10 +3190,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3184
3190
|
const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
|
|
3185
3191
|
return [
|
|
3186
3192
|
"<tr>",
|
|
3187
|
-
`<td>${
|
|
3188
|
-
`<td>${
|
|
3189
|
-
`<td>${
|
|
3190
|
-
`<td><code>${
|
|
3193
|
+
`<td>${escapeHtml(String(offset))}</td>`,
|
|
3194
|
+
`<td>${escapeHtml(event.type)}</td>`,
|
|
3195
|
+
`<td>${escapeHtml(event.turnId ?? "")}</td>`,
|
|
3196
|
+
`<td><code>${escapeHtml(JSON.stringify(event.payload))}</code></td>`,
|
|
3191
3197
|
"</tr>"
|
|
3192
3198
|
].join("");
|
|
3193
3199
|
}).join(`
|
|
@@ -3198,7 +3204,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3198
3204
|
"<head>",
|
|
3199
3205
|
'<meta charset="utf-8" />',
|
|
3200
3206
|
'<meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
3201
|
-
`<title>${
|
|
3207
|
+
`<title>${escapeHtml(options.title ?? "Voice Trace")}</title>`,
|
|
3202
3208
|
"<style>",
|
|
3203
3209
|
"body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
|
|
3204
3210
|
"main{max-width:1100px;margin:auto}",
|
|
@@ -3212,7 +3218,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3212
3218
|
"</style>",
|
|
3213
3219
|
"</head>",
|
|
3214
3220
|
"<body><main>",
|
|
3215
|
-
`<h1>${
|
|
3221
|
+
`<h1>${escapeHtml(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
|
|
3216
3222
|
`<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
|
|
3217
3223
|
'<section class="summary">',
|
|
3218
3224
|
`<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
|
|
@@ -3226,7 +3232,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3226
3232
|
eventRows,
|
|
3227
3233
|
"</tbody></table>",
|
|
3228
3234
|
"<h2>Markdown Export</h2>",
|
|
3229
|
-
`<pre>${
|
|
3235
|
+
`<pre>${escapeHtml(markdown)}</pre>`,
|
|
3230
3236
|
"</main></body></html>"
|
|
3231
3237
|
].join(`
|
|
3232
3238
|
`);
|
|
@@ -5605,7 +5611,6 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
5605
5611
|
}
|
|
5606
5612
|
};
|
|
5607
5613
|
};
|
|
5608
|
-
var escapeHtml9 = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5609
5614
|
var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
|
|
5610
5615
|
var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provider Runtime Recommendations") => [
|
|
5611
5616
|
`# ${title}`,
|
|
@@ -5640,11 +5645,11 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
|
|
|
5640
5645
|
].join(`
|
|
5641
5646
|
`);
|
|
5642
5647
|
var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider Runtime Recommendations") => {
|
|
5643
|
-
const cards = report.recommendations.map((recommendation) => `<article class="${
|
|
5644
|
-
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
5645
|
-
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${
|
|
5646
|
-
const profileRows = report.profiles.length === 0 ? "<li>No benchmark profiles were present.</li>" : report.profiles.map((profile) => `<li><strong>${
|
|
5647
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
5648
|
+
const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml(recommendation.status)}"><p class="eyebrow">${escapeHtml(recommendation.surface)} \xB7 ${escapeHtml(recommendation.status)}</p><h2>${escapeHtml(recommendation.recommendation)}</h2><p>${escapeHtml(recommendation.nextMove)}</p><pre>${escapeHtml(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
|
|
5649
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
5650
|
+
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml(provider.label ?? provider.id)}</strong><span>${escapeHtml(provider.role ?? "provider")} \xB7 ${escapeHtml(provider.status)} \xB7 p95 ${escapeHtml(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml(provider.nextMove)}</small></li>`).join("");
|
|
5651
|
+
const profileRows = report.profiles.length === 0 ? "<li>No benchmark profiles were present.</li>" : report.profiles.map((profile) => `<li><strong>${escapeHtml(profile.label ?? profile.id)}</strong><span>${escapeHtml(profile.status)} \xB7 ${escapeHtml(formatProviderMix(profile.bestProviders))}</span><small>${escapeHtml(profile.nextMove)}</small></li>`).join("");
|
|
5652
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml(title)}</h1><p>Generated ${escapeHtml(report.generatedAt)} from ${escapeHtml(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best mix ${escapeHtml(formatProviderMix(report.bestProviders))}</span><span class="pill">Profiles ${String(report.profiles.length)}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Benchmark Profiles</h2><ul>${profileRows}</ul></section><section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
5648
5653
|
};
|
|
5649
5654
|
var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Call Profile History") => [
|
|
5650
5655
|
`# ${title}`,
|
|
@@ -5678,11 +5683,11 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
|
|
|
5678
5683
|
].join(`
|
|
5679
5684
|
`);
|
|
5680
5685
|
var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
|
|
5681
|
-
const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${
|
|
5682
|
-
const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${
|
|
5683
|
-
const recommendations = report.recommendations.recommendations.map((recommendation) => `<article class="${
|
|
5684
|
-
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
5685
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
5686
|
+
const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${escapeHtml(profile.label ?? profile.id)}</td><td>${escapeHtml(profile.status ?? "unknown")}</td><td>${escapeHtml(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml(profile.maxTurnP95Ms ?? "n/a")}</td><td>${escapeHtml(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profiles present.</td></tr>';
|
|
5687
|
+
const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${escapeHtml(profile.label ?? profile.profileId)}</td><td>${escapeHtml(profile.status)}</td><td>${escapeHtml(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")}</td><td>${escapeHtml(profile.latencyBudgets.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml(profile.latencyBudgets.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml(profile.latencyBudgets.maxTurnP95Ms ?? "n/a")}</td></tr>`).join("") : '<tr><td colspan="6">No actionable defaults present.</td></tr>';
|
|
5688
|
+
const recommendations = report.recommendations.recommendations.map((recommendation) => `<article class="${escapeHtml(recommendation.status)}"><p class="eyebrow">${escapeHtml(recommendation.surface)} \xB7 ${escapeHtml(recommendation.status)}</p><h2>${escapeHtml(recommendation.recommendation)}</h2><p>${escapeHtml(recommendation.nextMove)}</p></article>`).join("");
|
|
5689
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
5690
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml(title)}</title><style>body{background:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #52624b;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</p><h1>${escapeHtml(title)}</h1><p>Generated ${escapeHtml(report.generatedAt)} from ${escapeHtml(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml(report.status)}</span><span class="pill">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
5686
5691
|
};
|
|
5687
5692
|
var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Call Evidence Runtime") => [
|
|
5688
5693
|
`# ${title}`,
|
|
@@ -5705,9 +5710,9 @@ var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Ca
|
|
|
5705
5710
|
].join(`
|
|
5706
5711
|
`);
|
|
5707
5712
|
var renderVoiceRealCallEvidenceRuntimeHTML = (report, title = "Voice Real-Call Evidence Runtime") => {
|
|
5708
|
-
const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
5709
|
-
const profileRows = report.history.summary.profiles?.length ? report.history.summary.profiles.map((profile) => `<tr><td>${
|
|
5710
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
5713
|
+
const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
5714
|
+
const profileRows = report.history.summary.profiles?.length ? report.history.summary.profiles.map((profile) => `<tr><td>${escapeHtml(profile.label ?? profile.id)}</td><td>${escapeHtml(profile.status ?? "unknown")}</td><td>${escapeHtml(profile.sessionCount ?? "n/a")}</td><td>${escapeHtml(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profile history has been collected yet.</td></tr>';
|
|
5715
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml(title)}</title><style>body{background:#0f1618;color:#f2f7f2;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,.card{background:#162225;border:1px solid #2f4548;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(132,204,22,.1))}.eyebrow{color:#99f6e4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.1rem,6vw,4.3rem);letter-spacing:-.06em;line-height:.94;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #4b6669;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail,.empty,.stale{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2f4548;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call evidence runtime</p><h1>${escapeHtml(title)}</h1><p>Generated ${escapeHtml(report.generatedAt)} from ${escapeHtml(report.source)}.</p><div class="summary"><span class="pill ${escapeHtml(report.status)}">Status ${escapeHtml(report.status)}</span><span class="pill">Stored ${String(report.summary.storedEvidence)}</span><span class="pill">Collected ${String(report.summary.collectedEvidence)}</span><span class="pill">Appended ${String(report.appended)}</span><span class="pill">Duplicates ${String(report.skippedDuplicates)}</span><span class="pill">Sessions ${String(report.summary.sessions)}</span><span class="pill">Profiles ${String(report.summary.profiles)}</span></div></section><section class="card"><h2>Rolling Profile History</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Sessions</th><th>Live p95</th><th>Provider p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Issues</h2><ul>${issueItems}</ul></section></main></body></html>`;
|
|
5711
5716
|
};
|
|
5712
5717
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
5713
5718
|
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
|
@@ -6144,7 +6149,6 @@ var DEFAULT_LINKS2 = [
|
|
|
6144
6149
|
{ href: "/voice/proof-trends", label: "Trend page" },
|
|
6145
6150
|
{ href: "/api/voice/proof-trends", label: "Trend JSON" }
|
|
6146
6151
|
];
|
|
6147
|
-
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6148
6152
|
var formatMs = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
6149
6153
|
var statusLabel = (report) => {
|
|
6150
6154
|
if (!report) {
|
|
@@ -6194,19 +6198,19 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
|
|
|
6194
6198
|
var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
|
|
6195
6199
|
const model = createVoiceProofTrendsViewModel(snapshot, options);
|
|
6196
6200
|
const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
|
|
6197
|
-
<span>${
|
|
6198
|
-
<strong>${
|
|
6199
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ?
|
|
6200
|
-
const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${
|
|
6201
|
-
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${
|
|
6201
|
+
<span>${escapeHtml(metric.label)}</span>
|
|
6202
|
+
<strong>${escapeHtml(metric.value)}</strong>
|
|
6203
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ? escapeHtml(model.error) : "Run the sustained proof trends script to populate evidence."}</p>`;
|
|
6204
|
+
const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</p>` : "";
|
|
6205
|
+
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml(model.status)}">
|
|
6202
6206
|
<header class="absolute-voice-proof-trends__header">
|
|
6203
|
-
<span class="absolute-voice-proof-trends__eyebrow">${
|
|
6204
|
-
<strong class="absolute-voice-proof-trends__label">${
|
|
6207
|
+
<span class="absolute-voice-proof-trends__eyebrow">${escapeHtml(model.title)}</span>
|
|
6208
|
+
<strong class="absolute-voice-proof-trends__label">${escapeHtml(model.label)}</strong>
|
|
6205
6209
|
</header>
|
|
6206
|
-
<p class="absolute-voice-proof-trends__description">${
|
|
6210
|
+
<p class="absolute-voice-proof-trends__description">${escapeHtml(model.description)}</p>
|
|
6207
6211
|
${metrics}
|
|
6208
6212
|
${links}
|
|
6209
|
-
${model.error ? `<p class="absolute-voice-proof-trends__error">${
|
|
6213
|
+
${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml(model.error)}</p>` : ""}
|
|
6210
6214
|
</section>`;
|
|
6211
6215
|
};
|
|
6212
6216
|
var getVoiceProofTrendsCSS = () => `.absolute-voice-proof-trends{border:1px solid #99f6e4;border-radius:20px;background:#f0fdfa;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(13,148,136,.12);font-family:inherit}.absolute-voice-proof-trends--warning,.absolute-voice-proof-trends--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-proof-trends__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-proof-trends__eyebrow{color:#0f766e;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-proof-trends__label{font-size:24px;line-height:1}.absolute-voice-proof-trends__description,.absolute-voice-proof-trends__empty{color:#475569}.absolute-voice-proof-trends__metrics{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));margin-top:14px}.absolute-voice-proof-trends__metrics article{background:#fff;border:1px solid #ccfbf1;border-radius:16px;padding:12px}.absolute-voice-proof-trends__metrics span{color:#64748b;display:block;font-size:12px;font-weight:800;text-transform:uppercase}.absolute-voice-proof-trends__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-proof-trends__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-proof-trends__links a{border:1px solid #99f6e4;border-radius:999px;color:#0f766e;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-proof-trends__error{color:#9f1239;font-weight:700}`;
|
|
@@ -6417,7 +6421,6 @@ var DEFAULT_LINKS3 = [
|
|
|
6417
6421
|
label: "Profile history JSON"
|
|
6418
6422
|
}
|
|
6419
6423
|
];
|
|
6420
|
-
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6421
6424
|
var formatMs2 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
6422
6425
|
var formatCount = (value) => new Intl.NumberFormat("en-US").format(value);
|
|
6423
6426
|
var formatAge = (value) => {
|
|
@@ -6472,21 +6475,21 @@ var createVoiceReconnectProfileEvidenceViewModel = (snapshot, options = {}) => {
|
|
|
6472
6475
|
var renderVoiceReconnectProfileEvidenceHTML = (snapshot, options = {}) => {
|
|
6473
6476
|
const model = createVoiceReconnectProfileEvidenceViewModel(snapshot, options);
|
|
6474
6477
|
const metrics = `<div class="absolute-voice-reconnect-evidence__metrics">${model.metrics.map((metric) => `<article>
|
|
6475
|
-
<span>${
|
|
6476
|
-
<strong>${
|
|
6478
|
+
<span>${escapeHtml(metric.label)}</span>
|
|
6479
|
+
<strong>${escapeHtml(metric.value)}</strong>
|
|
6477
6480
|
</article>`).join("")}</div>`;
|
|
6478
|
-
const latest = model.latest ? `<p class="absolute-voice-reconnect-evidence__latest">Latest ${
|
|
6479
|
-
const links = model.links.length ? `<p class="absolute-voice-reconnect-evidence__links">${model.links.map((link) => `<a href="${
|
|
6480
|
-
return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${
|
|
6481
|
+
const latest = model.latest ? `<p class="absolute-voice-reconnect-evidence__latest">Latest ${escapeHtml(model.latest.profileLabel)} \xB7 ${escapeHtml(model.latest.sessionId)} \xB7 ${escapeHtml(model.latest.surfaces)}</p>` : `<p class="absolute-voice-reconnect-evidence__empty">No persisted reconnect profile evidence yet.</p>`;
|
|
6482
|
+
const links = model.links.length ? `<p class="absolute-voice-reconnect-evidence__links">${model.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</p>` : "";
|
|
6483
|
+
return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${escapeHtml(model.status)}">
|
|
6481
6484
|
<header class="absolute-voice-reconnect-evidence__header">
|
|
6482
|
-
<span class="absolute-voice-reconnect-evidence__eyebrow">${
|
|
6483
|
-
<strong class="absolute-voice-reconnect-evidence__label">${
|
|
6485
|
+
<span class="absolute-voice-reconnect-evidence__eyebrow">${escapeHtml(model.title)}</span>
|
|
6486
|
+
<strong class="absolute-voice-reconnect-evidence__label">${escapeHtml(model.label)}</strong>
|
|
6484
6487
|
</header>
|
|
6485
|
-
<p class="absolute-voice-reconnect-evidence__description">${
|
|
6488
|
+
<p class="absolute-voice-reconnect-evidence__description">${escapeHtml(model.description)}</p>
|
|
6486
6489
|
${metrics}
|
|
6487
6490
|
${latest}
|
|
6488
6491
|
${links}
|
|
6489
|
-
${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${
|
|
6492
|
+
${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${escapeHtml(model.error)}</p>` : ""}
|
|
6490
6493
|
</section>`;
|
|
6491
6494
|
};
|
|
6492
6495
|
var getVoiceReconnectProfileEvidenceCSS = () => `.absolute-voice-reconnect-evidence{border:1px solid #bae6fd;border-radius:20px;background:#f0f9ff;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(14,165,233,.12);font-family:inherit}.absolute-voice-reconnect-evidence--warning,.absolute-voice-reconnect-evidence--error{border-color:#fbbf24;background:#fffbeb}.absolute-voice-reconnect-evidence__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-reconnect-evidence__eyebrow{color:#0369a1;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-reconnect-evidence__label{font-size:24px;line-height:1}.absolute-voice-reconnect-evidence__description,.absolute-voice-reconnect-evidence__empty,.absolute-voice-reconnect-evidence__latest{color:#475569}.absolute-voice-reconnect-evidence__metrics{display:grid;gap:10px;grid-template-columns:repeat(4,minmax(0,1fr));margin-top:14px}.absolute-voice-reconnect-evidence__metrics article{background:#fff;border:1px solid #bae6fd;border-radius:16px;padding:12px}.absolute-voice-reconnect-evidence__metrics span{color:#64748b;display:block;font-size:11px;font-weight:800;text-transform:uppercase}.absolute-voice-reconnect-evidence__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-reconnect-evidence__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-reconnect-evidence__links a{border:1px solid #7dd3fc;border-radius:999px;color:#0369a1;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-reconnect-evidence__error{color:#9f1239;font-weight:700}@media (max-width:720px){.absolute-voice-reconnect-evidence__metrics{grid-template-columns:repeat(2,minmax(0,1fr))}}`;
|
|
@@ -6693,7 +6696,6 @@ var createVoiceCallDebuggerStore = (path, options = {}) => {
|
|
|
6693
6696
|
var DEFAULT_TITLE7 = "Call Debugger";
|
|
6694
6697
|
var DEFAULT_DESCRIPTION7 = "Open the latest call artifact with snapshot, operations record, failure replay, provider path, transcript, and incident markdown.";
|
|
6695
6698
|
var DEFAULT_LINK_LABEL = "Open debugger";
|
|
6696
|
-
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6697
6699
|
var defaultHref = (path, report) => {
|
|
6698
6700
|
if (path.startsWith("/api/voice-call-debugger/")) {
|
|
6699
6701
|
return path.replace("/api/voice-call-debugger/", "/voice-call-debugger/");
|
|
@@ -6746,18 +6748,18 @@ var createVoiceCallDebuggerLaunchViewModel = (path, state, options = {}) => {
|
|
|
6746
6748
|
var renderVoiceCallDebuggerLaunchHTML = (path, state, options = {}) => {
|
|
6747
6749
|
const model = createVoiceCallDebuggerLaunchViewModel(path, state, options);
|
|
6748
6750
|
const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
|
|
6749
|
-
<dt>${
|
|
6750
|
-
<dd>${
|
|
6751
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
6752
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
6751
6753
|
</div>`).join("")}</dl>` : '<p class="absolute-voice-call-debugger-launch__empty">Load a call debugger report to see the latest support artifact.</p>';
|
|
6752
|
-
return `<section class="absolute-voice-call-debugger-launch absolute-voice-call-debugger-launch--${
|
|
6754
|
+
return `<section class="absolute-voice-call-debugger-launch absolute-voice-call-debugger-launch--${escapeHtml(model.status)}">
|
|
6753
6755
|
<header class="absolute-voice-call-debugger-launch__header">
|
|
6754
|
-
<span class="absolute-voice-call-debugger-launch__eyebrow">${
|
|
6755
|
-
<strong class="absolute-voice-call-debugger-launch__label">${
|
|
6756
|
+
<span class="absolute-voice-call-debugger-launch__eyebrow">${escapeHtml(model.title)}</span>
|
|
6757
|
+
<strong class="absolute-voice-call-debugger-launch__label">${escapeHtml(model.label)}</strong>
|
|
6756
6758
|
</header>
|
|
6757
|
-
<p class="absolute-voice-call-debugger-launch__description">${
|
|
6758
|
-
<a class="absolute-voice-call-debugger-launch__link" href="${
|
|
6759
|
+
<p class="absolute-voice-call-debugger-launch__description">${escapeHtml(model.description)}</p>
|
|
6760
|
+
<a class="absolute-voice-call-debugger-launch__link" href="${escapeHtml(model.href)}">${escapeHtml(options.linkLabel ?? DEFAULT_LINK_LABEL)}</a>
|
|
6759
6761
|
${rows}
|
|
6760
|
-
${model.error ? `<p class="absolute-voice-call-debugger-launch__error">${
|
|
6762
|
+
${model.error ? `<p class="absolute-voice-call-debugger-launch__error">${escapeHtml(model.error)}</p>` : ""}
|
|
6761
6763
|
</section>`;
|
|
6762
6764
|
};
|
|
6763
6765
|
var mountVoiceCallDebuggerLaunch = (element, path, options = {}) => {
|
|
@@ -6982,7 +6984,6 @@ var createVoiceSessionSnapshotStore = (path, options = {}) => {
|
|
|
6982
6984
|
var DEFAULT_TITLE8 = "Session Snapshot";
|
|
6983
6985
|
var DEFAULT_DESCRIPTION8 = "Portable call artifact with media graph, provider routing, proof, quality, and telephony evidence.";
|
|
6984
6986
|
var DEFAULT_DOWNLOAD_LABEL = "Download snapshot";
|
|
6985
|
-
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6986
6987
|
var formatStatus2 = (status) => status ?? "n/a";
|
|
6987
6988
|
var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
6988
6989
|
const snapshot = state.snapshot;
|
|
@@ -7032,23 +7033,23 @@ var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
|
7032
7033
|
var renderVoiceSessionSnapshotHTML = (state, options = {}) => {
|
|
7033
7034
|
const model = createVoiceSessionSnapshotViewModel(state, options);
|
|
7034
7035
|
const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
|
|
7035
|
-
<dt>${
|
|
7036
|
-
<dd>${
|
|
7036
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
7037
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
7037
7038
|
</div>`).join("")}</dl>` : '<p class="absolute-voice-session-snapshot__empty">Load a session snapshot to see support diagnostics.</p>';
|
|
7038
7039
|
const artifacts = model.artifacts.length ? `<div class="absolute-voice-session-snapshot__artifacts">${model.artifacts.map((artifact) => {
|
|
7039
|
-
const body = `<strong>${
|
|
7040
|
-
return artifact.href ? `<a href="${
|
|
7040
|
+
const body = `<strong>${escapeHtml(artifact.label)}</strong><span>${escapeHtml(artifact.status)}</span>`;
|
|
7041
|
+
return artifact.href ? `<a href="${escapeHtml(artifact.href)}">${body}</a>` : `<div>${body}</div>`;
|
|
7041
7042
|
}).join("")}</div>` : "";
|
|
7042
|
-
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${
|
|
7043
|
+
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${escapeHtml(model.status)}">
|
|
7043
7044
|
<header class="absolute-voice-session-snapshot__header">
|
|
7044
|
-
<span class="absolute-voice-session-snapshot__eyebrow">${
|
|
7045
|
-
<strong class="absolute-voice-session-snapshot__label">${
|
|
7045
|
+
<span class="absolute-voice-session-snapshot__eyebrow">${escapeHtml(model.title)}</span>
|
|
7046
|
+
<strong class="absolute-voice-session-snapshot__label">${escapeHtml(model.label)}</strong>
|
|
7046
7047
|
</header>
|
|
7047
|
-
<p class="absolute-voice-session-snapshot__description">${
|
|
7048
|
-
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${
|
|
7048
|
+
<p class="absolute-voice-session-snapshot__description">${escapeHtml(model.description)}</p>
|
|
7049
|
+
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${escapeHtml(options.downloadLabel ?? DEFAULT_DOWNLOAD_LABEL)}</button>` : ""}
|
|
7049
7050
|
${rows}
|
|
7050
7051
|
${artifacts}
|
|
7051
|
-
${model.error ? `<p class="absolute-voice-session-snapshot__error">${
|
|
7052
|
+
${model.error ? `<p class="absolute-voice-session-snapshot__error">${escapeHtml(model.error)}</p>` : ""}
|
|
7052
7053
|
</section>`;
|
|
7053
7054
|
};
|
|
7054
7055
|
var downloadBlob = (blob, filename) => {
|
|
@@ -7281,7 +7282,6 @@ var createVoiceSessionObservabilityStore = (path, options = {}) => {
|
|
|
7281
7282
|
// src/client/sessionObservabilityWidget.ts
|
|
7282
7283
|
var DEFAULT_TITLE9 = "Session Observability";
|
|
7283
7284
|
var DEFAULT_DESCRIPTION9 = "One support/debug report for a voice call across traces, provider recovery, tools, handoffs, guardrails, turn waterfalls, and incident handoff.";
|
|
7284
|
-
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7285
7285
|
var formatMs3 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
7286
7286
|
var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
|
|
7287
7287
|
const report = snapshot.report;
|
|
@@ -7303,20 +7303,20 @@ var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
|
|
|
7303
7303
|
updatedAt: snapshot.updatedAt
|
|
7304
7304
|
};
|
|
7305
7305
|
};
|
|
7306
|
-
var renderLinks = (links) => links.length ? `<p class="absolute-voice-session-observability__actions">${links.map((link) => `<a href="${
|
|
7306
|
+
var renderLinks = (links) => links.length ? `<p class="absolute-voice-session-observability__actions">${links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</p>` : "";
|
|
7307
7307
|
var renderVoiceSessionObservabilityHTML = (snapshot, options = {}) => {
|
|
7308
7308
|
const model = createVoiceSessionObservabilityViewModel(snapshot, options);
|
|
7309
|
-
const turns = model.turns.length ? `<div class="absolute-voice-session-observability__turns">${model.turns.map((turn) => `<article class="absolute-voice-session-observability__turn"><header><strong>${
|
|
7310
|
-
return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${
|
|
7309
|
+
const turns = model.turns.length ? `<div class="absolute-voice-session-observability__turns">${model.turns.map((turn) => `<article class="absolute-voice-session-observability__turn"><header><strong>${escapeHtml(turn.turnId)}</strong><span>${escapeHtml(turn.durationLabel)}</span></header><p>${escapeHtml(turn.label)}</p></article>`).join("")}</div>` : '<p class="absolute-voice-session-observability__empty">Open a voice session to see turn waterfalls.</p>';
|
|
7310
|
+
return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${escapeHtml(model.status)}">
|
|
7311
7311
|
<header class="absolute-voice-session-observability__header">
|
|
7312
|
-
<span class="absolute-voice-session-observability__eyebrow">${
|
|
7313
|
-
<strong class="absolute-voice-session-observability__label">${
|
|
7312
|
+
<span class="absolute-voice-session-observability__eyebrow">${escapeHtml(model.title)}</span>
|
|
7313
|
+
<strong class="absolute-voice-session-observability__label">${escapeHtml(model.label)}</strong>
|
|
7314
7314
|
</header>
|
|
7315
|
-
<p class="absolute-voice-session-observability__description">${
|
|
7316
|
-
${model.sessionId ? `<p class="absolute-voice-session-observability__session">${
|
|
7315
|
+
<p class="absolute-voice-session-observability__description">${escapeHtml(model.description)}</p>
|
|
7316
|
+
${model.sessionId ? `<p class="absolute-voice-session-observability__session">${escapeHtml(model.sessionId)}</p>` : ""}
|
|
7317
7317
|
${renderLinks(model.links)}
|
|
7318
7318
|
${turns}
|
|
7319
|
-
${model.error ? `<p class="absolute-voice-session-observability__error">${
|
|
7319
|
+
${model.error ? `<p class="absolute-voice-session-observability__error">${escapeHtml(model.error)}</p>` : ""}
|
|
7320
7320
|
</section>`;
|
|
7321
7321
|
};
|
|
7322
7322
|
var getVoiceSessionObservabilityCSS = () => `.absolute-voice-session-observability{border:1px solid #c8d9bf;border-radius:20px;background:#fbfff3;color:#18220d;padding:18px;box-shadow:0 18px 40px rgba(24,34,13,.12);font-family:inherit}.absolute-voice-session-observability--error,.absolute-voice-session-observability--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-session-observability--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-session-observability__header,.absolute-voice-session-observability__turn header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-session-observability__eyebrow{color:#4d7c0f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-session-observability__label{font-size:24px;line-height:1}.absolute-voice-session-observability__description,.absolute-voice-session-observability__turn p,.absolute-voice-session-observability__empty,.absolute-voice-session-observability__session{color:#4b5f3e}.absolute-voice-session-observability__actions{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0}.absolute-voice-session-observability__actions a{color:#3f6212;font-weight:800}.absolute-voice-session-observability__turns{display:grid;gap:12px;margin-top:14px}.absolute-voice-session-observability__turn{background:#fff;border:1px solid #dcebcf;border-radius:16px;padding:14px}.absolute-voice-session-observability__turn p{margin:10px 0 0}.absolute-voice-session-observability__empty{margin:14px 0 0}.absolute-voice-session-observability__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7498,7 +7498,6 @@ var DEFAULT_LINKS4 = [
|
|
|
7498
7498
|
{ href: "/production-readiness", label: "Readiness page" },
|
|
7499
7499
|
{ href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
|
|
7500
7500
|
];
|
|
7501
|
-
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7502
7501
|
var formatExplanationValue = (value, unit) => {
|
|
7503
7502
|
if (value === undefined || value === null) {
|
|
7504
7503
|
return "n/a";
|
|
@@ -7539,23 +7538,23 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
|
|
|
7539
7538
|
};
|
|
7540
7539
|
var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
|
|
7541
7540
|
const model = createVoiceReadinessFailuresViewModel(snapshot, options);
|
|
7542
|
-
const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${
|
|
7543
|
-
<span>${
|
|
7544
|
-
<strong>${
|
|
7545
|
-
<p>Observed ${
|
|
7546
|
-
<p>${
|
|
7547
|
-
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${
|
|
7548
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ?
|
|
7549
|
-
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${
|
|
7550
|
-
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${
|
|
7541
|
+
const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml(failure.status)}">
|
|
7542
|
+
<span>${escapeHtml(failure.status.toUpperCase())}</span>
|
|
7543
|
+
<strong>${escapeHtml(failure.label)}</strong>
|
|
7544
|
+
<p>Observed ${escapeHtml(failure.observed)} against ${escapeHtml(failure.thresholdLabel)} ${escapeHtml(failure.threshold)}.</p>
|
|
7545
|
+
<p>${escapeHtml(failure.remediation)}</p>
|
|
7546
|
+
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml(failure.sourceHref)}">Threshold source</a>` : ""}</p>
|
|
7547
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
|
|
7548
|
+
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</p>` : "";
|
|
7549
|
+
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml(model.status)}">
|
|
7551
7550
|
<header class="absolute-voice-readiness-failures__header">
|
|
7552
|
-
<span class="absolute-voice-readiness-failures__eyebrow">${
|
|
7553
|
-
<strong class="absolute-voice-readiness-failures__label">${
|
|
7551
|
+
<span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml(model.title)}</span>
|
|
7552
|
+
<strong class="absolute-voice-readiness-failures__label">${escapeHtml(model.label)}</strong>
|
|
7554
7553
|
</header>
|
|
7555
|
-
<p class="absolute-voice-readiness-failures__description">${
|
|
7554
|
+
<p class="absolute-voice-readiness-failures__description">${escapeHtml(model.description)}</p>
|
|
7556
7555
|
${failures}
|
|
7557
7556
|
${links}
|
|
7558
|
-
${model.error ? `<p class="absolute-voice-readiness-failures__error">${
|
|
7557
|
+
${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml(model.error)}</p>` : ""}
|
|
7559
7558
|
</section>`;
|
|
7560
7559
|
};
|
|
7561
7560
|
var getVoiceReadinessFailuresCSS = () => `.absolute-voice-readiness-failures{border:1px solid #fed7aa;border-radius:20px;background:#fff7ed;color:#1c1917;padding:18px;box-shadow:0 18px 40px rgba(234,88,12,.12);font-family:inherit}.absolute-voice-readiness-failures--ready{border-color:#86efac;background:#f0fdf4}.absolute-voice-readiness-failures--error{border-color:#fda4af;background:#fff1f2}.absolute-voice-readiness-failures__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-readiness-failures__eyebrow{color:#9a3412;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-readiness-failures__label{font-size:24px;line-height:1}.absolute-voice-readiness-failures__description,.absolute-voice-readiness-failures__empty{color:#57534e}.absolute-voice-readiness-failures__items{display:grid;gap:10px;margin-top:14px}.absolute-voice-readiness-failures__item{background:white;border:1px solid #fed7aa;border-radius:16px;padding:12px}.absolute-voice-readiness-failures__item--fail{border-color:#fb7185}.absolute-voice-readiness-failures__item span{color:#9a3412;display:block;font-size:12px;font-weight:900;text-transform:uppercase}.absolute-voice-readiness-failures__item strong{display:block;font-size:18px;margin-top:4px}.absolute-voice-readiness-failures__item p{margin:.45rem 0 0}.absolute-voice-readiness-failures__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-readiness-failures__links a{border:1px solid #fdba74;border-radius:999px;color:#9a3412;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-readiness-failures__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7772,7 +7771,6 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
7772
7771
|
};
|
|
7773
7772
|
|
|
7774
7773
|
// src/client/providerSimulationControlsWidget.ts
|
|
7775
|
-
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7776
7774
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
7777
7775
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
7778
7776
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -7792,18 +7790,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
7792
7790
|
};
|
|
7793
7791
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
7794
7792
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
7795
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
7796
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
7793
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml(provider.provider)} ${escapeHtml(formatKind(options.kind))} failure</button>`).join("");
|
|
7794
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml(provider.provider)} recovered</button>`).join("");
|
|
7797
7795
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
7798
7796
|
<header class="absolute-voice-provider-simulation__header">
|
|
7799
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
7800
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
7797
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml(model.title)}</span>
|
|
7798
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml(model.label)}</strong>
|
|
7801
7799
|
</header>
|
|
7802
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
7803
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
7800
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml(model.description)}</p>
|
|
7801
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
7804
7802
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
7805
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
7806
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
7803
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml(snapshot.error)}</p>` : ""}
|
|
7804
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml(model.resultText)}</pre>` : ""}
|
|
7807
7805
|
</section>`;
|
|
7808
7806
|
};
|
|
7809
7807
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -8064,7 +8062,6 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
|
|
|
8064
8062
|
// src/client/providerCapabilitiesWidget.ts
|
|
8065
8063
|
var DEFAULT_TITLE11 = "Provider Capabilities";
|
|
8066
8064
|
var DEFAULT_DESCRIPTION11 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
8067
|
-
var escapeHtml17 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8068
8065
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
8069
8066
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
8070
8067
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -8119,25 +8116,25 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
8119
8116
|
};
|
|
8120
8117
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
8121
8118
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
8122
|
-
const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${
|
|
8119
|
+
const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${escapeHtml(capability.status)}">
|
|
8123
8120
|
<header>
|
|
8124
|
-
<strong>${
|
|
8125
|
-
<span>${
|
|
8121
|
+
<strong>${escapeHtml(capability.label)}</strong>
|
|
8122
|
+
<span>${escapeHtml(formatStatus3(capability.status))}</span>
|
|
8126
8123
|
</header>
|
|
8127
|
-
<p>${
|
|
8124
|
+
<p>${escapeHtml(capability.detail)}</p>
|
|
8128
8125
|
<dl>${capability.rows.map((row) => `<div>
|
|
8129
|
-
<dt>${
|
|
8130
|
-
<dd>${
|
|
8126
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
8127
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
8131
8128
|
</div>`).join("")}</dl>
|
|
8132
8129
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
8133
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
8130
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml(model.status)}">
|
|
8134
8131
|
<header class="absolute-voice-provider-capabilities__header">
|
|
8135
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
8136
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
8132
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml(model.title)}</span>
|
|
8133
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml(model.label)}</strong>
|
|
8137
8134
|
</header>
|
|
8138
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
8135
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml(model.description)}</p>
|
|
8139
8136
|
${capabilities}
|
|
8140
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
8137
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8141
8138
|
</section>`;
|
|
8142
8139
|
};
|
|
8143
8140
|
var getVoiceProviderCapabilitiesCSS = () => `.absolute-voice-provider-capabilities{border:1px solid #bfd7ea;border-radius:20px;background:#f6fbff;color:#08131f;padding:18px;box-shadow:0 18px 40px rgba(14,51,78,.12);font-family:inherit}.absolute-voice-provider-capabilities--error,.absolute-voice-provider-capabilities--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-provider-capabilities__header,.absolute-voice-provider-capabilities__provider header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-capabilities__eyebrow{color:#255f85;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-capabilities__label{font-size:24px;line-height:1}.absolute-voice-provider-capabilities__description,.absolute-voice-provider-capabilities__provider p,.absolute-voice-provider-capabilities__provider dt,.absolute-voice-provider-capabilities__empty{color:#405467}.absolute-voice-provider-capabilities__providers{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-capabilities__provider{background:#fff;border:1px solid #d7e7f3;border-radius:16px;padding:14px}.absolute-voice-provider-capabilities__provider--selected,.absolute-voice-provider-capabilities__provider--healthy{border-color:#86efac}.absolute-voice-provider-capabilities__provider--degraded,.absolute-voice-provider-capabilities__provider--rate-limited,.absolute-voice-provider-capabilities__provider--suppressed,.absolute-voice-provider-capabilities__provider--unconfigured{border-color:#f2a7a7}.absolute-voice-provider-capabilities__provider p{margin:10px 0}.absolute-voice-provider-capabilities__provider dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-capabilities__provider div{background:#f6fbff;border:1px solid #d7e7f3;border-radius:12px;padding:8px}.absolute-voice-provider-capabilities__provider dt{font-size:12px}.absolute-voice-provider-capabilities__provider dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-capabilities__empty{margin:14px 0 0}.absolute-voice-provider-capabilities__error{color:#9f1239;font-weight:700}`;
|
|
@@ -8394,7 +8391,6 @@ function useVoiceProviderContracts(path = "/api/provider-contracts", options = {
|
|
|
8394
8391
|
// src/client/providerContractsWidget.ts
|
|
8395
8392
|
var DEFAULT_TITLE12 = "Provider Contracts";
|
|
8396
8393
|
var DEFAULT_DESCRIPTION12 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
8397
|
-
var escapeHtml18 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8398
8394
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
8399
8395
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
8400
8396
|
var contractDetail = (row) => {
|
|
@@ -8438,26 +8434,26 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
8438
8434
|
};
|
|
8439
8435
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
8440
8436
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
8441
|
-
const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${
|
|
8437
|
+
const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${escapeHtml(row.status)}">
|
|
8442
8438
|
<header>
|
|
8443
|
-
<strong>${
|
|
8444
|
-
<span>${
|
|
8439
|
+
<strong>${escapeHtml(row.label)}</strong>
|
|
8440
|
+
<span>${escapeHtml(formatStatus4(row.status))}</span>
|
|
8445
8441
|
</header>
|
|
8446
|
-
<p>${
|
|
8447
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
8442
|
+
<p>${escapeHtml(row.detail)}</p>
|
|
8443
|
+
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml(remediation.href)}">${escapeHtml(remediation.label)}</a>` : `<strong>${escapeHtml(remediation.label)}</strong>`}<span>${escapeHtml(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
|
|
8448
8444
|
<dl>${row.rows.map((item) => `<div>
|
|
8449
|
-
<dt>${
|
|
8450
|
-
<dd>${
|
|
8445
|
+
<dt>${escapeHtml(item.label)}</dt>
|
|
8446
|
+
<dd>${escapeHtml(item.value)}</dd>
|
|
8451
8447
|
</div>`).join("")}</dl>
|
|
8452
8448
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
8453
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
8449
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml(model.status)}">
|
|
8454
8450
|
<header class="absolute-voice-provider-contracts__header">
|
|
8455
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
8456
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
8451
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml(model.title)}</span>
|
|
8452
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml(model.label)}</strong>
|
|
8457
8453
|
</header>
|
|
8458
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
8454
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml(model.description)}</p>
|
|
8459
8455
|
${rows}
|
|
8460
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
8456
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8461
8457
|
</section>`;
|
|
8462
8458
|
};
|
|
8463
8459
|
var getVoiceProviderContractsCSS = () => `.absolute-voice-provider-contracts{border:1px solid #b8dcc7;border-radius:20px;background:#f7fff9;color:#09140d;padding:18px;box-shadow:0 18px 40px rgba(21,83,45,.12);font-family:inherit}.absolute-voice-provider-contracts--error,.absolute-voice-provider-contracts--warning{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-provider-contracts__header,.absolute-voice-provider-contracts__row header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-contracts__eyebrow{color:#166534;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-contracts__label{font-size:24px;line-height:1}.absolute-voice-provider-contracts__description,.absolute-voice-provider-contracts__row p,.absolute-voice-provider-contracts__row dt,.absolute-voice-provider-contracts__empty{color:#405448}.absolute-voice-provider-contracts__rows{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-contracts__row{background:#fff;border:1px solid #d6eadb;border-radius:16px;padding:14px}.absolute-voice-provider-contracts__row--pass{border-color:#86efac}.absolute-voice-provider-contracts__row--warn,.absolute-voice-provider-contracts__row--fail{border-color:#f2a7a7}.absolute-voice-provider-contracts__row p{margin:10px 0}.absolute-voice-provider-contracts__remediations{display:grid;gap:8px;list-style:none;margin:0 0 10px;padding:0}.absolute-voice-provider-contracts__remediations li{background:#fff7ed;border:1px solid #fed7aa;border-radius:12px;display:grid;gap:3px;padding:8px}.absolute-voice-provider-contracts__remediations a,.absolute-voice-provider-contracts__remediations strong{color:#9a3412}.absolute-voice-provider-contracts__remediations span{color:#7c2d12}.absolute-voice-provider-contracts__row dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-contracts__row div{background:#f7fff9;border:1px solid #d6eadb;border-radius:12px;padding:8px}.absolute-voice-provider-contracts__row dt{font-size:12px}.absolute-voice-provider-contracts__row dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-contracts__error{color:#9f1239;font-weight:700}`;
|
|
@@ -8654,7 +8650,6 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
8654
8650
|
// src/client/providerStatusWidget.ts
|
|
8655
8651
|
var DEFAULT_TITLE13 = "Voice Providers";
|
|
8656
8652
|
var DEFAULT_DESCRIPTION13 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
8657
|
-
var escapeHtml19 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8658
8653
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
8659
8654
|
var formatStatus5 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
8660
8655
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -8710,25 +8705,25 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
8710
8705
|
};
|
|
8711
8706
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
8712
8707
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
8713
|
-
const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${
|
|
8708
|
+
const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${escapeHtml(provider.status)}">
|
|
8714
8709
|
<header>
|
|
8715
|
-
<strong>${
|
|
8716
|
-
<span>${
|
|
8710
|
+
<strong>${escapeHtml(provider.label)}</strong>
|
|
8711
|
+
<span>${escapeHtml(formatStatus5(provider.status))}</span>
|
|
8717
8712
|
</header>
|
|
8718
|
-
<p>${
|
|
8713
|
+
<p>${escapeHtml(provider.detail)}</p>
|
|
8719
8714
|
<dl>${provider.rows.map((row) => `<div>
|
|
8720
|
-
<dt>${
|
|
8721
|
-
<dd>${
|
|
8715
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
8716
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
8722
8717
|
</div>`).join("")}</dl>
|
|
8723
8718
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
8724
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
8719
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml(model.status)}">
|
|
8725
8720
|
<header class="absolute-voice-provider-status__header">
|
|
8726
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
8727
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
8721
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
8722
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml(model.label)}</strong>
|
|
8728
8723
|
</header>
|
|
8729
|
-
<p class="absolute-voice-provider-status__description">${
|
|
8724
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml(model.description)}</p>
|
|
8730
8725
|
${providers}
|
|
8731
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
8726
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8732
8727
|
</section>`;
|
|
8733
8728
|
};
|
|
8734
8729
|
var getVoiceProviderStatusCSS = () => `.absolute-voice-provider-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-provider-status--error,.absolute-voice-provider-status--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-provider-status__header,.absolute-voice-provider-status__provider header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-status__label{font-size:24px;line-height:1}.absolute-voice-provider-status__description,.absolute-voice-provider-status__provider p,.absolute-voice-provider-status__provider dt,.absolute-voice-provider-status__empty{color:#514733}.absolute-voice-provider-status__providers{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-status__provider{background:#fff;border:1px solid #eee4d2;border-radius:16px;padding:14px}.absolute-voice-provider-status__provider--degraded,.absolute-voice-provider-status__provider--rate-limited,.absolute-voice-provider-status__provider--suppressed{border-color:#f2a7a7}.absolute-voice-provider-status__provider--recoverable{border-color:#fbbf24}.absolute-voice-provider-status__provider p{margin:10px 0}.absolute-voice-provider-status__provider dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-status__provider div{background:#fffaf0;border:1px solid #eee4d2;border-radius:12px;padding:8px}.absolute-voice-provider-status__provider dt{font-size:12px}.absolute-voice-provider-status__provider dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-status__empty{margin:14px 0 0}.absolute-voice-provider-status__error{color:#9f1239;font-weight:700}`;
|
|
@@ -8957,7 +8952,6 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
8957
8952
|
// src/client/routingStatusWidget.ts
|
|
8958
8953
|
var DEFAULT_TITLE14 = "Voice Routing";
|
|
8959
8954
|
var DEFAULT_DESCRIPTION14 = "Latest provider routing decision from the self-hosted trace store.";
|
|
8960
|
-
var escapeHtml20 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8961
8955
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
8962
8956
|
var formatProviderRoutes = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
|
|
8963
8957
|
var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
|
|
@@ -9039,22 +9033,22 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
9039
9033
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
9040
9034
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
9041
9035
|
const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
|
|
9042
|
-
<span>${
|
|
9043
|
-
<strong>${
|
|
9036
|
+
<span>${escapeHtml(item.label)}</span>
|
|
9037
|
+
<strong>${escapeHtml(item.value)}</strong>
|
|
9044
9038
|
</div>`).join("")}</div>` : "";
|
|
9045
9039
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
9046
|
-
<span>${
|
|
9047
|
-
<strong>${
|
|
9040
|
+
<span>${escapeHtml(row.label)}</span>
|
|
9041
|
+
<strong>${escapeHtml(row.value)}</strong>
|
|
9048
9042
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
9049
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
9043
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml(model.status)}">
|
|
9050
9044
|
<header class="absolute-voice-routing-status__header">
|
|
9051
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
9052
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
9045
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
9046
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml(model.label)}</strong>
|
|
9053
9047
|
</header>
|
|
9054
|
-
<p class="absolute-voice-routing-status__description">${
|
|
9048
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml(model.description)}</p>
|
|
9055
9049
|
${activeStack}
|
|
9056
9050
|
${rows}
|
|
9057
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
9051
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9058
9052
|
</section>`;
|
|
9059
9053
|
};
|
|
9060
9054
|
var getVoiceRoutingStatusCSS = () => `.absolute-voice-routing-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-routing-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-routing-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-routing-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-routing-status__label{font-size:24px;line-height:1}.absolute-voice-routing-status__description{color:#514733;margin:12px 0 0}.absolute-voice-routing-status__stack{background:linear-gradient(135deg,#16130d,#49391f);border-radius:18px;color:#fff;display:grid;gap:8px;grid-template-columns:repeat(5,minmax(0,1fr));margin-top:14px;padding:12px}.absolute-voice-routing-status__stack div{border-left:1px solid rgba(255,255,255,.18);padding-left:10px}.absolute-voice-routing-status__stack div:first-child{border-left:0;padding-left:0}.absolute-voice-routing-status__stack span{color:#e9d9b8;display:block;font-size:11px;font-weight:800;letter-spacing:.08em;margin-bottom:5px;text-transform:uppercase}.absolute-voice-routing-status__stack strong{display:block;font-size:13px;line-height:1.25;overflow-wrap:anywhere}.absolute-voice-routing-status__grid{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:14px}.absolute-voice-routing-status__grid div{background:#fff;border:1px solid #eee4d2;border-radius:14px;padding:10px 12px}.absolute-voice-routing-status__grid span{color:#655944;display:block;font-size:12px;margin-bottom:4px}.absolute-voice-routing-status__grid strong{overflow-wrap:anywhere}.absolute-voice-routing-status__empty{color:#655944;margin:14px 0 0}.absolute-voice-routing-status__error{color:#9f1239;font-weight:700}@media (max-width:760px){.absolute-voice-routing-status__stack{grid-template-columns:repeat(2,minmax(0,1fr))}.absolute-voice-routing-status__stack div{border-left:0;border-top:1px solid rgba(255,255,255,.18);padding-left:0;padding-top:8px}.absolute-voice-routing-status__stack div:first-child{border-top:0;padding-top:0}}`;
|
|
@@ -9485,7 +9479,6 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
|
|
|
9485
9479
|
var DEFAULT_TITLE15 = "Turn Latency";
|
|
9486
9480
|
var DEFAULT_DESCRIPTION15 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
9487
9481
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
9488
|
-
var escapeHtml21 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9489
9482
|
var formatMs4 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
9490
9483
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
9491
9484
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -9513,25 +9506,25 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
9513
9506
|
};
|
|
9514
9507
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
9515
9508
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
9516
|
-
const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${
|
|
9509
|
+
const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml(turn.status)}">
|
|
9517
9510
|
<header>
|
|
9518
|
-
<strong>${
|
|
9519
|
-
<span>${
|
|
9511
|
+
<strong>${escapeHtml(turn.label)}</strong>
|
|
9512
|
+
<span>${escapeHtml(turn.status)}</span>
|
|
9520
9513
|
</header>
|
|
9521
9514
|
<dl>${turn.rows.map((row) => `<div>
|
|
9522
|
-
<dt>${
|
|
9523
|
-
<dd>${
|
|
9515
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
9516
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
9524
9517
|
</div>`).join("")}</dl>
|
|
9525
9518
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
9526
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
9519
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml(model.status)}">
|
|
9527
9520
|
<header class="absolute-voice-turn-latency__header">
|
|
9528
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
9529
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
9521
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml(model.title)}</span>
|
|
9522
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml(model.label)}</strong>
|
|
9530
9523
|
</header>
|
|
9531
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
9532
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
9524
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml(model.description)}</p>
|
|
9525
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
9533
9526
|
${turns}
|
|
9534
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
9527
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9535
9528
|
</section>`;
|
|
9536
9529
|
};
|
|
9537
9530
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -9764,7 +9757,6 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
9764
9757
|
// src/client/turnQualityWidget.ts
|
|
9765
9758
|
var DEFAULT_TITLE16 = "Turn Quality";
|
|
9766
9759
|
var DEFAULT_DESCRIPTION16 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
9767
|
-
var escapeHtml22 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9768
9760
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
9769
9761
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
9770
9762
|
var getTurnDetail = (turn) => {
|
|
@@ -9820,25 +9812,25 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
9820
9812
|
};
|
|
9821
9813
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
9822
9814
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
9823
|
-
const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${
|
|
9815
|
+
const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${escapeHtml(turn.status)}">
|
|
9824
9816
|
<header>
|
|
9825
|
-
<strong>${
|
|
9826
|
-
<span>${
|
|
9817
|
+
<strong>${escapeHtml(turn.label)}</strong>
|
|
9818
|
+
<span>${escapeHtml(turn.status)}</span>
|
|
9827
9819
|
</header>
|
|
9828
|
-
<p>${
|
|
9820
|
+
<p>${escapeHtml(turn.detail)}</p>
|
|
9829
9821
|
<dl>${turn.rows.map((row) => `<div>
|
|
9830
|
-
<dt>${
|
|
9831
|
-
<dd>${
|
|
9822
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
9823
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
9832
9824
|
</div>`).join("")}</dl>
|
|
9833
9825
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
9834
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
9826
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml(model.status)}">
|
|
9835
9827
|
<header class="absolute-voice-turn-quality__header">
|
|
9836
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
9837
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
9828
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml(model.title)}</span>
|
|
9829
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml(model.label)}</strong>
|
|
9838
9830
|
</header>
|
|
9839
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
9831
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml(model.description)}</p>
|
|
9840
9832
|
${turns}
|
|
9841
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
9833
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9842
9834
|
</section>`;
|
|
9843
9835
|
};
|
|
9844
9836
|
var getVoiceTurnQualityCSS = () => `.absolute-voice-turn-quality{border:1px solid #e4d1a3;border-radius:20px;background:#fff9eb;color:#17120a;padding:18px;box-shadow:0 18px 40px rgba(73,48,14,.12);font-family:inherit}.absolute-voice-turn-quality--error,.absolute-voice-turn-quality--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-turn-quality__header,.absolute-voice-turn-quality__turn header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-turn-quality__eyebrow{color:#8a5a0a;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-turn-quality__label{font-size:24px;line-height:1}.absolute-voice-turn-quality__description,.absolute-voice-turn-quality__turn p,.absolute-voice-turn-quality__turn dt,.absolute-voice-turn-quality__empty{color:#5a4930}.absolute-voice-turn-quality__turns{display:grid;gap:12px;margin-top:14px}.absolute-voice-turn-quality__turn{background:#fff;border:1px solid #f0dfba;border-radius:16px;padding:14px}.absolute-voice-turn-quality__turn--pass{border-color:#86efac}.absolute-voice-turn-quality__turn--warn,.absolute-voice-turn-quality__turn--unknown{border-color:#fbbf24}.absolute-voice-turn-quality__turn--fail{border-color:#f2a7a7}.absolute-voice-turn-quality__turn p{margin:10px 0}.absolute-voice-turn-quality__turn dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-turn-quality__turn div{background:#fff9eb;border:1px solid #f0dfba;border-radius:12px;padding:8px}.absolute-voice-turn-quality__turn dt{font-size:12px}.absolute-voice-turn-quality__turn dd{font-weight:800;margin:4px 0 0}.absolute-voice-turn-quality__empty{margin:14px 0 0}.absolute-voice-turn-quality__error{color:#9f1239;font-weight:700}`;
|