@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/react/index.js
CHANGED
|
@@ -182,6 +182,9 @@ var useVoiceOpsStatus = (path = "/api/voice/ops-status", options = {}) => {
|
|
|
182
182
|
};
|
|
183
183
|
};
|
|
184
184
|
|
|
185
|
+
// src/internal/html.ts
|
|
186
|
+
var escapeHtml = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
187
|
+
|
|
185
188
|
// src/client/opsStatusWidget.ts
|
|
186
189
|
var DEFAULT_TITLE = "Voice Ops Status";
|
|
187
190
|
var DEFAULT_DESCRIPTION = "Certified workflow, provider, and handoff readiness from your AbsoluteJS voice app.";
|
|
@@ -192,7 +195,6 @@ var SURFACE_LABELS = {
|
|
|
192
195
|
sessions: "Sessions",
|
|
193
196
|
workflows: "Workflows"
|
|
194
197
|
};
|
|
195
|
-
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
196
198
|
var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
|
|
197
199
|
var surfaceDetail = (surface) => {
|
|
198
200
|
const total = readNumber(surface, "total");
|
|
@@ -595,7 +597,6 @@ var createVoiceOpsActionCenterStore = (options = {}) => {
|
|
|
595
597
|
// src/client/opsActionCenterWidget.ts
|
|
596
598
|
var DEFAULT_TITLE2 = "Voice Ops Action Center";
|
|
597
599
|
var DEFAULT_DESCRIPTION2 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
598
|
-
var escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
599
600
|
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
600
601
|
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
601
602
|
return {
|
|
@@ -617,18 +618,18 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
|
617
618
|
};
|
|
618
619
|
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
619
620
|
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
620
|
-
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${
|
|
621
|
-
${
|
|
621
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
622
|
+
${escapeHtml(action.isRunning ? "Working..." : action.label)}
|
|
622
623
|
</button>`).join("");
|
|
623
|
-
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${
|
|
624
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml(model.status)}">
|
|
624
625
|
<header class="absolute-voice-ops-action-center__header">
|
|
625
|
-
<span class="absolute-voice-ops-action-center__eyebrow">${
|
|
626
|
-
<strong class="absolute-voice-ops-action-center__label">${
|
|
626
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml(model.title)}</span>
|
|
627
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml(model.label)}</strong>
|
|
627
628
|
</header>
|
|
628
|
-
<p class="absolute-voice-ops-action-center__description">${
|
|
629
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml(model.description)}</p>
|
|
629
630
|
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
630
|
-
<p class="absolute-voice-ops-action-center__result">${
|
|
631
|
-
${model.error ? `<p class="absolute-voice-ops-action-center__error">${
|
|
631
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml(model.lastResultLabel)}</p>
|
|
632
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml(model.error)}</p>` : ""}
|
|
632
633
|
</section>`;
|
|
633
634
|
};
|
|
634
635
|
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}`;
|
|
@@ -890,7 +891,6 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
890
891
|
// src/client/deliveryRuntimeWidget.ts
|
|
891
892
|
var DEFAULT_TITLE3 = "Voice Delivery Runtime";
|
|
892
893
|
var DEFAULT_DESCRIPTION3 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
893
|
-
var escapeHtml3 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
894
894
|
var createSurface = (id, summary) => {
|
|
895
895
|
if (!summary) {
|
|
896
896
|
return {
|
|
@@ -939,26 +939,26 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
939
939
|
};
|
|
940
940
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
941
941
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
942
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
943
|
-
<span>${
|
|
944
|
-
<strong>${
|
|
942
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml(surface.status)}">
|
|
943
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
944
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
945
945
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
946
946
|
</li>`).join("");
|
|
947
947
|
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
948
948
|
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
949
949
|
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
950
950
|
</div>`;
|
|
951
|
-
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
952
|
-
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${
|
|
951
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml(model.actionError)}</p>` : "";
|
|
952
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml(model.status)}">
|
|
953
953
|
<header class="absolute-voice-delivery-runtime__header">
|
|
954
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
955
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
954
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml(model.title)}</span>
|
|
955
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml(model.label)}</strong>
|
|
956
956
|
</header>
|
|
957
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
957
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml(model.description)}</p>
|
|
958
958
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
959
959
|
${actions}
|
|
960
960
|
${actionError}
|
|
961
|
-
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
961
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml(model.error)}</p>` : ""}
|
|
962
962
|
</section>`;
|
|
963
963
|
};
|
|
964
964
|
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}`;
|
|
@@ -1230,7 +1230,6 @@ var DEFAULT_LINKS = [
|
|
|
1230
1230
|
{ href: "/switching-from-vapi", label: "Switching guide" },
|
|
1231
1231
|
{ href: "/api/voice/vapi-coverage", label: "Coverage JSON" }
|
|
1232
1232
|
];
|
|
1233
|
-
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1234
1233
|
var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1235
1234
|
var surfaceDetail2 = (surface) => {
|
|
1236
1235
|
if (surface.status === "pass") {
|
|
@@ -1267,24 +1266,24 @@ var createVoicePlatformCoverageViewModel = (snapshot, options = {}) => {
|
|
|
1267
1266
|
};
|
|
1268
1267
|
var renderVoicePlatformCoverageHTML = (snapshot, options = {}) => {
|
|
1269
1268
|
const model = createVoicePlatformCoverageViewModel(snapshot, options);
|
|
1270
|
-
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--${
|
|
1269
|
+
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)}">
|
|
1271
1270
|
<header>
|
|
1272
|
-
<strong>${
|
|
1273
|
-
<span>${
|
|
1271
|
+
<strong>${escapeHtml(surface.label)}</strong>
|
|
1272
|
+
<span>${escapeHtml(formatStatus(surface.status))}</span>
|
|
1274
1273
|
</header>
|
|
1275
|
-
<p>${
|
|
1274
|
+
<p>${escapeHtml(surface.detail)}</p>
|
|
1276
1275
|
<small>${surface.evidence.filter((item) => item.ok).length}/${surface.evidence.length} evidence checks passing</small>
|
|
1277
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-platform-coverage__empty">${model.error ?
|
|
1278
|
-
const links = model.links.length ? `<p class="absolute-voice-platform-coverage__links">${model.links.map((link) => `<a href="${
|
|
1279
|
-
return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${
|
|
1276
|
+
</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>`;
|
|
1277
|
+
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>` : "";
|
|
1278
|
+
return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${escapeHtml(model.status)}">
|
|
1280
1279
|
<header class="absolute-voice-platform-coverage__header">
|
|
1281
|
-
<span class="absolute-voice-platform-coverage__eyebrow">${
|
|
1282
|
-
<strong class="absolute-voice-platform-coverage__label">${
|
|
1280
|
+
<span class="absolute-voice-platform-coverage__eyebrow">${escapeHtml(model.title)}</span>
|
|
1281
|
+
<strong class="absolute-voice-platform-coverage__label">${escapeHtml(model.label)}</strong>
|
|
1283
1282
|
</header>
|
|
1284
|
-
<p class="absolute-voice-platform-coverage__description">${
|
|
1283
|
+
<p class="absolute-voice-platform-coverage__description">${escapeHtml(model.description)}</p>
|
|
1285
1284
|
${surfaces}
|
|
1286
1285
|
${links}
|
|
1287
|
-
${model.error ? `<p class="absolute-voice-platform-coverage__error">${
|
|
1286
|
+
${model.error ? `<p class="absolute-voice-platform-coverage__error">${escapeHtml(model.error)}</p>` : ""}
|
|
1288
1287
|
</section>`;
|
|
1289
1288
|
};
|
|
1290
1289
|
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}`;
|
|
@@ -1509,6 +1508,18 @@ var useVoiceProofTrends = (path = "/api/voice/proof-trends", options = {}) => {
|
|
|
1509
1508
|
// src/proofTrends.ts
|
|
1510
1509
|
import { Elysia as Elysia4 } from "elysia";
|
|
1511
1510
|
|
|
1511
|
+
// src/internal/status.ts
|
|
1512
|
+
var voiceStatusRank = (status) => status === "fail" ? 2 : status === "warn" ? 1 : 0;
|
|
1513
|
+
var worstVoiceStatus = (statuses) => {
|
|
1514
|
+
let worst = "pass";
|
|
1515
|
+
for (const status of statuses) {
|
|
1516
|
+
if (voiceStatusRank(status) > voiceStatusRank(worst)) {
|
|
1517
|
+
worst = status;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
return worst;
|
|
1521
|
+
};
|
|
1522
|
+
|
|
1512
1523
|
// src/providerDecisionTraces.ts
|
|
1513
1524
|
import { Elysia as Elysia3 } from "elysia";
|
|
1514
1525
|
|
|
@@ -1657,16 +1668,15 @@ var summarizeVoiceProviderHealth = async (input) => {
|
|
|
1657
1668
|
}
|
|
1658
1669
|
return summaries;
|
|
1659
1670
|
};
|
|
1660
|
-
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1661
1671
|
var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p class="voice-provider-empty">No provider status yet.</p>' : [
|
|
1662
1672
|
'<div class="voice-provider-health">',
|
|
1663
1673
|
...providers.map((provider) => {
|
|
1664
1674
|
const suppressionSeconds = typeof provider.suppressionRemainingMs === "number" ? Math.ceil(provider.suppressionRemainingMs / 1000) : undefined;
|
|
1665
1675
|
return [
|
|
1666
|
-
`<article class="voice-provider-card ${
|
|
1676
|
+
`<article class="voice-provider-card ${escapeHtml(provider.status)}">`,
|
|
1667
1677
|
'<div class="voice-provider-card-header">',
|
|
1668
|
-
`<strong>${
|
|
1669
|
-
`<span>${
|
|
1678
|
+
`<strong>${escapeHtml(provider.provider)}</strong>`,
|
|
1679
|
+
`<span>${escapeHtml(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>`,
|
|
1670
1680
|
"</div>",
|
|
1671
1681
|
"<dl>",
|
|
1672
1682
|
`<div><dt>Runs</dt><dd>${String(provider.runCount)}</dd></div>`,
|
|
@@ -1676,7 +1686,7 @@ var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p
|
|
|
1676
1686
|
`<div><dt>Fallbacks</dt><dd>${String(provider.fallbackCount)}</dd></div>`,
|
|
1677
1687
|
"</dl>",
|
|
1678
1688
|
suppressionSeconds ? `<p>Temporarily suppressed for ${String(suppressionSeconds)}s.</p>` : "",
|
|
1679
|
-
provider.lastError ? `<p>${
|
|
1689
|
+
provider.lastError ? `<p>${escapeHtml(provider.lastError)}</p>` : "",
|
|
1680
1690
|
"</article>"
|
|
1681
1691
|
].join("");
|
|
1682
1692
|
}),
|
|
@@ -1707,7 +1717,6 @@ var createVoiceProviderHealthRoutes = (options) => {
|
|
|
1707
1717
|
};
|
|
1708
1718
|
|
|
1709
1719
|
// src/resilienceRoutes.ts
|
|
1710
|
-
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1711
1720
|
var getString2 = (value) => typeof value === "string" ? value : undefined;
|
|
1712
1721
|
var getNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
1713
1722
|
var getBoolean = (value) => value === true;
|
|
@@ -1855,13 +1864,13 @@ var summarizeRoutingEvents = (events) => {
|
|
|
1855
1864
|
};
|
|
1856
1865
|
var renderProviderCards = (title, providers) => {
|
|
1857
1866
|
if (providers.length === 0) {
|
|
1858
|
-
return `<p class="muted">No ${
|
|
1867
|
+
return `<p class="muted">No ${escapeHtml(title)} provider health yet.</p>`;
|
|
1859
1868
|
}
|
|
1860
1869
|
return `<div class="provider-grid">${providers.map((provider) => `
|
|
1861
|
-
<article class="card provider ${
|
|
1870
|
+
<article class="card provider ${escapeHtml(provider.status)}">
|
|
1862
1871
|
<div class="card-header">
|
|
1863
|
-
<strong>${
|
|
1864
|
-
<span>${
|
|
1872
|
+
<strong>${escapeHtml(provider.provider)}</strong>
|
|
1873
|
+
<span>${escapeHtml(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
|
|
1865
1874
|
</div>
|
|
1866
1875
|
<dl>
|
|
1867
1876
|
<div><dt>Runs</dt><dd>${provider.runCount}</dd></div>
|
|
@@ -1870,7 +1879,7 @@ var renderProviderCards = (title, providers) => {
|
|
|
1870
1879
|
<div><dt>Timeouts</dt><dd>${provider.timeoutCount}</dd></div>
|
|
1871
1880
|
<div><dt>Fallbacks</dt><dd>${provider.fallbackCount}</dd></div>
|
|
1872
1881
|
</dl>
|
|
1873
|
-
${provider.lastError ? `<p class="muted">${
|
|
1882
|
+
${provider.lastError ? `<p class="muted">${escapeHtml(provider.lastError)}</p>` : ""}
|
|
1874
1883
|
</article>
|
|
1875
1884
|
`).join("")}</div>`;
|
|
1876
1885
|
};
|
|
@@ -1879,24 +1888,24 @@ var renderTimeline = (events) => {
|
|
|
1879
1888
|
return '<p class="muted">No provider routing events yet. Run the app or simulate provider failover.</p>';
|
|
1880
1889
|
}
|
|
1881
1890
|
return `<div class="timeline">${events.slice(0, 40).map((event) => `
|
|
1882
|
-
<article class="card event ${
|
|
1891
|
+
<article class="card event ${escapeHtml(event.status ?? "unknown")}">
|
|
1883
1892
|
<div class="card-header">
|
|
1884
|
-
<strong>${
|
|
1893
|
+
<strong>${escapeHtml(event.kind.toUpperCase())} ${escapeHtml(event.operation ?? "generate")}</strong>
|
|
1885
1894
|
<span>${new Date(event.at).toLocaleString()}</span>
|
|
1886
1895
|
</div>
|
|
1887
1896
|
<p>
|
|
1888
|
-
<span class="pill">${
|
|
1889
|
-
<span class="pill">provider: ${
|
|
1890
|
-
${event.fallbackProvider ? `<span class="pill">fallback: ${
|
|
1897
|
+
<span class="pill">${escapeHtml(event.status ?? "unknown")}</span>
|
|
1898
|
+
<span class="pill">provider: ${escapeHtml(event.provider ?? "unknown")}</span>
|
|
1899
|
+
${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml(event.fallbackProvider)}</span>` : ""}
|
|
1891
1900
|
${event.timedOut ? '<span class="pill danger">timed out</span>' : ""}
|
|
1892
1901
|
</p>
|
|
1893
1902
|
<dl>
|
|
1894
1903
|
<div><dt>Attempt</dt><dd>${event.attempt ?? 0}</dd></div>
|
|
1895
1904
|
<div><dt>Elapsed</dt><dd>${event.elapsedMs ?? 0}ms</dd></div>
|
|
1896
1905
|
<div><dt>Budget</dt><dd>${event.latencyBudgetMs ?? 0}ms</dd></div>
|
|
1897
|
-
<div><dt>Session</dt><dd>${
|
|
1906
|
+
<div><dt>Session</dt><dd>${escapeHtml(event.sessionId)}</dd></div>
|
|
1898
1907
|
</dl>
|
|
1899
|
-
${event.error ? `<p class="muted">${
|
|
1908
|
+
${event.error ? `<p class="muted">${escapeHtml(event.error)}</p>` : ""}
|
|
1900
1909
|
</article>
|
|
1901
1910
|
`).join("")}</div>`;
|
|
1902
1911
|
};
|
|
@@ -1906,9 +1915,9 @@ var renderSessionKind = (kind, summary) => {
|
|
|
1906
1915
|
const status = latest?.status ?? "idle";
|
|
1907
1916
|
const fallback = latest?.fallbackProvider && latest.fallbackProvider !== provider ? ` -> ${latest.fallbackProvider}` : "";
|
|
1908
1917
|
return `<div>
|
|
1909
|
-
<dt>${
|
|
1910
|
-
<dd>${
|
|
1911
|
-
<small>${
|
|
1918
|
+
<dt>${escapeHtml(kind.toUpperCase())}</dt>
|
|
1919
|
+
<dd>${escapeHtml(provider)}${escapeHtml(fallback)}</dd>
|
|
1920
|
+
<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>
|
|
1912
1921
|
</div>`;
|
|
1913
1922
|
};
|
|
1914
1923
|
var renderSessionSummaries = (sessions) => {
|
|
@@ -1916,10 +1925,10 @@ var renderSessionSummaries = (sessions) => {
|
|
|
1916
1925
|
return '<p class="muted">No call-level routing summaries yet. Run a voice session or provider simulation.</p>';
|
|
1917
1926
|
}
|
|
1918
1927
|
return `<div class="session-grid">${sessions.slice(0, 12).map((session) => `
|
|
1919
|
-
<article class="card session ${
|
|
1928
|
+
<article class="card session ${escapeHtml(session.status)}">
|
|
1920
1929
|
<div class="card-header">
|
|
1921
|
-
<strong>${
|
|
1922
|
-
<span>${
|
|
1930
|
+
<strong>${escapeHtml(session.sessionId)}</strong>
|
|
1931
|
+
<span>${escapeHtml(session.status)}</span>
|
|
1923
1932
|
</div>
|
|
1924
1933
|
<p>
|
|
1925
1934
|
<span class="pill">${session.eventCount} routing events</span>
|
|
@@ -1946,21 +1955,21 @@ var renderSimulationControls = (kind, simulation) => {
|
|
|
1946
1955
|
const pathPrefix = simulation.pathPrefix ?? `/api/${kind}-simulate`;
|
|
1947
1956
|
const failureProviders = simulation.failureProviders ?? configuredProviders.map(({ provider }) => provider);
|
|
1948
1957
|
const canFail = (provider) => configuredProviders.some((entry) => entry.provider === provider) && (!simulation.fallbackRequiredProvider || configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider));
|
|
1949
|
-
return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${
|
|
1950
|
-
<p class="muted">${
|
|
1958
|
+
return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml(pathPrefix)}">
|
|
1959
|
+
<p class="muted">${escapeHtml(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
|
|
1951
1960
|
<div class="simulate-actions">
|
|
1952
|
-
${failureProviders.map((provider) => `<button type="button" data-provider-fail="${
|
|
1953
|
-
${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${
|
|
1961
|
+
${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
|
|
1962
|
+
${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml(provider.provider)}">Mark ${escapeHtml(provider.provider)} recovered</button>`).join("")}
|
|
1954
1963
|
</div>
|
|
1955
|
-
${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${
|
|
1964
|
+
${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
|
|
1956
1965
|
<pre class="simulate-output" hidden></pre>
|
|
1957
1966
|
</div>`;
|
|
1958
1967
|
};
|
|
1959
1968
|
var renderVoiceResilienceHTML = (input) => {
|
|
1960
1969
|
const summary = summarizeRoutingEvents(input.routingEvents);
|
|
1961
|
-
const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${
|
|
1962
|
-
const links = input.links?.length ? input.links.map((link) => `<a href="${
|
|
1963
|
-
const snippet =
|
|
1970
|
+
const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml(kind)}: ${String(count)}</span>`).join("");
|
|
1971
|
+
const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join(" \xB7 ") : "";
|
|
1972
|
+
const snippet = escapeHtml(`const sttSimulator = createVoiceIOProviderFailureSimulator({
|
|
1964
1973
|
kind: 'stt',
|
|
1965
1974
|
providers: ['deepgram', 'assemblyai'],
|
|
1966
1975
|
fallback: ['deepgram', 'assemblyai'],
|
|
@@ -1998,7 +2007,7 @@ app.use(
|
|
|
1998
2007
|
<head>
|
|
1999
2008
|
<meta charset="utf-8" />
|
|
2000
2009
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
2001
|
-
<title>${
|
|
2010
|
+
<title>${escapeHtml(input.title ?? "AbsoluteJS Voice Resilience")}</title>
|
|
2002
2011
|
<style>
|
|
2003
2012
|
:root { color-scheme: dark; }
|
|
2004
2013
|
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; }
|
|
@@ -2191,7 +2200,6 @@ var createVoiceResilienceRoutes = (options) => {
|
|
|
2191
2200
|
};
|
|
2192
2201
|
|
|
2193
2202
|
// src/providerDecisionTraces.ts
|
|
2194
|
-
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2195
2203
|
var getString3 = (value) => typeof value === "string" ? value : undefined;
|
|
2196
2204
|
var getNumber3 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
2197
2205
|
var isDecisionTrace = (event) => Boolean(event && typeof event === "object" && "provider" in event && "reason" in event && "sessionId" in event && "status" in event && "surface" in event);
|
|
@@ -2206,8 +2214,7 @@ var surfaceForKind = (kind) => {
|
|
|
2206
2214
|
return "live-call";
|
|
2207
2215
|
}
|
|
2208
2216
|
};
|
|
2209
|
-
var
|
|
2210
|
-
var reportStatus = (issues) => issues.reduce((status, issue) => statusRank[issue.status] > statusRank[status] ? issue.status : status, "pass");
|
|
2217
|
+
var reportStatus = (issues) => worstVoiceStatus(issues.map((issue) => issue.status));
|
|
2211
2218
|
var uniqueSorted = (values) => [
|
|
2212
2219
|
...new Set(values.filter((value) => typeof value === "string"))
|
|
2213
2220
|
].sort();
|
|
@@ -2432,7 +2439,7 @@ var renderVoiceProviderDecisionTraceHTML = (report, title = "Provider Decision T
|
|
|
2432
2439
|
<head>
|
|
2433
2440
|
<meta charset="utf-8" />
|
|
2434
2441
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
2435
|
-
<title>${
|
|
2442
|
+
<title>${escapeHtml(title)}</title>
|
|
2436
2443
|
<style>
|
|
2437
2444
|
body{font-family:ui-sans-serif,system-ui,sans-serif;margin:0;background:#f8fafc;color:#0f172a}
|
|
2438
2445
|
main{max-width:1100px;margin:0 auto;padding:32px}
|
|
@@ -2446,8 +2453,8 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
|
|
|
2446
2453
|
</head>
|
|
2447
2454
|
<body>
|
|
2448
2455
|
<main>
|
|
2449
|
-
<p class="status ${report.status}">${
|
|
2450
|
-
<h1>${
|
|
2456
|
+
<p class="status ${report.status}">${escapeHtml(report.status)}</p>
|
|
2457
|
+
<h1>${escapeHtml(title)}</h1>
|
|
2451
2458
|
<p class="muted">Runtime proof for why providers were selected, skipped, failed, or recovered by fallback.</p>
|
|
2452
2459
|
<section class="grid">
|
|
2453
2460
|
<article class="card"><strong>${String(report.summary.decisions)}</strong><p>decisions</p></article>
|
|
@@ -2458,10 +2465,10 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
|
|
|
2458
2465
|
</section>
|
|
2459
2466
|
<section class="surfaces">
|
|
2460
2467
|
${report.surfaces.map((surface) => `<article class="surface">
|
|
2461
|
-
<header><strong>${
|
|
2468
|
+
<header><strong>${escapeHtml(surface.surface)}</strong> <span class="status ${surface.status}">${escapeHtml(surface.status)}</span></header>
|
|
2462
2469
|
<p>${String(surface.decisions)} decision(s), ${String(surface.fallbacks)} fallback(s), ${String(surface.degraded)} degraded decision(s), ${String(surface.errors)} error(s).</p>
|
|
2463
|
-
<p class="muted">Providers: ${
|
|
2464
|
-
<p>${surface.reasons.map((reason) => `<code>${
|
|
2470
|
+
<p class="muted">Providers: ${escapeHtml(surface.providers.join(", ") || "none")}</p>
|
|
2471
|
+
<p>${surface.reasons.map((reason) => `<code>${escapeHtml(reason)}</code>`).join(" ")}</p>
|
|
2465
2472
|
</article>`).join(`
|
|
2466
2473
|
`)}
|
|
2467
2474
|
</section>
|
|
@@ -2979,7 +2986,6 @@ var exportVoiceTrace = async (input) => {
|
|
|
2979
2986
|
};
|
|
2980
2987
|
};
|
|
2981
2988
|
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2982
|
-
var escapeHtml8 = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
2983
2989
|
var formatTraceValue = (value) => {
|
|
2984
2990
|
if (value === undefined || value === null) {
|
|
2985
2991
|
return "";
|
|
@@ -3263,10 +3269,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3263
3269
|
const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
|
|
3264
3270
|
return [
|
|
3265
3271
|
"<tr>",
|
|
3266
|
-
`<td>${
|
|
3267
|
-
`<td>${
|
|
3268
|
-
`<td>${
|
|
3269
|
-
`<td><code>${
|
|
3272
|
+
`<td>${escapeHtml(String(offset))}</td>`,
|
|
3273
|
+
`<td>${escapeHtml(event.type)}</td>`,
|
|
3274
|
+
`<td>${escapeHtml(event.turnId ?? "")}</td>`,
|
|
3275
|
+
`<td><code>${escapeHtml(JSON.stringify(event.payload))}</code></td>`,
|
|
3270
3276
|
"</tr>"
|
|
3271
3277
|
].join("");
|
|
3272
3278
|
}).join(`
|
|
@@ -3277,7 +3283,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3277
3283
|
"<head>",
|
|
3278
3284
|
'<meta charset="utf-8" />',
|
|
3279
3285
|
'<meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
3280
|
-
`<title>${
|
|
3286
|
+
`<title>${escapeHtml(options.title ?? "Voice Trace")}</title>`,
|
|
3281
3287
|
"<style>",
|
|
3282
3288
|
"body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
|
|
3283
3289
|
"main{max-width:1100px;margin:auto}",
|
|
@@ -3291,7 +3297,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3291
3297
|
"</style>",
|
|
3292
3298
|
"</head>",
|
|
3293
3299
|
"<body><main>",
|
|
3294
|
-
`<h1>${
|
|
3300
|
+
`<h1>${escapeHtml(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
|
|
3295
3301
|
`<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
|
|
3296
3302
|
'<section class="summary">',
|
|
3297
3303
|
`<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
|
|
@@ -3305,7 +3311,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
3305
3311
|
eventRows,
|
|
3306
3312
|
"</tbody></table>",
|
|
3307
3313
|
"<h2>Markdown Export</h2>",
|
|
3308
|
-
`<pre>${
|
|
3314
|
+
`<pre>${escapeHtml(markdown)}</pre>`,
|
|
3309
3315
|
"</main></body></html>"
|
|
3310
3316
|
].join(`
|
|
3311
3317
|
`);
|
|
@@ -5684,7 +5690,6 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
5684
5690
|
}
|
|
5685
5691
|
};
|
|
5686
5692
|
};
|
|
5687
|
-
var escapeHtml9 = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5688
5693
|
var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
|
|
5689
5694
|
var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provider Runtime Recommendations") => [
|
|
5690
5695
|
`# ${title}`,
|
|
@@ -5719,11 +5724,11 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
|
|
|
5719
5724
|
].join(`
|
|
5720
5725
|
`);
|
|
5721
5726
|
var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider Runtime Recommendations") => {
|
|
5722
|
-
const cards = report.recommendations.map((recommendation) => `<article class="${
|
|
5723
|
-
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
5724
|
-
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${
|
|
5725
|
-
const profileRows = report.profiles.length === 0 ? "<li>No benchmark profiles were present.</li>" : report.profiles.map((profile) => `<li><strong>${
|
|
5726
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
5727
|
+
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("");
|
|
5728
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
5729
|
+
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("");
|
|
5730
|
+
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("");
|
|
5731
|
+
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>`;
|
|
5727
5732
|
};
|
|
5728
5733
|
var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Call Profile History") => [
|
|
5729
5734
|
`# ${title}`,
|
|
@@ -5757,11 +5762,11 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
|
|
|
5757
5762
|
].join(`
|
|
5758
5763
|
`);
|
|
5759
5764
|
var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
|
|
5760
|
-
const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${
|
|
5761
|
-
const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${
|
|
5762
|
-
const recommendations = report.recommendations.recommendations.map((recommendation) => `<article class="${
|
|
5763
|
-
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
5764
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
5765
|
+
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>';
|
|
5766
|
+
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>';
|
|
5767
|
+
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("");
|
|
5768
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
5769
|
+
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>`;
|
|
5765
5770
|
};
|
|
5766
5771
|
var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Call Evidence Runtime") => [
|
|
5767
5772
|
`# ${title}`,
|
|
@@ -5784,9 +5789,9 @@ var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Ca
|
|
|
5784
5789
|
].join(`
|
|
5785
5790
|
`);
|
|
5786
5791
|
var renderVoiceRealCallEvidenceRuntimeHTML = (report, title = "Voice Real-Call Evidence Runtime") => {
|
|
5787
|
-
const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
5788
|
-
const profileRows = report.history.summary.profiles?.length ? report.history.summary.profiles.map((profile) => `<tr><td>${
|
|
5789
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
5792
|
+
const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
5793
|
+
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>';
|
|
5794
|
+
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>`;
|
|
5790
5795
|
};
|
|
5791
5796
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
5792
5797
|
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}`;
|
|
@@ -6394,7 +6398,6 @@ var DEFAULT_LINKS3 = [
|
|
|
6394
6398
|
label: "Profile history JSON"
|
|
6395
6399
|
}
|
|
6396
6400
|
];
|
|
6397
|
-
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6398
6401
|
var formatMs2 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
6399
6402
|
var formatCount = (value) => new Intl.NumberFormat("en-US").format(value);
|
|
6400
6403
|
var formatAge = (value) => {
|
|
@@ -6449,21 +6452,21 @@ var createVoiceReconnectProfileEvidenceViewModel = (snapshot, options = {}) => {
|
|
|
6449
6452
|
var renderVoiceReconnectProfileEvidenceHTML = (snapshot, options = {}) => {
|
|
6450
6453
|
const model = createVoiceReconnectProfileEvidenceViewModel(snapshot, options);
|
|
6451
6454
|
const metrics = `<div class="absolute-voice-reconnect-evidence__metrics">${model.metrics.map((metric) => `<article>
|
|
6452
|
-
<span>${
|
|
6453
|
-
<strong>${
|
|
6455
|
+
<span>${escapeHtml(metric.label)}</span>
|
|
6456
|
+
<strong>${escapeHtml(metric.value)}</strong>
|
|
6454
6457
|
</article>`).join("")}</div>`;
|
|
6455
|
-
const latest = model.latest ? `<p class="absolute-voice-reconnect-evidence__latest">Latest ${
|
|
6456
|
-
const links = model.links.length ? `<p class="absolute-voice-reconnect-evidence__links">${model.links.map((link) => `<a href="${
|
|
6457
|
-
return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${
|
|
6458
|
+
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>`;
|
|
6459
|
+
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>` : "";
|
|
6460
|
+
return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${escapeHtml(model.status)}">
|
|
6458
6461
|
<header class="absolute-voice-reconnect-evidence__header">
|
|
6459
|
-
<span class="absolute-voice-reconnect-evidence__eyebrow">${
|
|
6460
|
-
<strong class="absolute-voice-reconnect-evidence__label">${
|
|
6462
|
+
<span class="absolute-voice-reconnect-evidence__eyebrow">${escapeHtml(model.title)}</span>
|
|
6463
|
+
<strong class="absolute-voice-reconnect-evidence__label">${escapeHtml(model.label)}</strong>
|
|
6461
6464
|
</header>
|
|
6462
|
-
<p class="absolute-voice-reconnect-evidence__description">${
|
|
6465
|
+
<p class="absolute-voice-reconnect-evidence__description">${escapeHtml(model.description)}</p>
|
|
6463
6466
|
${metrics}
|
|
6464
6467
|
${latest}
|
|
6465
6468
|
${links}
|
|
6466
|
-
${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${
|
|
6469
|
+
${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${escapeHtml(model.error)}</p>` : ""}
|
|
6467
6470
|
</section>`;
|
|
6468
6471
|
};
|
|
6469
6472
|
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))}}`;
|
|
@@ -6676,7 +6679,6 @@ var createVoiceCallDebuggerStore = (path, options = {}) => {
|
|
|
6676
6679
|
var DEFAULT_TITLE7 = "Call Debugger";
|
|
6677
6680
|
var DEFAULT_DESCRIPTION7 = "Open the latest call artifact with snapshot, operations record, failure replay, provider path, transcript, and incident markdown.";
|
|
6678
6681
|
var DEFAULT_LINK_LABEL = "Open debugger";
|
|
6679
|
-
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6680
6682
|
var defaultHref = (path, report) => {
|
|
6681
6683
|
if (path.startsWith("/api/voice-call-debugger/")) {
|
|
6682
6684
|
return path.replace("/api/voice-call-debugger/", "/voice-call-debugger/");
|
|
@@ -6729,18 +6731,18 @@ var createVoiceCallDebuggerLaunchViewModel = (path, state, options = {}) => {
|
|
|
6729
6731
|
var renderVoiceCallDebuggerLaunchHTML = (path, state, options = {}) => {
|
|
6730
6732
|
const model = createVoiceCallDebuggerLaunchViewModel(path, state, options);
|
|
6731
6733
|
const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
|
|
6732
|
-
<dt>${
|
|
6733
|
-
<dd>${
|
|
6734
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
6735
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
6734
6736
|
</div>`).join("")}</dl>` : '<p class="absolute-voice-call-debugger-launch__empty">Load a call debugger report to see the latest support artifact.</p>';
|
|
6735
|
-
return `<section class="absolute-voice-call-debugger-launch absolute-voice-call-debugger-launch--${
|
|
6737
|
+
return `<section class="absolute-voice-call-debugger-launch absolute-voice-call-debugger-launch--${escapeHtml(model.status)}">
|
|
6736
6738
|
<header class="absolute-voice-call-debugger-launch__header">
|
|
6737
|
-
<span class="absolute-voice-call-debugger-launch__eyebrow">${
|
|
6738
|
-
<strong class="absolute-voice-call-debugger-launch__label">${
|
|
6739
|
+
<span class="absolute-voice-call-debugger-launch__eyebrow">${escapeHtml(model.title)}</span>
|
|
6740
|
+
<strong class="absolute-voice-call-debugger-launch__label">${escapeHtml(model.label)}</strong>
|
|
6739
6741
|
</header>
|
|
6740
|
-
<p class="absolute-voice-call-debugger-launch__description">${
|
|
6741
|
-
<a class="absolute-voice-call-debugger-launch__link" href="${
|
|
6742
|
+
<p class="absolute-voice-call-debugger-launch__description">${escapeHtml(model.description)}</p>
|
|
6743
|
+
<a class="absolute-voice-call-debugger-launch__link" href="${escapeHtml(model.href)}">${escapeHtml(options.linkLabel ?? DEFAULT_LINK_LABEL)}</a>
|
|
6742
6744
|
${rows}
|
|
6743
|
-
${model.error ? `<p class="absolute-voice-call-debugger-launch__error">${
|
|
6745
|
+
${model.error ? `<p class="absolute-voice-call-debugger-launch__error">${escapeHtml(model.error)}</p>` : ""}
|
|
6744
6746
|
</section>`;
|
|
6745
6747
|
};
|
|
6746
6748
|
var mountVoiceCallDebuggerLaunch = (element, path, options = {}) => {
|
|
@@ -6957,7 +6959,6 @@ var createVoiceSessionSnapshotStore = (path, options = {}) => {
|
|
|
6957
6959
|
var DEFAULT_TITLE8 = "Session Snapshot";
|
|
6958
6960
|
var DEFAULT_DESCRIPTION8 = "Portable call artifact with media graph, provider routing, proof, quality, and telephony evidence.";
|
|
6959
6961
|
var DEFAULT_DOWNLOAD_LABEL = "Download snapshot";
|
|
6960
|
-
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6961
6962
|
var formatStatus2 = (status) => status ?? "n/a";
|
|
6962
6963
|
var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
6963
6964
|
const snapshot = state.snapshot;
|
|
@@ -7007,23 +7008,23 @@ var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
|
7007
7008
|
var renderVoiceSessionSnapshotHTML = (state, options = {}) => {
|
|
7008
7009
|
const model = createVoiceSessionSnapshotViewModel(state, options);
|
|
7009
7010
|
const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
|
|
7010
|
-
<dt>${
|
|
7011
|
-
<dd>${
|
|
7011
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
7012
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
7012
7013
|
</div>`).join("")}</dl>` : '<p class="absolute-voice-session-snapshot__empty">Load a session snapshot to see support diagnostics.</p>';
|
|
7013
7014
|
const artifacts = model.artifacts.length ? `<div class="absolute-voice-session-snapshot__artifacts">${model.artifacts.map((artifact) => {
|
|
7014
|
-
const body = `<strong>${
|
|
7015
|
-
return artifact.href ? `<a href="${
|
|
7015
|
+
const body = `<strong>${escapeHtml(artifact.label)}</strong><span>${escapeHtml(artifact.status)}</span>`;
|
|
7016
|
+
return artifact.href ? `<a href="${escapeHtml(artifact.href)}">${body}</a>` : `<div>${body}</div>`;
|
|
7016
7017
|
}).join("")}</div>` : "";
|
|
7017
|
-
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${
|
|
7018
|
+
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${escapeHtml(model.status)}">
|
|
7018
7019
|
<header class="absolute-voice-session-snapshot__header">
|
|
7019
|
-
<span class="absolute-voice-session-snapshot__eyebrow">${
|
|
7020
|
-
<strong class="absolute-voice-session-snapshot__label">${
|
|
7020
|
+
<span class="absolute-voice-session-snapshot__eyebrow">${escapeHtml(model.title)}</span>
|
|
7021
|
+
<strong class="absolute-voice-session-snapshot__label">${escapeHtml(model.label)}</strong>
|
|
7021
7022
|
</header>
|
|
7022
|
-
<p class="absolute-voice-session-snapshot__description">${
|
|
7023
|
-
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${
|
|
7023
|
+
<p class="absolute-voice-session-snapshot__description">${escapeHtml(model.description)}</p>
|
|
7024
|
+
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${escapeHtml(options.downloadLabel ?? DEFAULT_DOWNLOAD_LABEL)}</button>` : ""}
|
|
7024
7025
|
${rows}
|
|
7025
7026
|
${artifacts}
|
|
7026
|
-
${model.error ? `<p class="absolute-voice-session-snapshot__error">${
|
|
7027
|
+
${model.error ? `<p class="absolute-voice-session-snapshot__error">${escapeHtml(model.error)}</p>` : ""}
|
|
7027
7028
|
</section>`;
|
|
7028
7029
|
};
|
|
7029
7030
|
var downloadBlob = (blob, filename) => {
|
|
@@ -7249,7 +7250,6 @@ var createVoiceSessionObservabilityStore = (path, options = {}) => {
|
|
|
7249
7250
|
// src/client/sessionObservabilityWidget.ts
|
|
7250
7251
|
var DEFAULT_TITLE9 = "Session Observability";
|
|
7251
7252
|
var DEFAULT_DESCRIPTION9 = "One support/debug report for a voice call across traces, provider recovery, tools, handoffs, guardrails, turn waterfalls, and incident handoff.";
|
|
7252
|
-
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7253
7253
|
var formatMs3 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
7254
7254
|
var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
|
|
7255
7255
|
const report = snapshot.report;
|
|
@@ -7271,20 +7271,20 @@ var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
|
|
|
7271
7271
|
updatedAt: snapshot.updatedAt
|
|
7272
7272
|
};
|
|
7273
7273
|
};
|
|
7274
|
-
var renderLinks = (links) => links.length ? `<p class="absolute-voice-session-observability__actions">${links.map((link) => `<a href="${
|
|
7274
|
+
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>` : "";
|
|
7275
7275
|
var renderVoiceSessionObservabilityHTML = (snapshot, options = {}) => {
|
|
7276
7276
|
const model = createVoiceSessionObservabilityViewModel(snapshot, options);
|
|
7277
|
-
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>${
|
|
7278
|
-
return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${
|
|
7277
|
+
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>';
|
|
7278
|
+
return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${escapeHtml(model.status)}">
|
|
7279
7279
|
<header class="absolute-voice-session-observability__header">
|
|
7280
|
-
<span class="absolute-voice-session-observability__eyebrow">${
|
|
7281
|
-
<strong class="absolute-voice-session-observability__label">${
|
|
7280
|
+
<span class="absolute-voice-session-observability__eyebrow">${escapeHtml(model.title)}</span>
|
|
7281
|
+
<strong class="absolute-voice-session-observability__label">${escapeHtml(model.label)}</strong>
|
|
7282
7282
|
</header>
|
|
7283
|
-
<p class="absolute-voice-session-observability__description">${
|
|
7284
|
-
${model.sessionId ? `<p class="absolute-voice-session-observability__session">${
|
|
7283
|
+
<p class="absolute-voice-session-observability__description">${escapeHtml(model.description)}</p>
|
|
7284
|
+
${model.sessionId ? `<p class="absolute-voice-session-observability__session">${escapeHtml(model.sessionId)}</p>` : ""}
|
|
7285
7285
|
${renderLinks(model.links)}
|
|
7286
7286
|
${turns}
|
|
7287
|
-
${model.error ? `<p class="absolute-voice-session-observability__error">${
|
|
7287
|
+
${model.error ? `<p class="absolute-voice-session-observability__error">${escapeHtml(model.error)}</p>` : ""}
|
|
7288
7288
|
</section>`;
|
|
7289
7289
|
};
|
|
7290
7290
|
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}`;
|
|
@@ -7502,7 +7502,6 @@ var DEFAULT_LINKS4 = [
|
|
|
7502
7502
|
{ href: "/voice/real-call-profile-history", label: "Profile history" },
|
|
7503
7503
|
{ href: "/api/voice/real-call-profile-history", label: "JSON" }
|
|
7504
7504
|
];
|
|
7505
|
-
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7506
7505
|
var formatMs4 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
7507
7506
|
var formatProviderRoutes = (profile) => Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "No complete route yet";
|
|
7508
7507
|
var createProfileView = (profile) => ({
|
|
@@ -7533,25 +7532,25 @@ var createVoiceProfileComparisonViewModel = (snapshot, options = {}) => {
|
|
|
7533
7532
|
};
|
|
7534
7533
|
var renderVoiceProfileComparisonHTML = (snapshot, options = {}) => {
|
|
7535
7534
|
const model = createVoiceProfileComparisonViewModel(snapshot, options);
|
|
7536
|
-
const profiles = model.profiles.length ? `<div class="absolute-voice-profile-comparison__profiles">${model.profiles.map((profile) => `<article class="absolute-voice-profile-comparison__profile absolute-voice-profile-comparison__profile--${
|
|
7535
|
+
const profiles = model.profiles.length ? `<div class="absolute-voice-profile-comparison__profiles">${model.profiles.map((profile) => `<article class="absolute-voice-profile-comparison__profile absolute-voice-profile-comparison__profile--${escapeHtml(profile.status)}">
|
|
7537
7536
|
<header>
|
|
7538
|
-
<span>${
|
|
7539
|
-
<strong>${
|
|
7537
|
+
<span>${escapeHtml(profile.status)}</span>
|
|
7538
|
+
<strong>${escapeHtml(profile.label)}</strong>
|
|
7540
7539
|
</header>
|
|
7541
|
-
<p>${
|
|
7542
|
-
<div>${profile.evidence.map((metric) => `<span><small>${
|
|
7543
|
-
<em>${
|
|
7544
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ?
|
|
7545
|
-
const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${
|
|
7546
|
-
return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${
|
|
7540
|
+
<p>${escapeHtml(profile.providerRoutes)}</p>
|
|
7541
|
+
<div>${profile.evidence.map((metric) => `<span><small>${escapeHtml(metric.label)}</small><b>${escapeHtml(metric.value)}</b></span>`).join("")}</div>
|
|
7542
|
+
<em>${escapeHtml(profile.nextMove)}</em>
|
|
7543
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ? escapeHtml(model.error) : "Run real-call profile collection to populate profile comparisons."}</p>`;
|
|
7544
|
+
const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</p>` : "";
|
|
7545
|
+
return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${escapeHtml(model.status)}">
|
|
7547
7546
|
<header class="absolute-voice-profile-comparison__header">
|
|
7548
|
-
<span class="absolute-voice-profile-comparison__eyebrow">${
|
|
7549
|
-
<strong class="absolute-voice-profile-comparison__label">${
|
|
7547
|
+
<span class="absolute-voice-profile-comparison__eyebrow">${escapeHtml(model.title)}</span>
|
|
7548
|
+
<strong class="absolute-voice-profile-comparison__label">${escapeHtml(model.label)}</strong>
|
|
7550
7549
|
</header>
|
|
7551
|
-
<p class="absolute-voice-profile-comparison__description">${
|
|
7550
|
+
<p class="absolute-voice-profile-comparison__description">${escapeHtml(model.description)}</p>
|
|
7552
7551
|
${profiles}
|
|
7553
7552
|
${links}
|
|
7554
|
-
${model.error ? `<p class="absolute-voice-profile-comparison__error">${
|
|
7553
|
+
${model.error ? `<p class="absolute-voice-profile-comparison__error">${escapeHtml(model.error)}</p>` : ""}
|
|
7555
7554
|
</section>`;
|
|
7556
7555
|
};
|
|
7557
7556
|
var getVoiceProfileComparisonCSS = () => `.absolute-voice-profile-comparison{border:1px solid #c7d2fe;border-radius:20px;background:#eef2ff;color:#111827;padding:18px;box-shadow:0 18px 40px rgba(79,70,229,.12);font-family:inherit}.absolute-voice-profile-comparison--warning,.absolute-voice-profile-comparison--error{border-color:#fbbf24;background:#fffbeb}.absolute-voice-profile-comparison__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-profile-comparison__eyebrow{color:#4338ca;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-profile-comparison__label{font-size:24px;line-height:1}.absolute-voice-profile-comparison__description,.absolute-voice-profile-comparison__empty{color:#4b5563}.absolute-voice-profile-comparison__profiles{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));margin-top:14px}.absolute-voice-profile-comparison__profile{background:#fff;border:1px solid #c7d2fe;border-radius:16px;padding:14px}.absolute-voice-profile-comparison__profile--warn{border-color:#fbbf24}.absolute-voice-profile-comparison__profile--fail{border-color:#f87171}.absolute-voice-profile-comparison__profile header{align-items:center;display:flex;gap:8px;justify-content:space-between}.absolute-voice-profile-comparison__profile header span{border:1px solid currentColor;border-radius:999px;color:#4338ca;font-size:11px;font-weight:900;padding:3px 7px;text-transform:uppercase}.absolute-voice-profile-comparison__profile p{color:#1f2937;font-weight:800;overflow-wrap:anywhere}.absolute-voice-profile-comparison__profile div{display:grid;gap:8px;grid-template-columns:repeat(3,minmax(0,1fr))}.absolute-voice-profile-comparison__profile small{color:#6b7280;display:block;font-size:11px}.absolute-voice-profile-comparison__profile b{display:block}.absolute-voice-profile-comparison__profile em{color:#4b5563;display:block;font-size:13px;margin-top:12px}.absolute-voice-profile-comparison__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-profile-comparison__links a{border:1px solid #a5b4fc;border-radius:999px;color:#4338ca;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-profile-comparison__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7774,27 +7773,26 @@ var createVoiceProfileSwitchRecommendationStore = (path = "/api/voice/profile-sw
|
|
|
7774
7773
|
// src/client/profileSwitchRecommendationWidget.ts
|
|
7775
7774
|
var DEFAULT_TITLE11 = "Profile Switch Recommendation";
|
|
7776
7775
|
var DEFAULT_DESCRIPTION11 = "Compares the current session against measured profile evidence and recommends whether to switch stacks.";
|
|
7777
|
-
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7778
7776
|
var formatRoute = (routes) => routes ? Object.entries(routes).map(([role, provider]) => `${role}: ${provider}`).join(", ") : "No route";
|
|
7779
7777
|
var renderVoiceProfileSwitchRecommendationHTML = (snapshot, options = {}) => {
|
|
7780
7778
|
const recommendation = snapshot.recommendation;
|
|
7781
7779
|
const status = snapshot.error ? "error" : recommendation ? recommendation.status : snapshot.isLoading ? "loading" : "empty";
|
|
7782
7780
|
const label = snapshot.error ? "Unavailable" : recommendation ? recommendation.status === "switch" ? `Switch to ${recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "recommended profile"}` : recommendation.status === "stay" ? "Keep current profile" : "Needs evidence" : snapshot.isLoading ? "Checking" : "No recommendation";
|
|
7783
7781
|
const body = recommendation ? `<div class="absolute-voice-profile-switch__body">
|
|
7784
|
-
<p><strong>Current:</strong> ${
|
|
7785
|
-
<p><strong>Recommended:</strong> ${
|
|
7786
|
-
<p><strong>Routes:</strong> ${
|
|
7787
|
-
<ul>${recommendation.reasons.map((reason) => `<li>${
|
|
7788
|
-
<em>${
|
|
7789
|
-
</div>` : `<p class="absolute-voice-profile-switch__empty">${
|
|
7790
|
-
return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${
|
|
7782
|
+
<p><strong>Current:</strong> ${escapeHtml(recommendation.currentProfile?.label ?? recommendation.currentProfile?.profileId ?? "Unknown")}</p>
|
|
7783
|
+
<p><strong>Recommended:</strong> ${escapeHtml(recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "None")}</p>
|
|
7784
|
+
<p><strong>Routes:</strong> ${escapeHtml(formatRoute(recommendation.recommendedProfile?.providerRoutes))}</p>
|
|
7785
|
+
<ul>${recommendation.reasons.map((reason) => `<li>${escapeHtml(reason)}</li>`).join("")}</ul>
|
|
7786
|
+
<em>${escapeHtml(recommendation.nextMove)}</em>
|
|
7787
|
+
</div>` : `<p class="absolute-voice-profile-switch__empty">${escapeHtml(snapshot.error ?? "Run session traffic to populate a recommendation.")}</p>`;
|
|
7788
|
+
return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${escapeHtml(status)}">
|
|
7791
7789
|
<header class="absolute-voice-profile-switch__header">
|
|
7792
|
-
<span class="absolute-voice-profile-switch__eyebrow">${
|
|
7793
|
-
<strong class="absolute-voice-profile-switch__label">${
|
|
7790
|
+
<span class="absolute-voice-profile-switch__eyebrow">${escapeHtml(options.title ?? DEFAULT_TITLE11)}</span>
|
|
7791
|
+
<strong class="absolute-voice-profile-switch__label">${escapeHtml(label)}</strong>
|
|
7794
7792
|
</header>
|
|
7795
|
-
<p class="absolute-voice-profile-switch__description">${
|
|
7793
|
+
<p class="absolute-voice-profile-switch__description">${escapeHtml(options.description ?? DEFAULT_DESCRIPTION11)}</p>
|
|
7796
7794
|
${body}
|
|
7797
|
-
${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${
|
|
7795
|
+
${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${escapeHtml(snapshot.error)}</p>` : ""}
|
|
7798
7796
|
</section>`;
|
|
7799
7797
|
};
|
|
7800
7798
|
var getVoiceProfileSwitchRecommendationCSS = () => `.absolute-voice-profile-switch{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-profile-switch--switch{border-color:#fdba74}.absolute-voice-profile-switch--stay{border-color:#86efac;background:#f0fdf4}.absolute-voice-profile-switch--warn,.absolute-voice-profile-switch--error{border-color:#fca5a5;background:#fff1f2}.absolute-voice-profile-switch__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-profile-switch__eyebrow{color:#c2410c;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-profile-switch__label{font-size:24px;line-height:1}.absolute-voice-profile-switch__description,.absolute-voice-profile-switch__body em,.absolute-voice-profile-switch__empty{color:#57534e}.absolute-voice-profile-switch__body{background:#fff;border:1px solid #fed7aa;border-radius:16px;margin-top:14px;padding:14px}.absolute-voice-profile-switch__body p{margin:.35rem 0}.absolute-voice-profile-switch__body ul{margin:.75rem 0;padding-left:1.2rem}.absolute-voice-profile-switch__body em{display:block}.absolute-voice-profile-switch__error{color:#9f1239;font-weight:700}`;
|
|
@@ -7949,7 +7947,6 @@ var DEFAULT_LINKS5 = [
|
|
|
7949
7947
|
{ href: "/production-readiness", label: "Readiness page" },
|
|
7950
7948
|
{ href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
|
|
7951
7949
|
];
|
|
7952
|
-
var escapeHtml17 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7953
7950
|
var formatExplanationValue = (value, unit) => {
|
|
7954
7951
|
if (value === undefined || value === null) {
|
|
7955
7952
|
return "n/a";
|
|
@@ -7990,23 +7987,23 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
|
|
|
7990
7987
|
};
|
|
7991
7988
|
var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
|
|
7992
7989
|
const model = createVoiceReadinessFailuresViewModel(snapshot, options);
|
|
7993
|
-
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--${
|
|
7994
|
-
<span>${
|
|
7995
|
-
<strong>${
|
|
7996
|
-
<p>Observed ${
|
|
7997
|
-
<p>${
|
|
7998
|
-
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${
|
|
7999
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ?
|
|
8000
|
-
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${
|
|
8001
|
-
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${
|
|
7990
|
+
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)}">
|
|
7991
|
+
<span>${escapeHtml(failure.status.toUpperCase())}</span>
|
|
7992
|
+
<strong>${escapeHtml(failure.label)}</strong>
|
|
7993
|
+
<p>Observed ${escapeHtml(failure.observed)} against ${escapeHtml(failure.thresholdLabel)} ${escapeHtml(failure.threshold)}.</p>
|
|
7994
|
+
<p>${escapeHtml(failure.remediation)}</p>
|
|
7995
|
+
<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>
|
|
7996
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
|
|
7997
|
+
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>` : "";
|
|
7998
|
+
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml(model.status)}">
|
|
8002
7999
|
<header class="absolute-voice-readiness-failures__header">
|
|
8003
|
-
<span class="absolute-voice-readiness-failures__eyebrow">${
|
|
8004
|
-
<strong class="absolute-voice-readiness-failures__label">${
|
|
8000
|
+
<span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml(model.title)}</span>
|
|
8001
|
+
<strong class="absolute-voice-readiness-failures__label">${escapeHtml(model.label)}</strong>
|
|
8005
8002
|
</header>
|
|
8006
|
-
<p class="absolute-voice-readiness-failures__description">${
|
|
8003
|
+
<p class="absolute-voice-readiness-failures__description">${escapeHtml(model.description)}</p>
|
|
8007
8004
|
${failures}
|
|
8008
8005
|
${links}
|
|
8009
|
-
${model.error ? `<p class="absolute-voice-readiness-failures__error">${
|
|
8006
|
+
${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8010
8007
|
</section>`;
|
|
8011
8008
|
};
|
|
8012
8009
|
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}`;
|
|
@@ -8235,7 +8232,6 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
8235
8232
|
};
|
|
8236
8233
|
|
|
8237
8234
|
// src/client/providerSimulationControlsWidget.ts
|
|
8238
|
-
var escapeHtml18 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8239
8235
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
8240
8236
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
8241
8237
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -8255,18 +8251,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
8255
8251
|
};
|
|
8256
8252
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
8257
8253
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
8258
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
8259
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
8254
|
+
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("");
|
|
8255
|
+
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("");
|
|
8260
8256
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
8261
8257
|
<header class="absolute-voice-provider-simulation__header">
|
|
8262
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
8263
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
8258
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml(model.title)}</span>
|
|
8259
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml(model.label)}</strong>
|
|
8264
8260
|
</header>
|
|
8265
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
8266
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
8261
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml(model.description)}</p>
|
|
8262
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
8267
8263
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
8268
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
8269
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
8264
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml(snapshot.error)}</p>` : ""}
|
|
8265
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml(model.resultText)}</pre>` : ""}
|
|
8270
8266
|
</section>`;
|
|
8271
8267
|
};
|
|
8272
8268
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -8526,7 +8522,6 @@ var useVoiceProviderCapabilities = (path = "/api/provider-capabilities", options
|
|
|
8526
8522
|
// src/client/providerCapabilitiesWidget.ts
|
|
8527
8523
|
var DEFAULT_TITLE13 = "Provider Capabilities";
|
|
8528
8524
|
var DEFAULT_DESCRIPTION13 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
8529
|
-
var escapeHtml19 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8530
8525
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
8531
8526
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
8532
8527
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -8581,25 +8576,25 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
8581
8576
|
};
|
|
8582
8577
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
8583
8578
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
8584
|
-
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--${
|
|
8579
|
+
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)}">
|
|
8585
8580
|
<header>
|
|
8586
|
-
<strong>${
|
|
8587
|
-
<span>${
|
|
8581
|
+
<strong>${escapeHtml(capability.label)}</strong>
|
|
8582
|
+
<span>${escapeHtml(formatStatus3(capability.status))}</span>
|
|
8588
8583
|
</header>
|
|
8589
|
-
<p>${
|
|
8584
|
+
<p>${escapeHtml(capability.detail)}</p>
|
|
8590
8585
|
<dl>${capability.rows.map((row) => `<div>
|
|
8591
|
-
<dt>${
|
|
8592
|
-
<dd>${
|
|
8586
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
8587
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
8593
8588
|
</div>`).join("")}</dl>
|
|
8594
8589
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
8595
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
8590
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml(model.status)}">
|
|
8596
8591
|
<header class="absolute-voice-provider-capabilities__header">
|
|
8597
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
8598
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
8592
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml(model.title)}</span>
|
|
8593
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml(model.label)}</strong>
|
|
8599
8594
|
</header>
|
|
8600
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
8595
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml(model.description)}</p>
|
|
8601
8596
|
${capabilities}
|
|
8602
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
8597
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8603
8598
|
</section>`;
|
|
8604
8599
|
};
|
|
8605
8600
|
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}`;
|
|
@@ -8817,7 +8812,6 @@ var useVoiceProviderContracts = (path = "/api/provider-contracts", options = {})
|
|
|
8817
8812
|
// src/client/providerContractsWidget.ts
|
|
8818
8813
|
var DEFAULT_TITLE14 = "Provider Contracts";
|
|
8819
8814
|
var DEFAULT_DESCRIPTION14 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
8820
|
-
var escapeHtml20 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8821
8815
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
8822
8816
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
8823
8817
|
var contractDetail = (row) => {
|
|
@@ -8861,26 +8855,26 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
8861
8855
|
};
|
|
8862
8856
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
8863
8857
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
8864
|
-
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--${
|
|
8858
|
+
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)}">
|
|
8865
8859
|
<header>
|
|
8866
|
-
<strong>${
|
|
8867
|
-
<span>${
|
|
8860
|
+
<strong>${escapeHtml(row.label)}</strong>
|
|
8861
|
+
<span>${escapeHtml(formatStatus4(row.status))}</span>
|
|
8868
8862
|
</header>
|
|
8869
|
-
<p>${
|
|
8870
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
8863
|
+
<p>${escapeHtml(row.detail)}</p>
|
|
8864
|
+
${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>` : ""}
|
|
8871
8865
|
<dl>${row.rows.map((item) => `<div>
|
|
8872
|
-
<dt>${
|
|
8873
|
-
<dd>${
|
|
8866
|
+
<dt>${escapeHtml(item.label)}</dt>
|
|
8867
|
+
<dd>${escapeHtml(item.value)}</dd>
|
|
8874
8868
|
</div>`).join("")}</dl>
|
|
8875
8869
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
8876
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
8870
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml(model.status)}">
|
|
8877
8871
|
<header class="absolute-voice-provider-contracts__header">
|
|
8878
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
8879
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
8872
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml(model.title)}</span>
|
|
8873
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml(model.label)}</strong>
|
|
8880
8874
|
</header>
|
|
8881
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
8875
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml(model.description)}</p>
|
|
8882
8876
|
${rows}
|
|
8883
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
8877
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8884
8878
|
</section>`;
|
|
8885
8879
|
};
|
|
8886
8880
|
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}`;
|
|
@@ -9119,7 +9113,6 @@ var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
|
9119
9113
|
// src/client/providerStatusWidget.ts
|
|
9120
9114
|
var DEFAULT_TITLE15 = "Voice Providers";
|
|
9121
9115
|
var DEFAULT_DESCRIPTION15 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
9122
|
-
var escapeHtml21 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9123
9116
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
9124
9117
|
var formatStatus5 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
9125
9118
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -9175,25 +9168,25 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
9175
9168
|
};
|
|
9176
9169
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
9177
9170
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
9178
|
-
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--${
|
|
9171
|
+
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)}">
|
|
9179
9172
|
<header>
|
|
9180
|
-
<strong>${
|
|
9181
|
-
<span>${
|
|
9173
|
+
<strong>${escapeHtml(provider.label)}</strong>
|
|
9174
|
+
<span>${escapeHtml(formatStatus5(provider.status))}</span>
|
|
9182
9175
|
</header>
|
|
9183
|
-
<p>${
|
|
9176
|
+
<p>${escapeHtml(provider.detail)}</p>
|
|
9184
9177
|
<dl>${provider.rows.map((row) => `<div>
|
|
9185
|
-
<dt>${
|
|
9186
|
-
<dd>${
|
|
9178
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
9179
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
9187
9180
|
</div>`).join("")}</dl>
|
|
9188
9181
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
9189
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
9182
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml(model.status)}">
|
|
9190
9183
|
<header class="absolute-voice-provider-status__header">
|
|
9191
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
9192
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
9184
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
9185
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml(model.label)}</strong>
|
|
9193
9186
|
</header>
|
|
9194
|
-
<p class="absolute-voice-provider-status__description">${
|
|
9187
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml(model.description)}</p>
|
|
9195
9188
|
${providers}
|
|
9196
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
9189
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9197
9190
|
</section>`;
|
|
9198
9191
|
};
|
|
9199
9192
|
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}`;
|
|
@@ -9416,7 +9409,6 @@ var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
|
9416
9409
|
// src/client/routingStatusWidget.ts
|
|
9417
9410
|
var DEFAULT_TITLE16 = "Voice Routing";
|
|
9418
9411
|
var DEFAULT_DESCRIPTION16 = "Latest provider routing decision from the self-hosted trace store.";
|
|
9419
|
-
var escapeHtml22 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9420
9412
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
9421
9413
|
var formatProviderRoutes2 = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
|
|
9422
9414
|
var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
|
|
@@ -9498,22 +9490,22 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
9498
9490
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
9499
9491
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
9500
9492
|
const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
|
|
9501
|
-
<span>${
|
|
9502
|
-
<strong>${
|
|
9493
|
+
<span>${escapeHtml(item.label)}</span>
|
|
9494
|
+
<strong>${escapeHtml(item.value)}</strong>
|
|
9503
9495
|
</div>`).join("")}</div>` : "";
|
|
9504
9496
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
9505
|
-
<span>${
|
|
9506
|
-
<strong>${
|
|
9497
|
+
<span>${escapeHtml(row.label)}</span>
|
|
9498
|
+
<strong>${escapeHtml(row.value)}</strong>
|
|
9507
9499
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
9508
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
9500
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml(model.status)}">
|
|
9509
9501
|
<header class="absolute-voice-routing-status__header">
|
|
9510
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
9511
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
9502
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
9503
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml(model.label)}</strong>
|
|
9512
9504
|
</header>
|
|
9513
|
-
<p class="absolute-voice-routing-status__description">${
|
|
9505
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml(model.description)}</p>
|
|
9514
9506
|
${activeStack}
|
|
9515
9507
|
${rows}
|
|
9516
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
9508
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9517
9509
|
</section>`;
|
|
9518
9510
|
};
|
|
9519
9511
|
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}}`;
|
|
@@ -9693,7 +9685,6 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
|
|
|
9693
9685
|
// src/client/traceTimelineWidget.ts
|
|
9694
9686
|
var DEFAULT_TITLE17 = "Voice Traces";
|
|
9695
9687
|
var DEFAULT_DESCRIPTION17 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
9696
|
-
var escapeHtml23 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9697
9688
|
var formatMs5 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
9698
9689
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
9699
9690
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -9723,27 +9714,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
9723
9714
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
9724
9715
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
9725
9716
|
const supportLinks = [
|
|
9726
|
-
`<a href="${
|
|
9727
|
-
session.operationsRecordHref ? `<a href="${
|
|
9728
|
-
session.incidentBundleHref ? `<a href="${
|
|
9717
|
+
`<a href="${escapeHtml(session.detailHref)}">Open timeline</a>`,
|
|
9718
|
+
session.operationsRecordHref ? `<a href="${escapeHtml(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
9719
|
+
session.incidentBundleHref ? `<a href="${escapeHtml(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
9729
9720
|
].filter(Boolean).join("");
|
|
9730
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
9721
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml(session.status)}">
|
|
9731
9722
|
<header>
|
|
9732
|
-
<strong>${
|
|
9733
|
-
<span>${
|
|
9723
|
+
<strong>${escapeHtml(session.sessionId)}</strong>
|
|
9724
|
+
<span>${escapeHtml(session.status)}</span>
|
|
9734
9725
|
</header>
|
|
9735
|
-
<p>${
|
|
9726
|
+
<p>${escapeHtml(session.label)} \xB7 ${escapeHtml(session.durationLabel)} \xB7 ${escapeHtml(session.providerLabel)}</p>
|
|
9736
9727
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
9737
9728
|
</article>`;
|
|
9738
9729
|
}).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
9739
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
9730
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml(model.status)}">
|
|
9740
9731
|
<header class="absolute-voice-trace-timeline__header">
|
|
9741
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
9742
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
9732
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml(model.title)}</span>
|
|
9733
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml(model.label)}</strong>
|
|
9743
9734
|
</header>
|
|
9744
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
9735
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml(model.description)}</p>
|
|
9745
9736
|
${sessions}
|
|
9746
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
9737
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9747
9738
|
</section>`;
|
|
9748
9739
|
};
|
|
9749
9740
|
var getVoiceTraceTimelineCSS = () => `.absolute-voice-trace-timeline{border:1px solid #bad7d3;border-radius:20px;background:#f3fffb;color:#09201c;padding:18px;box-shadow:0 18px 40px rgba(9,32,28,.12);font-family:inherit}.absolute-voice-trace-timeline--error,.absolute-voice-trace-timeline--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-trace-timeline--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-trace-timeline__header,.absolute-voice-trace-timeline__session header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-trace-timeline__eyebrow{color:#17665b;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-trace-timeline__label{font-size:24px;line-height:1}.absolute-voice-trace-timeline__description,.absolute-voice-trace-timeline__session p,.absolute-voice-trace-timeline__empty{color:#35544f}.absolute-voice-trace-timeline__sessions{display:grid;gap:12px;margin-top:14px}.absolute-voice-trace-timeline__session{background:#fff;border:1px solid #cfe7e2;border-radius:16px;padding:14px}.absolute-voice-trace-timeline__session--failed{border-color:#f2a7a7}.absolute-voice-trace-timeline__session--warning{border-color:#fbbf24}.absolute-voice-trace-timeline__session p{margin:10px 0}.absolute-voice-trace-timeline__actions{display:flex;flex-wrap:wrap;gap:10px}.absolute-voice-trace-timeline__session a{color:#0f766e;font-weight:800}.absolute-voice-trace-timeline__empty{margin:14px 0 0}.absolute-voice-trace-timeline__error{color:#9f1239;font-weight:700}`;
|
|
@@ -9995,7 +9986,6 @@ var useVoiceAgentSquadStatus = (path = "/api/voice-traces", options = {}) => {
|
|
|
9995
9986
|
// src/client/agentSquadStatusWidget.ts
|
|
9996
9987
|
var DEFAULT_TITLE18 = "Voice Agent Squad";
|
|
9997
9988
|
var DEFAULT_DESCRIPTION18 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
9998
|
-
var escapeHtml24 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9999
9989
|
var labelFor = (current) => {
|
|
10000
9990
|
if (!current)
|
|
10001
9991
|
return "Waiting for specialist activity";
|
|
@@ -10022,24 +10012,24 @@ var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
|
10022
10012
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
10023
10013
|
const current = model.current;
|
|
10024
10014
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
10025
|
-
<span>${
|
|
10026
|
-
<strong>${
|
|
10027
|
-
<em>${
|
|
10028
|
-
${session.summary || session.reason ? `<p>${
|
|
10015
|
+
<span>${escapeHtml(session.sessionId)}</span>
|
|
10016
|
+
<strong>${escapeHtml(session.targetAgentId ?? "none")}</strong>
|
|
10017
|
+
<em>${escapeHtml(session.status)}</em>
|
|
10018
|
+
${session.summary || session.reason ? `<p>${escapeHtml(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
10029
10019
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
10030
10020
|
return `<section class="absolute-voice-agent-squad-status">
|
|
10031
10021
|
<header>
|
|
10032
|
-
<span>${
|
|
10033
|
-
<strong>${
|
|
10022
|
+
<span>${escapeHtml(model.title)}</span>
|
|
10023
|
+
<strong>${escapeHtml(model.label)}</strong>
|
|
10034
10024
|
</header>
|
|
10035
|
-
<p>${
|
|
10025
|
+
<p>${escapeHtml(model.description)}</p>
|
|
10036
10026
|
<div>
|
|
10037
|
-
<span>Session</span><strong>${
|
|
10038
|
-
<span>From</span><strong>${
|
|
10039
|
-
<span>Status</span><strong>${
|
|
10027
|
+
<span>Session</span><strong>${escapeHtml(current?.sessionId ?? "n/a")}</strong>
|
|
10028
|
+
<span>From</span><strong>${escapeHtml(current?.fromAgentId ?? "n/a")}</strong>
|
|
10029
|
+
<span>Status</span><strong>${escapeHtml(current?.status ?? "idle")}</strong>
|
|
10040
10030
|
</div>
|
|
10041
10031
|
<ul>${rows}</ul>
|
|
10042
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
10032
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
10043
10033
|
</section>`;
|
|
10044
10034
|
};
|
|
10045
10035
|
var getVoiceAgentSquadStatusCSS = () => `.absolute-voice-agent-squad-status{border:1px solid #38bdf866;border-radius:20px;background:#0f172a;color:#f8fafc;padding:18px;font-family:inherit}.absolute-voice-agent-squad-status header{display:grid;gap:4px}.absolute-voice-agent-squad-status header span{color:#7dd3fc;font-size:12px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-agent-squad-status header strong{font-size:20px}.absolute-voice-agent-squad-status p{color:#cbd5e1}.absolute-voice-agent-squad-status div{display:grid;gap:6px;grid-template-columns:max-content 1fr;margin:14px 0}.absolute-voice-agent-squad-status div span{color:#94a3b8}.absolute-voice-agent-squad-status ul{display:grid;gap:8px;list-style:none;margin:0;padding:0}.absolute-voice-agent-squad-status li{background:#020617;border:1px solid #1e293b;border-radius:14px;padding:10px}.absolute-voice-agent-squad-status li span{color:#94a3b8;display:block;font-size:12px}.absolute-voice-agent-squad-status li strong{display:block}.absolute-voice-agent-squad-status li em{color:#7dd3fc;font-style:normal}.absolute-voice-agent-squad-status__error{color:#fecaca;font-weight:800}`;
|
|
@@ -10276,7 +10266,6 @@ var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
|
|
|
10276
10266
|
var DEFAULT_TITLE19 = "Turn Latency";
|
|
10277
10267
|
var DEFAULT_DESCRIPTION19 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
10278
10268
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
10279
|
-
var escapeHtml25 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
10280
10269
|
var formatMs6 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
10281
10270
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
10282
10271
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -10304,25 +10293,25 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
10304
10293
|
};
|
|
10305
10294
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
10306
10295
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
10307
|
-
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--${
|
|
10296
|
+
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)}">
|
|
10308
10297
|
<header>
|
|
10309
|
-
<strong>${
|
|
10310
|
-
<span>${
|
|
10298
|
+
<strong>${escapeHtml(turn.label)}</strong>
|
|
10299
|
+
<span>${escapeHtml(turn.status)}</span>
|
|
10311
10300
|
</header>
|
|
10312
10301
|
<dl>${turn.rows.map((row) => `<div>
|
|
10313
|
-
<dt>${
|
|
10314
|
-
<dd>${
|
|
10302
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
10303
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
10315
10304
|
</div>`).join("")}</dl>
|
|
10316
10305
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
10317
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
10306
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml(model.status)}">
|
|
10318
10307
|
<header class="absolute-voice-turn-latency__header">
|
|
10319
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
10320
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
10308
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml(model.title)}</span>
|
|
10309
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml(model.label)}</strong>
|
|
10321
10310
|
</header>
|
|
10322
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
10323
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
10311
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml(model.description)}</p>
|
|
10312
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
10324
10313
|
${turns}
|
|
10325
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
10314
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml(model.error)}</p>` : ""}
|
|
10326
10315
|
</section>`;
|
|
10327
10316
|
};
|
|
10328
10317
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -10558,7 +10547,6 @@ var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
|
10558
10547
|
// src/client/turnQualityWidget.ts
|
|
10559
10548
|
var DEFAULT_TITLE20 = "Turn Quality";
|
|
10560
10549
|
var DEFAULT_DESCRIPTION20 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
10561
|
-
var escapeHtml26 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
10562
10550
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
10563
10551
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
10564
10552
|
var getTurnDetail = (turn) => {
|
|
@@ -10614,25 +10602,25 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
10614
10602
|
};
|
|
10615
10603
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
10616
10604
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
10617
|
-
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--${
|
|
10605
|
+
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)}">
|
|
10618
10606
|
<header>
|
|
10619
|
-
<strong>${
|
|
10620
|
-
<span>${
|
|
10607
|
+
<strong>${escapeHtml(turn.label)}</strong>
|
|
10608
|
+
<span>${escapeHtml(turn.status)}</span>
|
|
10621
10609
|
</header>
|
|
10622
|
-
<p>${
|
|
10610
|
+
<p>${escapeHtml(turn.detail)}</p>
|
|
10623
10611
|
<dl>${turn.rows.map((row) => `<div>
|
|
10624
|
-
<dt>${
|
|
10625
|
-
<dd>${
|
|
10612
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
10613
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
10626
10614
|
</div>`).join("")}</dl>
|
|
10627
10615
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
10628
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
10616
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml(model.status)}">
|
|
10629
10617
|
<header class="absolute-voice-turn-quality__header">
|
|
10630
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
10631
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
10618
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml(model.title)}</span>
|
|
10619
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml(model.label)}</strong>
|
|
10632
10620
|
</header>
|
|
10633
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
10621
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml(model.description)}</p>
|
|
10634
10622
|
${turns}
|
|
10635
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
10623
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml(model.error)}</p>` : ""}
|
|
10636
10624
|
</section>`;
|
|
10637
10625
|
};
|
|
10638
10626
|
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}`;
|
|
@@ -12574,7 +12562,6 @@ var createVoiceWidgetViewModel = (input) => {
|
|
|
12574
12562
|
title: input.title ?? "Voice"
|
|
12575
12563
|
};
|
|
12576
12564
|
};
|
|
12577
|
-
var escapeHtml27 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
12578
12565
|
var resolveRadius = (radius) => typeof radius === "number" ? `${radius}px` : radius;
|
|
12579
12566
|
var renderVoiceWidgetHTML = (model) => {
|
|
12580
12567
|
const t = model.theme;
|
|
@@ -12582,23 +12569,23 @@ var renderVoiceWidgetHTML = (model) => {
|
|
|
12582
12569
|
const dotStyle = `background:${model.errorMessage ? t.errorAccent : model.agentState === "idle" ? "rgba(148,163,184,0.6)" : t.accent};border-radius:50%;height:10px;width:10px;`;
|
|
12583
12570
|
const buttons = [];
|
|
12584
12571
|
if (model.controls.canStart) {
|
|
12585
|
-
buttons.push(`<button type="button" data-action="start" style="background:${t.accent};border:none;border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${
|
|
12572
|
+
buttons.push(`<button type="button" data-action="start" style="background:${t.accent};border:none;border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${escapeHtml(model.labels.startCall)}</button>`);
|
|
12586
12573
|
}
|
|
12587
12574
|
if (model.controls.canMute) {
|
|
12588
|
-
buttons.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${
|
|
12575
|
+
buttons.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${escapeHtml(model.labels.mute)}</button>`);
|
|
12589
12576
|
}
|
|
12590
12577
|
if (model.controls.canEnd) {
|
|
12591
|
-
buttons.push(`<button type="button" data-action="end" style="background:${t.errorAccent};border:none;border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${
|
|
12578
|
+
buttons.push(`<button type="button" data-action="end" style="background:${t.errorAccent};border:none;border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${escapeHtml(model.labels.endCall)}</button>`);
|
|
12592
12579
|
}
|
|
12593
|
-
return `<div role="region" aria-live="polite" data-agent-state="${model.agentState}" class="${
|
|
12580
|
+
return `<div role="region" aria-live="polite" data-agent-state="${model.agentState}" class="${escapeHtml(model.classes.container)}" style="${containerStyle}">
|
|
12594
12581
|
<div style="align-items:center;display:flex;gap:10px;margin-bottom:12px;">
|
|
12595
|
-
<span aria-hidden="true" class="${
|
|
12596
|
-
<strong style="font-size:15px;">${
|
|
12597
|
-
<span style="font-size:13px;margin-left:auto;opacity:0.7;">${
|
|
12582
|
+
<span aria-hidden="true" class="${escapeHtml(model.classes.dot)}" style="${dotStyle}"></span>
|
|
12583
|
+
<strong style="font-size:15px;">${escapeHtml(model.title)}</strong>
|
|
12584
|
+
<span style="font-size:13px;margin-left:auto;opacity:0.7;">${escapeHtml(model.statusLabel)}</span>
|
|
12598
12585
|
</div>
|
|
12599
|
-
${model.partial ? `<p style="font-size:13px;margin:8px 0 12px;opacity:0.85;word-break:break-word;">\u201C${
|
|
12586
|
+
${model.partial ? `<p style="font-size:13px;margin:8px 0 12px;opacity:0.85;word-break:break-word;">\u201C${escapeHtml(model.partial)}\u201D</p>` : ""}
|
|
12600
12587
|
<div style="display:flex;gap:10px;">${buttons.join("")}</div>
|
|
12601
|
-
${model.errorMessage ? `<p style="color:${t.errorAccent};font-size:12px;margin-top:12px;">${
|
|
12588
|
+
${model.errorMessage ? `<p style="color:${t.errorAccent};font-size:12px;margin-top:12px;">${escapeHtml(model.errorMessage)}</p>` : ""}
|
|
12602
12589
|
</div>`;
|
|
12603
12590
|
};
|
|
12604
12591
|
|