@absolutejs/voice 0.0.22-beta.528 → 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 +513 -892
- 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 +57 -62
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/index.js +231 -239
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -2660,11 +2660,13 @@ var createVoiceCallDebuggerStore = (path, options = {}) => {
|
|
|
2660
2660
|
}
|
|
2661
2661
|
};
|
|
2662
2662
|
};
|
|
2663
|
+
// src/internal/html.ts
|
|
2664
|
+
var escapeHtml = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2665
|
+
|
|
2663
2666
|
// src/client/callDebuggerWidget.ts
|
|
2664
2667
|
var DEFAULT_TITLE = "Call Debugger";
|
|
2665
2668
|
var DEFAULT_DESCRIPTION = "Open the latest call artifact with snapshot, operations record, failure replay, provider path, transcript, and incident markdown.";
|
|
2666
2669
|
var DEFAULT_LINK_LABEL = "Open debugger";
|
|
2667
|
-
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2668
2670
|
var defaultHref = (path, report) => {
|
|
2669
2671
|
if (path.startsWith("/api/voice-call-debugger/")) {
|
|
2670
2672
|
return path.replace("/api/voice-call-debugger/", "/voice-call-debugger/");
|
|
@@ -2773,7 +2775,6 @@ var defineVoiceCallDebuggerLaunchElement = (tagName = "absolute-voice-call-debug
|
|
|
2773
2775
|
var DEFAULT_TITLE2 = "Session Snapshot";
|
|
2774
2776
|
var DEFAULT_DESCRIPTION2 = "Portable call artifact with media graph, provider routing, proof, quality, and telephony evidence.";
|
|
2775
2777
|
var DEFAULT_DOWNLOAD_LABEL = "Download snapshot";
|
|
2776
|
-
var escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2777
2778
|
var formatStatus = (status) => status ?? "n/a";
|
|
2778
2779
|
var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
2779
2780
|
const snapshot = state.snapshot;
|
|
@@ -2823,23 +2824,23 @@ var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
|
2823
2824
|
var renderVoiceSessionSnapshotHTML = (state, options = {}) => {
|
|
2824
2825
|
const model = createVoiceSessionSnapshotViewModel(state, options);
|
|
2825
2826
|
const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
|
|
2826
|
-
<dt>${
|
|
2827
|
-
<dd>${
|
|
2827
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
2828
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
2828
2829
|
</div>`).join("")}</dl>` : '<p class="absolute-voice-session-snapshot__empty">Load a session snapshot to see support diagnostics.</p>';
|
|
2829
2830
|
const artifacts = model.artifacts.length ? `<div class="absolute-voice-session-snapshot__artifacts">${model.artifacts.map((artifact) => {
|
|
2830
|
-
const body = `<strong>${
|
|
2831
|
-
return artifact.href ? `<a href="${
|
|
2831
|
+
const body = `<strong>${escapeHtml(artifact.label)}</strong><span>${escapeHtml(artifact.status)}</span>`;
|
|
2832
|
+
return artifact.href ? `<a href="${escapeHtml(artifact.href)}">${body}</a>` : `<div>${body}</div>`;
|
|
2832
2833
|
}).join("")}</div>` : "";
|
|
2833
|
-
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${
|
|
2834
|
+
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${escapeHtml(model.status)}">
|
|
2834
2835
|
<header class="absolute-voice-session-snapshot__header">
|
|
2835
|
-
<span class="absolute-voice-session-snapshot__eyebrow">${
|
|
2836
|
-
<strong class="absolute-voice-session-snapshot__label">${
|
|
2836
|
+
<span class="absolute-voice-session-snapshot__eyebrow">${escapeHtml(model.title)}</span>
|
|
2837
|
+
<strong class="absolute-voice-session-snapshot__label">${escapeHtml(model.label)}</strong>
|
|
2837
2838
|
</header>
|
|
2838
|
-
<p class="absolute-voice-session-snapshot__description">${
|
|
2839
|
-
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${
|
|
2839
|
+
<p class="absolute-voice-session-snapshot__description">${escapeHtml(model.description)}</p>
|
|
2840
|
+
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${escapeHtml(options.downloadLabel ?? DEFAULT_DOWNLOAD_LABEL)}</button>` : ""}
|
|
2840
2841
|
${rows}
|
|
2841
2842
|
${artifacts}
|
|
2842
|
-
${model.error ? `<p class="absolute-voice-session-snapshot__error">${
|
|
2843
|
+
${model.error ? `<p class="absolute-voice-session-snapshot__error">${escapeHtml(model.error)}</p>` : ""}
|
|
2843
2844
|
</section>`;
|
|
2844
2845
|
};
|
|
2845
2846
|
var downloadBlob = (blob, filename) => {
|
|
@@ -2904,7 +2905,6 @@ var defineVoiceSessionSnapshotElement = (tagName = "absolute-voice-session-snaps
|
|
|
2904
2905
|
// src/client/sessionObservabilityWidget.ts
|
|
2905
2906
|
var DEFAULT_TITLE3 = "Session Observability";
|
|
2906
2907
|
var DEFAULT_DESCRIPTION3 = "One support/debug report for a voice call across traces, provider recovery, tools, handoffs, guardrails, turn waterfalls, and incident handoff.";
|
|
2907
|
-
var escapeHtml3 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2908
2908
|
var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
2909
2909
|
var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
|
|
2910
2910
|
const report = snapshot.report;
|
|
@@ -2926,20 +2926,20 @@ var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
|
|
|
2926
2926
|
updatedAt: snapshot.updatedAt
|
|
2927
2927
|
};
|
|
2928
2928
|
};
|
|
2929
|
-
var renderLinks = (links) => links.length ? `<p class="absolute-voice-session-observability__actions">${links.map((link) => `<a href="${
|
|
2929
|
+
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>` : "";
|
|
2930
2930
|
var renderVoiceSessionObservabilityHTML = (snapshot, options = {}) => {
|
|
2931
2931
|
const model = createVoiceSessionObservabilityViewModel(snapshot, options);
|
|
2932
|
-
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>${
|
|
2933
|
-
return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${
|
|
2932
|
+
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>';
|
|
2933
|
+
return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${escapeHtml(model.status)}">
|
|
2934
2934
|
<header class="absolute-voice-session-observability__header">
|
|
2935
|
-
<span class="absolute-voice-session-observability__eyebrow">${
|
|
2936
|
-
<strong class="absolute-voice-session-observability__label">${
|
|
2935
|
+
<span class="absolute-voice-session-observability__eyebrow">${escapeHtml(model.title)}</span>
|
|
2936
|
+
<strong class="absolute-voice-session-observability__label">${escapeHtml(model.label)}</strong>
|
|
2937
2937
|
</header>
|
|
2938
|
-
<p class="absolute-voice-session-observability__description">${
|
|
2939
|
-
${model.sessionId ? `<p class="absolute-voice-session-observability__session">${
|
|
2938
|
+
<p class="absolute-voice-session-observability__description">${escapeHtml(model.description)}</p>
|
|
2939
|
+
${model.sessionId ? `<p class="absolute-voice-session-observability__session">${escapeHtml(model.sessionId)}</p>` : ""}
|
|
2940
2940
|
${renderLinks(model.links)}
|
|
2941
2941
|
${turns}
|
|
2942
|
-
${model.error ? `<p class="absolute-voice-session-observability__error">${
|
|
2942
|
+
${model.error ? `<p class="absolute-voice-session-observability__error">${escapeHtml(model.error)}</p>` : ""}
|
|
2943
2943
|
</section>`;
|
|
2944
2944
|
};
|
|
2945
2945
|
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}`;
|
|
@@ -3698,7 +3698,6 @@ var SURFACE_LABELS = {
|
|
|
3698
3698
|
sessions: "Sessions",
|
|
3699
3699
|
workflows: "Workflows"
|
|
3700
3700
|
};
|
|
3701
|
-
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3702
3701
|
var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
|
|
3703
3702
|
var surfaceDetail = (surface) => {
|
|
3704
3703
|
const total = readNumber(surface, "total");
|
|
@@ -3753,24 +3752,24 @@ var createVoiceOpsStatusViewModel = (snapshot, options = {}) => {
|
|
|
3753
3752
|
};
|
|
3754
3753
|
var renderVoiceOpsStatusHTML = (snapshot, options = {}) => {
|
|
3755
3754
|
const model = createVoiceOpsStatusViewModel(snapshot, options);
|
|
3756
|
-
const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${
|
|
3757
|
-
<span>${
|
|
3758
|
-
<strong>${
|
|
3755
|
+
const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${escapeHtml(surface.status)}">
|
|
3756
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
3757
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
3759
3758
|
</li>`).join("") : '<li class="absolute-voice-ops-status__surface"><span>Status</span><strong>Waiting for first check</strong></li>';
|
|
3760
|
-
const links = model.links.length ? `<nav class="absolute-voice-ops-status__links">${model.links.slice(0, 4).map((link) => `<a href="${
|
|
3761
|
-
return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${
|
|
3759
|
+
const links = model.links.length ? `<nav class="absolute-voice-ops-status__links">${model.links.slice(0, 4).map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join("")}</nav>` : "";
|
|
3760
|
+
return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${escapeHtml(model.status)}">
|
|
3762
3761
|
<header class="absolute-voice-ops-status__header">
|
|
3763
|
-
<span class="absolute-voice-ops-status__eyebrow">${
|
|
3764
|
-
<strong class="absolute-voice-ops-status__label">${
|
|
3762
|
+
<span class="absolute-voice-ops-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
3763
|
+
<strong class="absolute-voice-ops-status__label">${escapeHtml(model.label)}</strong>
|
|
3765
3764
|
</header>
|
|
3766
|
-
<p class="absolute-voice-ops-status__description">${
|
|
3765
|
+
<p class="absolute-voice-ops-status__description">${escapeHtml(model.description)}</p>
|
|
3767
3766
|
<div class="absolute-voice-ops-status__summary">
|
|
3768
3767
|
<span>${model.passed} passing</span>
|
|
3769
3768
|
<span>${Math.max(model.total - model.passed, 0)} failing</span>
|
|
3770
3769
|
<span>${model.total} checks</span>
|
|
3771
3770
|
</div>
|
|
3772
3771
|
<ul class="absolute-voice-ops-status__surfaces">${surfaces}</ul>
|
|
3773
|
-
${model.error ? `<p class="absolute-voice-ops-status__error">${
|
|
3772
|
+
${model.error ? `<p class="absolute-voice-ops-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
3774
3773
|
${links}
|
|
3775
3774
|
</section>`;
|
|
3776
3775
|
};
|
|
@@ -3819,7 +3818,6 @@ var DEFAULT_LINKS = [
|
|
|
3819
3818
|
{ href: "/switching-from-vapi", label: "Switching guide" },
|
|
3820
3819
|
{ href: "/api/voice/vapi-coverage", label: "Coverage JSON" }
|
|
3821
3820
|
];
|
|
3822
|
-
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3823
3821
|
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
3824
3822
|
var surfaceDetail2 = (surface) => {
|
|
3825
3823
|
if (surface.status === "pass") {
|
|
@@ -3856,24 +3854,24 @@ var createVoicePlatformCoverageViewModel = (snapshot, options = {}) => {
|
|
|
3856
3854
|
};
|
|
3857
3855
|
var renderVoicePlatformCoverageHTML = (snapshot, options = {}) => {
|
|
3858
3856
|
const model = createVoicePlatformCoverageViewModel(snapshot, options);
|
|
3859
|
-
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--${
|
|
3857
|
+
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)}">
|
|
3860
3858
|
<header>
|
|
3861
|
-
<strong>${
|
|
3862
|
-
<span>${
|
|
3859
|
+
<strong>${escapeHtml(surface.label)}</strong>
|
|
3860
|
+
<span>${escapeHtml(formatStatus2(surface.status))}</span>
|
|
3863
3861
|
</header>
|
|
3864
|
-
<p>${
|
|
3862
|
+
<p>${escapeHtml(surface.detail)}</p>
|
|
3865
3863
|
<small>${surface.evidence.filter((item) => item.ok).length}/${surface.evidence.length} evidence checks passing</small>
|
|
3866
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-platform-coverage__empty">${model.error ?
|
|
3867
|
-
const links = model.links.length ? `<p class="absolute-voice-platform-coverage__links">${model.links.map((link) => `<a href="${
|
|
3868
|
-
return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${
|
|
3864
|
+
</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>`;
|
|
3865
|
+
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>` : "";
|
|
3866
|
+
return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${escapeHtml(model.status)}">
|
|
3869
3867
|
<header class="absolute-voice-platform-coverage__header">
|
|
3870
|
-
<span class="absolute-voice-platform-coverage__eyebrow">${
|
|
3871
|
-
<strong class="absolute-voice-platform-coverage__label">${
|
|
3868
|
+
<span class="absolute-voice-platform-coverage__eyebrow">${escapeHtml(model.title)}</span>
|
|
3869
|
+
<strong class="absolute-voice-platform-coverage__label">${escapeHtml(model.label)}</strong>
|
|
3872
3870
|
</header>
|
|
3873
|
-
<p class="absolute-voice-platform-coverage__description">${
|
|
3871
|
+
<p class="absolute-voice-platform-coverage__description">${escapeHtml(model.description)}</p>
|
|
3874
3872
|
${surfaces}
|
|
3875
3873
|
${links}
|
|
3876
|
-
${model.error ? `<p class="absolute-voice-platform-coverage__error">${
|
|
3874
|
+
${model.error ? `<p class="absolute-voice-platform-coverage__error">${escapeHtml(model.error)}</p>` : ""}
|
|
3877
3875
|
</section>`;
|
|
3878
3876
|
};
|
|
3879
3877
|
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}`;
|
|
@@ -3916,6 +3914,18 @@ var defineVoicePlatformCoverageElement = (tagName = "absolute-voice-platform-cov
|
|
|
3916
3914
|
// src/proofTrends.ts
|
|
3917
3915
|
import { Elysia as Elysia4 } from "elysia";
|
|
3918
3916
|
|
|
3917
|
+
// src/internal/status.ts
|
|
3918
|
+
var voiceStatusRank = (status) => status === "fail" ? 2 : status === "warn" ? 1 : 0;
|
|
3919
|
+
var worstVoiceStatus = (statuses) => {
|
|
3920
|
+
let worst = "pass";
|
|
3921
|
+
for (const status of statuses) {
|
|
3922
|
+
if (voiceStatusRank(status) > voiceStatusRank(worst)) {
|
|
3923
|
+
worst = status;
|
|
3924
|
+
}
|
|
3925
|
+
}
|
|
3926
|
+
return worst;
|
|
3927
|
+
};
|
|
3928
|
+
|
|
3919
3929
|
// src/providerDecisionTraces.ts
|
|
3920
3930
|
import { Elysia as Elysia3 } from "elysia";
|
|
3921
3931
|
|
|
@@ -4064,16 +4074,15 @@ var summarizeVoiceProviderHealth = async (input) => {
|
|
|
4064
4074
|
}
|
|
4065
4075
|
return summaries;
|
|
4066
4076
|
};
|
|
4067
|
-
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4068
4077
|
var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p class="voice-provider-empty">No provider status yet.</p>' : [
|
|
4069
4078
|
'<div class="voice-provider-health">',
|
|
4070
4079
|
...providers.map((provider) => {
|
|
4071
4080
|
const suppressionSeconds = typeof provider.suppressionRemainingMs === "number" ? Math.ceil(provider.suppressionRemainingMs / 1000) : undefined;
|
|
4072
4081
|
return [
|
|
4073
|
-
`<article class="voice-provider-card ${
|
|
4082
|
+
`<article class="voice-provider-card ${escapeHtml(provider.status)}">`,
|
|
4074
4083
|
'<div class="voice-provider-card-header">',
|
|
4075
|
-
`<strong>${
|
|
4076
|
-
`<span>${
|
|
4084
|
+
`<strong>${escapeHtml(provider.provider)}</strong>`,
|
|
4085
|
+
`<span>${escapeHtml(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>`,
|
|
4077
4086
|
"</div>",
|
|
4078
4087
|
"<dl>",
|
|
4079
4088
|
`<div><dt>Runs</dt><dd>${String(provider.runCount)}</dd></div>`,
|
|
@@ -4083,7 +4092,7 @@ var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p
|
|
|
4083
4092
|
`<div><dt>Fallbacks</dt><dd>${String(provider.fallbackCount)}</dd></div>`,
|
|
4084
4093
|
"</dl>",
|
|
4085
4094
|
suppressionSeconds ? `<p>Temporarily suppressed for ${String(suppressionSeconds)}s.</p>` : "",
|
|
4086
|
-
provider.lastError ? `<p>${
|
|
4095
|
+
provider.lastError ? `<p>${escapeHtml(provider.lastError)}</p>` : "",
|
|
4087
4096
|
"</article>"
|
|
4088
4097
|
].join("");
|
|
4089
4098
|
}),
|
|
@@ -4114,7 +4123,6 @@ var createVoiceProviderHealthRoutes = (options) => {
|
|
|
4114
4123
|
};
|
|
4115
4124
|
|
|
4116
4125
|
// src/resilienceRoutes.ts
|
|
4117
|
-
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4118
4126
|
var getString2 = (value) => typeof value === "string" ? value : undefined;
|
|
4119
4127
|
var getNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
4120
4128
|
var getBoolean = (value) => value === true;
|
|
@@ -4262,13 +4270,13 @@ var summarizeRoutingEvents = (events) => {
|
|
|
4262
4270
|
};
|
|
4263
4271
|
var renderProviderCards = (title, providers) => {
|
|
4264
4272
|
if (providers.length === 0) {
|
|
4265
|
-
return `<p class="muted">No ${
|
|
4273
|
+
return `<p class="muted">No ${escapeHtml(title)} provider health yet.</p>`;
|
|
4266
4274
|
}
|
|
4267
4275
|
return `<div class="provider-grid">${providers.map((provider) => `
|
|
4268
|
-
<article class="card provider ${
|
|
4276
|
+
<article class="card provider ${escapeHtml(provider.status)}">
|
|
4269
4277
|
<div class="card-header">
|
|
4270
|
-
<strong>${
|
|
4271
|
-
<span>${
|
|
4278
|
+
<strong>${escapeHtml(provider.provider)}</strong>
|
|
4279
|
+
<span>${escapeHtml(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
|
|
4272
4280
|
</div>
|
|
4273
4281
|
<dl>
|
|
4274
4282
|
<div><dt>Runs</dt><dd>${provider.runCount}</dd></div>
|
|
@@ -4277,7 +4285,7 @@ var renderProviderCards = (title, providers) => {
|
|
|
4277
4285
|
<div><dt>Timeouts</dt><dd>${provider.timeoutCount}</dd></div>
|
|
4278
4286
|
<div><dt>Fallbacks</dt><dd>${provider.fallbackCount}</dd></div>
|
|
4279
4287
|
</dl>
|
|
4280
|
-
${provider.lastError ? `<p class="muted">${
|
|
4288
|
+
${provider.lastError ? `<p class="muted">${escapeHtml(provider.lastError)}</p>` : ""}
|
|
4281
4289
|
</article>
|
|
4282
4290
|
`).join("")}</div>`;
|
|
4283
4291
|
};
|
|
@@ -4286,24 +4294,24 @@ var renderTimeline = (events) => {
|
|
|
4286
4294
|
return '<p class="muted">No provider routing events yet. Run the app or simulate provider failover.</p>';
|
|
4287
4295
|
}
|
|
4288
4296
|
return `<div class="timeline">${events.slice(0, 40).map((event) => `
|
|
4289
|
-
<article class="card event ${
|
|
4297
|
+
<article class="card event ${escapeHtml(event.status ?? "unknown")}">
|
|
4290
4298
|
<div class="card-header">
|
|
4291
|
-
<strong>${
|
|
4299
|
+
<strong>${escapeHtml(event.kind.toUpperCase())} ${escapeHtml(event.operation ?? "generate")}</strong>
|
|
4292
4300
|
<span>${new Date(event.at).toLocaleString()}</span>
|
|
4293
4301
|
</div>
|
|
4294
4302
|
<p>
|
|
4295
|
-
<span class="pill">${
|
|
4296
|
-
<span class="pill">provider: ${
|
|
4297
|
-
${event.fallbackProvider ? `<span class="pill">fallback: ${
|
|
4303
|
+
<span class="pill">${escapeHtml(event.status ?? "unknown")}</span>
|
|
4304
|
+
<span class="pill">provider: ${escapeHtml(event.provider ?? "unknown")}</span>
|
|
4305
|
+
${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml(event.fallbackProvider)}</span>` : ""}
|
|
4298
4306
|
${event.timedOut ? '<span class="pill danger">timed out</span>' : ""}
|
|
4299
4307
|
</p>
|
|
4300
4308
|
<dl>
|
|
4301
4309
|
<div><dt>Attempt</dt><dd>${event.attempt ?? 0}</dd></div>
|
|
4302
4310
|
<div><dt>Elapsed</dt><dd>${event.elapsedMs ?? 0}ms</dd></div>
|
|
4303
4311
|
<div><dt>Budget</dt><dd>${event.latencyBudgetMs ?? 0}ms</dd></div>
|
|
4304
|
-
<div><dt>Session</dt><dd>${
|
|
4312
|
+
<div><dt>Session</dt><dd>${escapeHtml(event.sessionId)}</dd></div>
|
|
4305
4313
|
</dl>
|
|
4306
|
-
${event.error ? `<p class="muted">${
|
|
4314
|
+
${event.error ? `<p class="muted">${escapeHtml(event.error)}</p>` : ""}
|
|
4307
4315
|
</article>
|
|
4308
4316
|
`).join("")}</div>`;
|
|
4309
4317
|
};
|
|
@@ -4313,9 +4321,9 @@ var renderSessionKind = (kind, summary) => {
|
|
|
4313
4321
|
const status = latest?.status ?? "idle";
|
|
4314
4322
|
const fallback = latest?.fallbackProvider && latest.fallbackProvider !== provider ? ` -> ${latest.fallbackProvider}` : "";
|
|
4315
4323
|
return `<div>
|
|
4316
|
-
<dt>${
|
|
4317
|
-
<dd>${
|
|
4318
|
-
<small>${
|
|
4324
|
+
<dt>${escapeHtml(kind.toUpperCase())}</dt>
|
|
4325
|
+
<dd>${escapeHtml(provider)}${escapeHtml(fallback)}</dd>
|
|
4326
|
+
<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>
|
|
4319
4327
|
</div>`;
|
|
4320
4328
|
};
|
|
4321
4329
|
var renderSessionSummaries = (sessions) => {
|
|
@@ -4323,10 +4331,10 @@ var renderSessionSummaries = (sessions) => {
|
|
|
4323
4331
|
return '<p class="muted">No call-level routing summaries yet. Run a voice session or provider simulation.</p>';
|
|
4324
4332
|
}
|
|
4325
4333
|
return `<div class="session-grid">${sessions.slice(0, 12).map((session) => `
|
|
4326
|
-
<article class="card session ${
|
|
4334
|
+
<article class="card session ${escapeHtml(session.status)}">
|
|
4327
4335
|
<div class="card-header">
|
|
4328
|
-
<strong>${
|
|
4329
|
-
<span>${
|
|
4336
|
+
<strong>${escapeHtml(session.sessionId)}</strong>
|
|
4337
|
+
<span>${escapeHtml(session.status)}</span>
|
|
4330
4338
|
</div>
|
|
4331
4339
|
<p>
|
|
4332
4340
|
<span class="pill">${session.eventCount} routing events</span>
|
|
@@ -4353,21 +4361,21 @@ var renderSimulationControls = (kind, simulation) => {
|
|
|
4353
4361
|
const pathPrefix = simulation.pathPrefix ?? `/api/${kind}-simulate`;
|
|
4354
4362
|
const failureProviders = simulation.failureProviders ?? configuredProviders.map(({ provider }) => provider);
|
|
4355
4363
|
const canFail = (provider) => configuredProviders.some((entry) => entry.provider === provider) && (!simulation.fallbackRequiredProvider || configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider));
|
|
4356
|
-
return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${
|
|
4357
|
-
<p class="muted">${
|
|
4364
|
+
return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml(pathPrefix)}">
|
|
4365
|
+
<p class="muted">${escapeHtml(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
|
|
4358
4366
|
<div class="simulate-actions">
|
|
4359
|
-
${failureProviders.map((provider) => `<button type="button" data-provider-fail="${
|
|
4360
|
-
${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${
|
|
4367
|
+
${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
|
|
4368
|
+
${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml(provider.provider)}">Mark ${escapeHtml(provider.provider)} recovered</button>`).join("")}
|
|
4361
4369
|
</div>
|
|
4362
|
-
${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${
|
|
4370
|
+
${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
|
|
4363
4371
|
<pre class="simulate-output" hidden></pre>
|
|
4364
4372
|
</div>`;
|
|
4365
4373
|
};
|
|
4366
4374
|
var renderVoiceResilienceHTML = (input) => {
|
|
4367
4375
|
const summary = summarizeRoutingEvents(input.routingEvents);
|
|
4368
|
-
const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${
|
|
4369
|
-
const links = input.links?.length ? input.links.map((link) => `<a href="${
|
|
4370
|
-
const snippet =
|
|
4376
|
+
const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml(kind)}: ${String(count)}</span>`).join("");
|
|
4377
|
+
const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml(link.href)}">${escapeHtml(link.label)}</a>`).join(" \xB7 ") : "";
|
|
4378
|
+
const snippet = escapeHtml(`const sttSimulator = createVoiceIOProviderFailureSimulator({
|
|
4371
4379
|
kind: 'stt',
|
|
4372
4380
|
providers: ['deepgram', 'assemblyai'],
|
|
4373
4381
|
fallback: ['deepgram', 'assemblyai'],
|
|
@@ -4405,7 +4413,7 @@ app.use(
|
|
|
4405
4413
|
<head>
|
|
4406
4414
|
<meta charset="utf-8" />
|
|
4407
4415
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
4408
|
-
<title>${
|
|
4416
|
+
<title>${escapeHtml(input.title ?? "AbsoluteJS Voice Resilience")}</title>
|
|
4409
4417
|
<style>
|
|
4410
4418
|
:root { color-scheme: dark; }
|
|
4411
4419
|
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; }
|
|
@@ -4598,7 +4606,6 @@ var createVoiceResilienceRoutes = (options) => {
|
|
|
4598
4606
|
};
|
|
4599
4607
|
|
|
4600
4608
|
// src/providerDecisionTraces.ts
|
|
4601
|
-
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4602
4609
|
var getString3 = (value) => typeof value === "string" ? value : undefined;
|
|
4603
4610
|
var getNumber3 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
4604
4611
|
var isDecisionTrace = (event) => Boolean(event && typeof event === "object" && "provider" in event && "reason" in event && "sessionId" in event && "status" in event && "surface" in event);
|
|
@@ -4613,8 +4620,7 @@ var surfaceForKind = (kind) => {
|
|
|
4613
4620
|
return "live-call";
|
|
4614
4621
|
}
|
|
4615
4622
|
};
|
|
4616
|
-
var
|
|
4617
|
-
var reportStatus = (issues) => issues.reduce((status, issue) => statusRank[issue.status] > statusRank[status] ? issue.status : status, "pass");
|
|
4623
|
+
var reportStatus = (issues) => worstVoiceStatus(issues.map((issue) => issue.status));
|
|
4618
4624
|
var uniqueSorted = (values) => [
|
|
4619
4625
|
...new Set(values.filter((value) => typeof value === "string"))
|
|
4620
4626
|
].sort();
|
|
@@ -4839,7 +4845,7 @@ var renderVoiceProviderDecisionTraceHTML = (report, title = "Provider Decision T
|
|
|
4839
4845
|
<head>
|
|
4840
4846
|
<meta charset="utf-8" />
|
|
4841
4847
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
4842
|
-
<title>${
|
|
4848
|
+
<title>${escapeHtml(title)}</title>
|
|
4843
4849
|
<style>
|
|
4844
4850
|
body{font-family:ui-sans-serif,system-ui,sans-serif;margin:0;background:#f8fafc;color:#0f172a}
|
|
4845
4851
|
main{max-width:1100px;margin:0 auto;padding:32px}
|
|
@@ -4853,8 +4859,8 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
|
|
|
4853
4859
|
</head>
|
|
4854
4860
|
<body>
|
|
4855
4861
|
<main>
|
|
4856
|
-
<p class="status ${report.status}">${
|
|
4857
|
-
<h1>${
|
|
4862
|
+
<p class="status ${report.status}">${escapeHtml(report.status)}</p>
|
|
4863
|
+
<h1>${escapeHtml(title)}</h1>
|
|
4858
4864
|
<p class="muted">Runtime proof for why providers were selected, skipped, failed, or recovered by fallback.</p>
|
|
4859
4865
|
<section class="grid">
|
|
4860
4866
|
<article class="card"><strong>${String(report.summary.decisions)}</strong><p>decisions</p></article>
|
|
@@ -4865,10 +4871,10 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
|
|
|
4865
4871
|
</section>
|
|
4866
4872
|
<section class="surfaces">
|
|
4867
4873
|
${report.surfaces.map((surface) => `<article class="surface">
|
|
4868
|
-
<header><strong>${
|
|
4874
|
+
<header><strong>${escapeHtml(surface.surface)}</strong> <span class="status ${surface.status}">${escapeHtml(surface.status)}</span></header>
|
|
4869
4875
|
<p>${String(surface.decisions)} decision(s), ${String(surface.fallbacks)} fallback(s), ${String(surface.degraded)} degraded decision(s), ${String(surface.errors)} error(s).</p>
|
|
4870
|
-
<p class="muted">Providers: ${
|
|
4871
|
-
<p>${surface.reasons.map((reason) => `<code>${
|
|
4876
|
+
<p class="muted">Providers: ${escapeHtml(surface.providers.join(", ") || "none")}</p>
|
|
4877
|
+
<p>${surface.reasons.map((reason) => `<code>${escapeHtml(reason)}</code>`).join(" ")}</p>
|
|
4872
4878
|
</article>`).join(`
|
|
4873
4879
|
`)}
|
|
4874
4880
|
</section>
|
|
@@ -5386,7 +5392,6 @@ var exportVoiceTrace = async (input) => {
|
|
|
5386
5392
|
};
|
|
5387
5393
|
};
|
|
5388
5394
|
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
5389
|
-
var escapeHtml9 = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5390
5395
|
var formatTraceValue = (value) => {
|
|
5391
5396
|
if (value === undefined || value === null) {
|
|
5392
5397
|
return "";
|
|
@@ -5670,10 +5675,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5670
5675
|
const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
|
|
5671
5676
|
return [
|
|
5672
5677
|
"<tr>",
|
|
5673
|
-
`<td>${
|
|
5674
|
-
`<td>${
|
|
5675
|
-
`<td>${
|
|
5676
|
-
`<td><code>${
|
|
5678
|
+
`<td>${escapeHtml(String(offset))}</td>`,
|
|
5679
|
+
`<td>${escapeHtml(event.type)}</td>`,
|
|
5680
|
+
`<td>${escapeHtml(event.turnId ?? "")}</td>`,
|
|
5681
|
+
`<td><code>${escapeHtml(JSON.stringify(event.payload))}</code></td>`,
|
|
5677
5682
|
"</tr>"
|
|
5678
5683
|
].join("");
|
|
5679
5684
|
}).join(`
|
|
@@ -5684,7 +5689,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5684
5689
|
"<head>",
|
|
5685
5690
|
'<meta charset="utf-8" />',
|
|
5686
5691
|
'<meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
5687
|
-
`<title>${
|
|
5692
|
+
`<title>${escapeHtml(options.title ?? "Voice Trace")}</title>`,
|
|
5688
5693
|
"<style>",
|
|
5689
5694
|
"body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
|
|
5690
5695
|
"main{max-width:1100px;margin:auto}",
|
|
@@ -5698,7 +5703,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5698
5703
|
"</style>",
|
|
5699
5704
|
"</head>",
|
|
5700
5705
|
"<body><main>",
|
|
5701
|
-
`<h1>${
|
|
5706
|
+
`<h1>${escapeHtml(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
|
|
5702
5707
|
`<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
|
|
5703
5708
|
'<section class="summary">',
|
|
5704
5709
|
`<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
|
|
@@ -5712,7 +5717,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5712
5717
|
eventRows,
|
|
5713
5718
|
"</tbody></table>",
|
|
5714
5719
|
"<h2>Markdown Export</h2>",
|
|
5715
|
-
`<pre>${
|
|
5720
|
+
`<pre>${escapeHtml(markdown)}</pre>`,
|
|
5716
5721
|
"</main></body></html>"
|
|
5717
5722
|
].join(`
|
|
5718
5723
|
`);
|
|
@@ -8091,7 +8096,6 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
8091
8096
|
}
|
|
8092
8097
|
};
|
|
8093
8098
|
};
|
|
8094
|
-
var escapeHtml10 = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8095
8099
|
var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
|
|
8096
8100
|
var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provider Runtime Recommendations") => [
|
|
8097
8101
|
`# ${title}`,
|
|
@@ -8126,11 +8130,11 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
|
|
|
8126
8130
|
].join(`
|
|
8127
8131
|
`);
|
|
8128
8132
|
var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider Runtime Recommendations") => {
|
|
8129
|
-
const cards = report.recommendations.map((recommendation) => `<article class="${
|
|
8130
|
-
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
8131
|
-
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${
|
|
8132
|
-
const profileRows = report.profiles.length === 0 ? "<li>No benchmark profiles were present.</li>" : report.profiles.map((profile) => `<li><strong>${
|
|
8133
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
8133
|
+
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("");
|
|
8134
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
8135
|
+
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("");
|
|
8136
|
+
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("");
|
|
8137
|
+
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>`;
|
|
8134
8138
|
};
|
|
8135
8139
|
var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Call Profile History") => [
|
|
8136
8140
|
`# ${title}`,
|
|
@@ -8164,11 +8168,11 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
|
|
|
8164
8168
|
].join(`
|
|
8165
8169
|
`);
|
|
8166
8170
|
var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
|
|
8167
|
-
const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${
|
|
8168
|
-
const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${
|
|
8169
|
-
const recommendations = report.recommendations.recommendations.map((recommendation) => `<article class="${
|
|
8170
|
-
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
8171
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
8171
|
+
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>';
|
|
8172
|
+
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>';
|
|
8173
|
+
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("");
|
|
8174
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
8175
|
+
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>`;
|
|
8172
8176
|
};
|
|
8173
8177
|
var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Call Evidence Runtime") => [
|
|
8174
8178
|
`# ${title}`,
|
|
@@ -8191,9 +8195,9 @@ var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Ca
|
|
|
8191
8195
|
].join(`
|
|
8192
8196
|
`);
|
|
8193
8197
|
var renderVoiceRealCallEvidenceRuntimeHTML = (report, title = "Voice Real-Call Evidence Runtime") => {
|
|
8194
|
-
const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${
|
|
8195
|
-
const profileRows = report.history.summary.profiles?.length ? report.history.summary.profiles.map((profile) => `<tr><td>${
|
|
8196
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
8198
|
+
const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml(issue)}</li>`).join("");
|
|
8199
|
+
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>';
|
|
8200
|
+
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>`;
|
|
8197
8201
|
};
|
|
8198
8202
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
8199
8203
|
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
|
@@ -8551,7 +8555,6 @@ var DEFAULT_LINKS2 = [
|
|
|
8551
8555
|
{ href: "/voice/proof-trends", label: "Trend page" },
|
|
8552
8556
|
{ href: "/api/voice/proof-trends", label: "Trend JSON" }
|
|
8553
8557
|
];
|
|
8554
|
-
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8555
8558
|
var formatMs2 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
8556
8559
|
var statusLabel = (report) => {
|
|
8557
8560
|
if (!report) {
|
|
@@ -8601,19 +8604,19 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
|
|
|
8601
8604
|
var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
|
|
8602
8605
|
const model = createVoiceProofTrendsViewModel(snapshot, options);
|
|
8603
8606
|
const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
|
|
8604
|
-
<span>${
|
|
8605
|
-
<strong>${
|
|
8606
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ?
|
|
8607
|
-
const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${
|
|
8608
|
-
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${
|
|
8607
|
+
<span>${escapeHtml(metric.label)}</span>
|
|
8608
|
+
<strong>${escapeHtml(metric.value)}</strong>
|
|
8609
|
+
</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>`;
|
|
8610
|
+
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>` : "";
|
|
8611
|
+
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml(model.status)}">
|
|
8609
8612
|
<header class="absolute-voice-proof-trends__header">
|
|
8610
|
-
<span class="absolute-voice-proof-trends__eyebrow">${
|
|
8611
|
-
<strong class="absolute-voice-proof-trends__label">${
|
|
8613
|
+
<span class="absolute-voice-proof-trends__eyebrow">${escapeHtml(model.title)}</span>
|
|
8614
|
+
<strong class="absolute-voice-proof-trends__label">${escapeHtml(model.label)}</strong>
|
|
8612
8615
|
</header>
|
|
8613
|
-
<p class="absolute-voice-proof-trends__description">${
|
|
8616
|
+
<p class="absolute-voice-proof-trends__description">${escapeHtml(model.description)}</p>
|
|
8614
8617
|
${metrics}
|
|
8615
8618
|
${links}
|
|
8616
|
-
${model.error ? `<p class="absolute-voice-proof-trends__error">${
|
|
8619
|
+
${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8617
8620
|
</section>`;
|
|
8618
8621
|
};
|
|
8619
8622
|
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}`;
|
|
@@ -8662,7 +8665,6 @@ var DEFAULT_LINKS3 = [
|
|
|
8662
8665
|
label: "Profile history JSON"
|
|
8663
8666
|
}
|
|
8664
8667
|
];
|
|
8665
|
-
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8666
8668
|
var formatMs3 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
8667
8669
|
var formatCount = (value) => new Intl.NumberFormat("en-US").format(value);
|
|
8668
8670
|
var formatAge = (value) => {
|
|
@@ -8717,21 +8719,21 @@ var createVoiceReconnectProfileEvidenceViewModel = (snapshot, options = {}) => {
|
|
|
8717
8719
|
var renderVoiceReconnectProfileEvidenceHTML = (snapshot, options = {}) => {
|
|
8718
8720
|
const model = createVoiceReconnectProfileEvidenceViewModel(snapshot, options);
|
|
8719
8721
|
const metrics = `<div class="absolute-voice-reconnect-evidence__metrics">${model.metrics.map((metric) => `<article>
|
|
8720
|
-
<span>${
|
|
8721
|
-
<strong>${
|
|
8722
|
+
<span>${escapeHtml(metric.label)}</span>
|
|
8723
|
+
<strong>${escapeHtml(metric.value)}</strong>
|
|
8722
8724
|
</article>`).join("")}</div>`;
|
|
8723
|
-
const latest = model.latest ? `<p class="absolute-voice-reconnect-evidence__latest">Latest ${
|
|
8724
|
-
const links = model.links.length ? `<p class="absolute-voice-reconnect-evidence__links">${model.links.map((link) => `<a href="${
|
|
8725
|
-
return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${
|
|
8725
|
+
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>`;
|
|
8726
|
+
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>` : "";
|
|
8727
|
+
return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${escapeHtml(model.status)}">
|
|
8726
8728
|
<header class="absolute-voice-reconnect-evidence__header">
|
|
8727
|
-
<span class="absolute-voice-reconnect-evidence__eyebrow">${
|
|
8728
|
-
<strong class="absolute-voice-reconnect-evidence__label">${
|
|
8729
|
+
<span class="absolute-voice-reconnect-evidence__eyebrow">${escapeHtml(model.title)}</span>
|
|
8730
|
+
<strong class="absolute-voice-reconnect-evidence__label">${escapeHtml(model.label)}</strong>
|
|
8729
8731
|
</header>
|
|
8730
|
-
<p class="absolute-voice-reconnect-evidence__description">${
|
|
8732
|
+
<p class="absolute-voice-reconnect-evidence__description">${escapeHtml(model.description)}</p>
|
|
8731
8733
|
${metrics}
|
|
8732
8734
|
${latest}
|
|
8733
8735
|
${links}
|
|
8734
|
-
${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${
|
|
8736
|
+
${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8735
8737
|
</section>`;
|
|
8736
8738
|
};
|
|
8737
8739
|
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))}}`;
|
|
@@ -8778,7 +8780,6 @@ var DEFAULT_LINKS4 = [
|
|
|
8778
8780
|
{ href: "/voice/real-call-profile-history", label: "Profile history" },
|
|
8779
8781
|
{ href: "/api/voice/real-call-profile-history", label: "JSON" }
|
|
8780
8782
|
];
|
|
8781
|
-
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8782
8783
|
var formatMs4 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
8783
8784
|
var formatProviderRoutes = (profile) => Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "No complete route yet";
|
|
8784
8785
|
var createProfileView = (profile) => ({
|
|
@@ -8809,25 +8810,25 @@ var createVoiceProfileComparisonViewModel = (snapshot, options = {}) => {
|
|
|
8809
8810
|
};
|
|
8810
8811
|
var renderVoiceProfileComparisonHTML = (snapshot, options = {}) => {
|
|
8811
8812
|
const model = createVoiceProfileComparisonViewModel(snapshot, options);
|
|
8812
|
-
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--${
|
|
8813
|
+
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)}">
|
|
8813
8814
|
<header>
|
|
8814
|
-
<span>${
|
|
8815
|
-
<strong>${
|
|
8815
|
+
<span>${escapeHtml(profile.status)}</span>
|
|
8816
|
+
<strong>${escapeHtml(profile.label)}</strong>
|
|
8816
8817
|
</header>
|
|
8817
|
-
<p>${
|
|
8818
|
-
<div>${profile.evidence.map((metric) => `<span><small>${
|
|
8819
|
-
<em>${
|
|
8820
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ?
|
|
8821
|
-
const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${
|
|
8822
|
-
return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${
|
|
8818
|
+
<p>${escapeHtml(profile.providerRoutes)}</p>
|
|
8819
|
+
<div>${profile.evidence.map((metric) => `<span><small>${escapeHtml(metric.label)}</small><b>${escapeHtml(metric.value)}</b></span>`).join("")}</div>
|
|
8820
|
+
<em>${escapeHtml(profile.nextMove)}</em>
|
|
8821
|
+
</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>`;
|
|
8822
|
+
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>` : "";
|
|
8823
|
+
return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${escapeHtml(model.status)}">
|
|
8823
8824
|
<header class="absolute-voice-profile-comparison__header">
|
|
8824
|
-
<span class="absolute-voice-profile-comparison__eyebrow">${
|
|
8825
|
-
<strong class="absolute-voice-profile-comparison__label">${
|
|
8825
|
+
<span class="absolute-voice-profile-comparison__eyebrow">${escapeHtml(model.title)}</span>
|
|
8826
|
+
<strong class="absolute-voice-profile-comparison__label">${escapeHtml(model.label)}</strong>
|
|
8826
8827
|
</header>
|
|
8827
|
-
<p class="absolute-voice-profile-comparison__description">${
|
|
8828
|
+
<p class="absolute-voice-profile-comparison__description">${escapeHtml(model.description)}</p>
|
|
8828
8829
|
${profiles}
|
|
8829
8830
|
${links}
|
|
8830
|
-
${model.error ? `<p class="absolute-voice-profile-comparison__error">${
|
|
8831
|
+
${model.error ? `<p class="absolute-voice-profile-comparison__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8831
8832
|
</section>`;
|
|
8832
8833
|
};
|
|
8833
8834
|
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}`;
|
|
@@ -8870,27 +8871,26 @@ var defineVoiceProfileComparisonElement = (tagName = "absolute-voice-profile-com
|
|
|
8870
8871
|
// src/client/profileSwitchRecommendationWidget.ts
|
|
8871
8872
|
var DEFAULT_TITLE9 = "Profile Switch Recommendation";
|
|
8872
8873
|
var DEFAULT_DESCRIPTION9 = "Compares the current session against measured profile evidence and recommends whether to switch stacks.";
|
|
8873
|
-
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8874
8874
|
var formatRoute = (routes) => routes ? Object.entries(routes).map(([role, provider]) => `${role}: ${provider}`).join(", ") : "No route";
|
|
8875
8875
|
var renderVoiceProfileSwitchRecommendationHTML = (snapshot, options = {}) => {
|
|
8876
8876
|
const recommendation = snapshot.recommendation;
|
|
8877
8877
|
const status = snapshot.error ? "error" : recommendation ? recommendation.status : snapshot.isLoading ? "loading" : "empty";
|
|
8878
8878
|
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";
|
|
8879
8879
|
const body = recommendation ? `<div class="absolute-voice-profile-switch__body">
|
|
8880
|
-
<p><strong>Current:</strong> ${
|
|
8881
|
-
<p><strong>Recommended:</strong> ${
|
|
8882
|
-
<p><strong>Routes:</strong> ${
|
|
8883
|
-
<ul>${recommendation.reasons.map((reason) => `<li>${
|
|
8884
|
-
<em>${
|
|
8885
|
-
</div>` : `<p class="absolute-voice-profile-switch__empty">${
|
|
8886
|
-
return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${
|
|
8880
|
+
<p><strong>Current:</strong> ${escapeHtml(recommendation.currentProfile?.label ?? recommendation.currentProfile?.profileId ?? "Unknown")}</p>
|
|
8881
|
+
<p><strong>Recommended:</strong> ${escapeHtml(recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "None")}</p>
|
|
8882
|
+
<p><strong>Routes:</strong> ${escapeHtml(formatRoute(recommendation.recommendedProfile?.providerRoutes))}</p>
|
|
8883
|
+
<ul>${recommendation.reasons.map((reason) => `<li>${escapeHtml(reason)}</li>`).join("")}</ul>
|
|
8884
|
+
<em>${escapeHtml(recommendation.nextMove)}</em>
|
|
8885
|
+
</div>` : `<p class="absolute-voice-profile-switch__empty">${escapeHtml(snapshot.error ?? "Run session traffic to populate a recommendation.")}</p>`;
|
|
8886
|
+
return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${escapeHtml(status)}">
|
|
8887
8887
|
<header class="absolute-voice-profile-switch__header">
|
|
8888
|
-
<span class="absolute-voice-profile-switch__eyebrow">${
|
|
8889
|
-
<strong class="absolute-voice-profile-switch__label">${
|
|
8888
|
+
<span class="absolute-voice-profile-switch__eyebrow">${escapeHtml(options.title ?? DEFAULT_TITLE9)}</span>
|
|
8889
|
+
<strong class="absolute-voice-profile-switch__label">${escapeHtml(label)}</strong>
|
|
8890
8890
|
</header>
|
|
8891
|
-
<p class="absolute-voice-profile-switch__description">${
|
|
8891
|
+
<p class="absolute-voice-profile-switch__description">${escapeHtml(options.description ?? DEFAULT_DESCRIPTION9)}</p>
|
|
8892
8892
|
${body}
|
|
8893
|
-
${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${
|
|
8893
|
+
${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${escapeHtml(snapshot.error)}</p>` : ""}
|
|
8894
8894
|
</section>`;
|
|
8895
8895
|
};
|
|
8896
8896
|
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}`;
|
|
@@ -8937,7 +8937,6 @@ var DEFAULT_LINKS5 = [
|
|
|
8937
8937
|
{ href: "/production-readiness", label: "Readiness page" },
|
|
8938
8938
|
{ href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
|
|
8939
8939
|
];
|
|
8940
|
-
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8941
8940
|
var formatExplanationValue = (value, unit) => {
|
|
8942
8941
|
if (value === undefined || value === null) {
|
|
8943
8942
|
return "n/a";
|
|
@@ -8978,23 +8977,23 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
|
|
|
8978
8977
|
};
|
|
8979
8978
|
var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
|
|
8980
8979
|
const model = createVoiceReadinessFailuresViewModel(snapshot, options);
|
|
8981
|
-
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--${
|
|
8982
|
-
<span>${
|
|
8983
|
-
<strong>${
|
|
8984
|
-
<p>Observed ${
|
|
8985
|
-
<p>${
|
|
8986
|
-
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${
|
|
8987
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ?
|
|
8988
|
-
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${
|
|
8989
|
-
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${
|
|
8980
|
+
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)}">
|
|
8981
|
+
<span>${escapeHtml(failure.status.toUpperCase())}</span>
|
|
8982
|
+
<strong>${escapeHtml(failure.label)}</strong>
|
|
8983
|
+
<p>Observed ${escapeHtml(failure.observed)} against ${escapeHtml(failure.thresholdLabel)} ${escapeHtml(failure.threshold)}.</p>
|
|
8984
|
+
<p>${escapeHtml(failure.remediation)}</p>
|
|
8985
|
+
<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>
|
|
8986
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
|
|
8987
|
+
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>` : "";
|
|
8988
|
+
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml(model.status)}">
|
|
8990
8989
|
<header class="absolute-voice-readiness-failures__header">
|
|
8991
|
-
<span class="absolute-voice-readiness-failures__eyebrow">${
|
|
8992
|
-
<strong class="absolute-voice-readiness-failures__label">${
|
|
8990
|
+
<span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml(model.title)}</span>
|
|
8991
|
+
<strong class="absolute-voice-readiness-failures__label">${escapeHtml(model.label)}</strong>
|
|
8993
8992
|
</header>
|
|
8994
|
-
<p class="absolute-voice-readiness-failures__description">${
|
|
8993
|
+
<p class="absolute-voice-readiness-failures__description">${escapeHtml(model.description)}</p>
|
|
8995
8994
|
${failures}
|
|
8996
8995
|
${links}
|
|
8997
|
-
${model.error ? `<p class="absolute-voice-readiness-failures__error">${
|
|
8996
|
+
${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml(model.error)}</p>` : ""}
|
|
8998
8997
|
</section>`;
|
|
8999
8998
|
};
|
|
9000
8999
|
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}`;
|
|
@@ -9036,7 +9035,6 @@ var defineVoiceReadinessFailuresElement = (tagName = "absolute-voice-readiness-f
|
|
|
9036
9035
|
// src/client/opsActionCenterWidget.ts
|
|
9037
9036
|
var DEFAULT_TITLE11 = "Voice Ops Action Center";
|
|
9038
9037
|
var DEFAULT_DESCRIPTION11 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
9039
|
-
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9040
9038
|
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
9041
9039
|
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
9042
9040
|
return {
|
|
@@ -9058,18 +9056,18 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
|
9058
9056
|
};
|
|
9059
9057
|
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
9060
9058
|
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
9061
|
-
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${
|
|
9062
|
-
${
|
|
9059
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
9060
|
+
${escapeHtml(action.isRunning ? "Working..." : action.label)}
|
|
9063
9061
|
</button>`).join("");
|
|
9064
|
-
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${
|
|
9062
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml(model.status)}">
|
|
9065
9063
|
<header class="absolute-voice-ops-action-center__header">
|
|
9066
|
-
<span class="absolute-voice-ops-action-center__eyebrow">${
|
|
9067
|
-
<strong class="absolute-voice-ops-action-center__label">${
|
|
9064
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml(model.title)}</span>
|
|
9065
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml(model.label)}</strong>
|
|
9068
9066
|
</header>
|
|
9069
|
-
<p class="absolute-voice-ops-action-center__description">${
|
|
9067
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml(model.description)}</p>
|
|
9070
9068
|
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
9071
|
-
<p class="absolute-voice-ops-action-center__result">${
|
|
9072
|
-
${model.error ? `<p class="absolute-voice-ops-action-center__error">${
|
|
9069
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml(model.lastResultLabel)}</p>
|
|
9070
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9073
9071
|
</section>`;
|
|
9074
9072
|
};
|
|
9075
9073
|
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}`;
|
|
@@ -9668,7 +9666,6 @@ var ACTION_LABELS = {
|
|
|
9668
9666
|
"resume-assistant": "Resume assistant",
|
|
9669
9667
|
tag: "Tag"
|
|
9670
9668
|
};
|
|
9671
|
-
var escapeHtml17 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9672
9669
|
var createVoiceLiveOpsInput = (action, input) => ({
|
|
9673
9670
|
action,
|
|
9674
9671
|
assignee: input.assignee,
|
|
@@ -9679,17 +9676,17 @@ var createVoiceLiveOpsInput = (action, input) => ({
|
|
|
9679
9676
|
var renderVoiceLiveOpsHTML = (snapshot, options = {}) => {
|
|
9680
9677
|
const sessionId = options.getSessionId?.() ?? "";
|
|
9681
9678
|
const disabled = snapshot.isRunning || !sessionId;
|
|
9682
|
-
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${
|
|
9683
|
-
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${
|
|
9679
|
+
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml(action)}"${disabled ? " disabled" : ""}>${escapeHtml(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
|
|
9680
|
+
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml(snapshot.lastResult.action)}. Control: ${escapeHtml(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
|
|
9684
9681
|
return `<section class="absolute-voice-live-ops">
|
|
9685
9682
|
<header class="absolute-voice-live-ops__header">
|
|
9686
|
-
<span>${
|
|
9687
|
-
<strong>${
|
|
9683
|
+
<span>${escapeHtml(options.title ?? "Live Ops")}</span>
|
|
9684
|
+
<strong>${escapeHtml(sessionId || "No active session")}</strong>
|
|
9688
9685
|
</header>
|
|
9689
|
-
<p class="absolute-voice-live-ops__description">${
|
|
9690
|
-
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${
|
|
9691
|
-
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${
|
|
9692
|
-
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${
|
|
9686
|
+
<p class="absolute-voice-live-ops__description">${escapeHtml(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
|
|
9687
|
+
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml(options.defaultAssignee ?? "operator")}" /></label>
|
|
9688
|
+
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml(options.defaultTag ?? "live-ops")}" /></label>
|
|
9689
|
+
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
|
|
9693
9690
|
<div class="absolute-voice-live-ops__actions">${actions}</div>
|
|
9694
9691
|
${result}
|
|
9695
9692
|
</section>`;
|
|
@@ -9776,16 +9773,15 @@ var defineVoiceLiveOpsElement = (tagName = "absolute-voice-live-ops", options =
|
|
|
9776
9773
|
});
|
|
9777
9774
|
};
|
|
9778
9775
|
// src/client/opsActionHistoryWidget.ts
|
|
9779
|
-
var escapeHtml18 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9780
9776
|
var renderVoiceOpsActionHistoryWidgetHTML = (snapshot, options = {}) => {
|
|
9781
9777
|
const report = snapshot.report;
|
|
9782
9778
|
const entries = (report?.entries ?? []).slice(0, options.limit ?? 5);
|
|
9783
|
-
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${
|
|
9779
|
+
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml(entry.actionId)}</span><strong>${escapeHtml(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
|
|
9784
9780
|
return `<section class="absolute-voice-ops-action-history">
|
|
9785
|
-
<header><span>Operator proof</span><strong>${
|
|
9781
|
+
<header><span>Operator proof</span><strong>${escapeHtml(options.title ?? "Action History")}</strong></header>
|
|
9786
9782
|
<p>${String(report?.total ?? 0)} action(s), ${String(report?.failed ?? 0)} failed.</p>
|
|
9787
9783
|
<ul>${rows || "<li>No operator actions recorded yet.</li>"}</ul>
|
|
9788
|
-
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${
|
|
9784
|
+
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml(snapshot.error)}</p>` : ""}
|
|
9789
9785
|
</section>`;
|
|
9790
9786
|
};
|
|
9791
9787
|
var getVoiceOpsActionHistoryCSS = () => `.absolute-voice-ops-action-history{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;font-family:inherit}.absolute-voice-ops-action-history header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-history header span{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-history header strong{font-size:24px}.absolute-voice-ops-action-history p{color:#514733}.absolute-voice-ops-action-history ul{display:grid;gap:8px;list-style:none;margin:12px 0 0;padding:0}.absolute-voice-ops-action-history__entry{background:#fff;border:1px solid #eee4d2;border-radius:14px;display:grid;gap:3px;padding:10px 12px}.absolute-voice-ops-action-history__entry--error{border-color:#f2a7a7}.absolute-voice-ops-action-history__entry span{font-weight:800}.absolute-voice-ops-action-history__entry small{color:#655944}.absolute-voice-ops-action-history__error{color:#9f1239;font-weight:700}`;
|
|
@@ -9808,7 +9804,6 @@ var mountVoiceOpsActionHistory = (element, path = "/api/voice/ops-actions/histor
|
|
|
9808
9804
|
// src/client/deliveryRuntimeWidget.ts
|
|
9809
9805
|
var DEFAULT_TITLE12 = "Voice Delivery Runtime";
|
|
9810
9806
|
var DEFAULT_DESCRIPTION12 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
9811
|
-
var escapeHtml19 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9812
9807
|
var createSurface = (id, summary) => {
|
|
9813
9808
|
if (!summary) {
|
|
9814
9809
|
return {
|
|
@@ -9857,26 +9852,26 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
9857
9852
|
};
|
|
9858
9853
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
9859
9854
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
9860
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
9861
|
-
<span>${
|
|
9862
|
-
<strong>${
|
|
9855
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml(surface.status)}">
|
|
9856
|
+
<span>${escapeHtml(surface.label)}</span>
|
|
9857
|
+
<strong>${escapeHtml(surface.detail)}</strong>
|
|
9863
9858
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
9864
9859
|
</li>`).join("");
|
|
9865
9860
|
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
9866
9861
|
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
9867
9862
|
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
9868
9863
|
</div>`;
|
|
9869
|
-
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
9870
|
-
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${
|
|
9864
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml(model.actionError)}</p>` : "";
|
|
9865
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml(model.status)}">
|
|
9871
9866
|
<header class="absolute-voice-delivery-runtime__header">
|
|
9872
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
9873
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
9867
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml(model.title)}</span>
|
|
9868
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml(model.label)}</strong>
|
|
9874
9869
|
</header>
|
|
9875
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
9870
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml(model.description)}</p>
|
|
9876
9871
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
9877
9872
|
${actions}
|
|
9878
9873
|
${actionError}
|
|
9879
|
-
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
9874
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml(model.error)}</p>` : ""}
|
|
9880
9875
|
</section>`;
|
|
9881
9876
|
};
|
|
9882
9877
|
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}`;
|
|
@@ -10014,7 +10009,6 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
10014
10009
|
// src/client/routingStatusWidget.ts
|
|
10015
10010
|
var DEFAULT_TITLE13 = "Voice Routing";
|
|
10016
10011
|
var DEFAULT_DESCRIPTION13 = "Latest provider routing decision from the self-hosted trace store.";
|
|
10017
|
-
var escapeHtml20 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
10018
10012
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
10019
10013
|
var formatProviderRoutes2 = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
|
|
10020
10014
|
var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
|
|
@@ -10096,22 +10090,22 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
10096
10090
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
10097
10091
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
10098
10092
|
const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
|
|
10099
|
-
<span>${
|
|
10100
|
-
<strong>${
|
|
10093
|
+
<span>${escapeHtml(item.label)}</span>
|
|
10094
|
+
<strong>${escapeHtml(item.value)}</strong>
|
|
10101
10095
|
</div>`).join("")}</div>` : "";
|
|
10102
10096
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
10103
|
-
<span>${
|
|
10104
|
-
<strong>${
|
|
10097
|
+
<span>${escapeHtml(row.label)}</span>
|
|
10098
|
+
<strong>${escapeHtml(row.value)}</strong>
|
|
10105
10099
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
10106
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
10100
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml(model.status)}">
|
|
10107
10101
|
<header class="absolute-voice-routing-status__header">
|
|
10108
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
10109
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
10102
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
10103
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml(model.label)}</strong>
|
|
10110
10104
|
</header>
|
|
10111
|
-
<p class="absolute-voice-routing-status__description">${
|
|
10105
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml(model.description)}</p>
|
|
10112
10106
|
${activeStack}
|
|
10113
10107
|
${rows}
|
|
10114
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
10108
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
10115
10109
|
</section>`;
|
|
10116
10110
|
};
|
|
10117
10111
|
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}}`;
|
|
@@ -10910,7 +10904,6 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
10910
10904
|
};
|
|
10911
10905
|
};
|
|
10912
10906
|
// src/client/providerSimulationControlsWidget.ts
|
|
10913
|
-
var escapeHtml21 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
10914
10907
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
10915
10908
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
10916
10909
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -10930,18 +10923,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
10930
10923
|
};
|
|
10931
10924
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
10932
10925
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
10933
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
10934
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
10926
|
+
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("");
|
|
10927
|
+
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("");
|
|
10935
10928
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
10936
10929
|
<header class="absolute-voice-provider-simulation__header">
|
|
10937
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
10938
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
10930
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml(model.title)}</span>
|
|
10931
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml(model.label)}</strong>
|
|
10939
10932
|
</header>
|
|
10940
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
10941
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
10933
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml(model.description)}</p>
|
|
10934
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
10942
10935
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
10943
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
10944
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
10936
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml(snapshot.error)}</p>` : ""}
|
|
10937
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml(model.resultText)}</pre>` : ""}
|
|
10945
10938
|
</section>`;
|
|
10946
10939
|
};
|
|
10947
10940
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -11008,7 +11001,6 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
|
|
|
11008
11001
|
// src/client/providerStatusWidget.ts
|
|
11009
11002
|
var DEFAULT_TITLE14 = "Voice Providers";
|
|
11010
11003
|
var DEFAULT_DESCRIPTION14 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
11011
|
-
var escapeHtml22 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11012
11004
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
11013
11005
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
11014
11006
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -11064,25 +11056,25 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
11064
11056
|
};
|
|
11065
11057
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
11066
11058
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
11067
|
-
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--${
|
|
11059
|
+
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)}">
|
|
11068
11060
|
<header>
|
|
11069
|
-
<strong>${
|
|
11070
|
-
<span>${
|
|
11061
|
+
<strong>${escapeHtml(provider.label)}</strong>
|
|
11062
|
+
<span>${escapeHtml(formatStatus3(provider.status))}</span>
|
|
11071
11063
|
</header>
|
|
11072
|
-
<p>${
|
|
11064
|
+
<p>${escapeHtml(provider.detail)}</p>
|
|
11073
11065
|
<dl>${provider.rows.map((row) => `<div>
|
|
11074
|
-
<dt>${
|
|
11075
|
-
<dd>${
|
|
11066
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
11067
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
11076
11068
|
</div>`).join("")}</dl>
|
|
11077
11069
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
11078
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
11070
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml(model.status)}">
|
|
11079
11071
|
<header class="absolute-voice-provider-status__header">
|
|
11080
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
11081
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
11072
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml(model.title)}</span>
|
|
11073
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml(model.label)}</strong>
|
|
11082
11074
|
</header>
|
|
11083
|
-
<p class="absolute-voice-provider-status__description">${
|
|
11075
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml(model.description)}</p>
|
|
11084
11076
|
${providers}
|
|
11085
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
11077
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
11086
11078
|
</section>`;
|
|
11087
11079
|
};
|
|
11088
11080
|
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}`;
|
|
@@ -11125,7 +11117,6 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
11125
11117
|
// src/client/providerCapabilitiesWidget.ts
|
|
11126
11118
|
var DEFAULT_TITLE15 = "Provider Capabilities";
|
|
11127
11119
|
var DEFAULT_DESCRIPTION15 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
11128
|
-
var escapeHtml23 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11129
11120
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
11130
11121
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
11131
11122
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -11180,25 +11171,25 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
11180
11171
|
};
|
|
11181
11172
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
11182
11173
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
11183
|
-
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--${
|
|
11174
|
+
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)}">
|
|
11184
11175
|
<header>
|
|
11185
|
-
<strong>${
|
|
11186
|
-
<span>${
|
|
11176
|
+
<strong>${escapeHtml(capability.label)}</strong>
|
|
11177
|
+
<span>${escapeHtml(formatStatus4(capability.status))}</span>
|
|
11187
11178
|
</header>
|
|
11188
|
-
<p>${
|
|
11179
|
+
<p>${escapeHtml(capability.detail)}</p>
|
|
11189
11180
|
<dl>${capability.rows.map((row) => `<div>
|
|
11190
|
-
<dt>${
|
|
11191
|
-
<dd>${
|
|
11181
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
11182
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
11192
11183
|
</div>`).join("")}</dl>
|
|
11193
11184
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
11194
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
11185
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml(model.status)}">
|
|
11195
11186
|
<header class="absolute-voice-provider-capabilities__header">
|
|
11196
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
11197
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
11187
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml(model.title)}</span>
|
|
11188
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml(model.label)}</strong>
|
|
11198
11189
|
</header>
|
|
11199
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
11190
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml(model.description)}</p>
|
|
11200
11191
|
${capabilities}
|
|
11201
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
11192
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml(model.error)}</p>` : ""}
|
|
11202
11193
|
</section>`;
|
|
11203
11194
|
};
|
|
11204
11195
|
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}`;
|
|
@@ -11241,7 +11232,6 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
|
|
|
11241
11232
|
// src/client/providerContractsWidget.ts
|
|
11242
11233
|
var DEFAULT_TITLE16 = "Provider Contracts";
|
|
11243
11234
|
var DEFAULT_DESCRIPTION16 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
11244
|
-
var escapeHtml24 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11245
11235
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
11246
11236
|
var formatStatus5 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
11247
11237
|
var contractDetail = (row) => {
|
|
@@ -11285,26 +11275,26 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
11285
11275
|
};
|
|
11286
11276
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
11287
11277
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
11288
|
-
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--${
|
|
11278
|
+
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)}">
|
|
11289
11279
|
<header>
|
|
11290
|
-
<strong>${
|
|
11291
|
-
<span>${
|
|
11280
|
+
<strong>${escapeHtml(row.label)}</strong>
|
|
11281
|
+
<span>${escapeHtml(formatStatus5(row.status))}</span>
|
|
11292
11282
|
</header>
|
|
11293
|
-
<p>${
|
|
11294
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
11283
|
+
<p>${escapeHtml(row.detail)}</p>
|
|
11284
|
+
${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>` : ""}
|
|
11295
11285
|
<dl>${row.rows.map((item) => `<div>
|
|
11296
|
-
<dt>${
|
|
11297
|
-
<dd>${
|
|
11286
|
+
<dt>${escapeHtml(item.label)}</dt>
|
|
11287
|
+
<dd>${escapeHtml(item.value)}</dd>
|
|
11298
11288
|
</div>`).join("")}</dl>
|
|
11299
11289
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
11300
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
11290
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml(model.status)}">
|
|
11301
11291
|
<header class="absolute-voice-provider-contracts__header">
|
|
11302
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
11303
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
11292
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml(model.title)}</span>
|
|
11293
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml(model.label)}</strong>
|
|
11304
11294
|
</header>
|
|
11305
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
11295
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml(model.description)}</p>
|
|
11306
11296
|
${rows}
|
|
11307
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
11297
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml(model.error)}</p>` : ""}
|
|
11308
11298
|
</section>`;
|
|
11309
11299
|
};
|
|
11310
11300
|
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}`;
|
|
@@ -11347,7 +11337,6 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
|
|
|
11347
11337
|
// src/client/turnQualityWidget.ts
|
|
11348
11338
|
var DEFAULT_TITLE17 = "Turn Quality";
|
|
11349
11339
|
var DEFAULT_DESCRIPTION17 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
11350
|
-
var escapeHtml25 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11351
11340
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
11352
11341
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
11353
11342
|
var getTurnDetail = (turn) => {
|
|
@@ -11403,25 +11392,25 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
11403
11392
|
};
|
|
11404
11393
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
11405
11394
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
11406
|
-
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--${
|
|
11395
|
+
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)}">
|
|
11407
11396
|
<header>
|
|
11408
|
-
<strong>${
|
|
11409
|
-
<span>${
|
|
11397
|
+
<strong>${escapeHtml(turn.label)}</strong>
|
|
11398
|
+
<span>${escapeHtml(turn.status)}</span>
|
|
11410
11399
|
</header>
|
|
11411
|
-
<p>${
|
|
11400
|
+
<p>${escapeHtml(turn.detail)}</p>
|
|
11412
11401
|
<dl>${turn.rows.map((row) => `<div>
|
|
11413
|
-
<dt>${
|
|
11414
|
-
<dd>${
|
|
11402
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
11403
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
11415
11404
|
</div>`).join("")}</dl>
|
|
11416
11405
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
11417
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
11406
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml(model.status)}">
|
|
11418
11407
|
<header class="absolute-voice-turn-quality__header">
|
|
11419
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
11420
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
11408
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml(model.title)}</span>
|
|
11409
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml(model.label)}</strong>
|
|
11421
11410
|
</header>
|
|
11422
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
11411
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml(model.description)}</p>
|
|
11423
11412
|
${turns}
|
|
11424
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
11413
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml(model.error)}</p>` : ""}
|
|
11425
11414
|
</section>`;
|
|
11426
11415
|
};
|
|
11427
11416
|
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}`;
|
|
@@ -11465,7 +11454,6 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
11465
11454
|
var DEFAULT_TITLE18 = "Turn Latency";
|
|
11466
11455
|
var DEFAULT_DESCRIPTION18 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
11467
11456
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
11468
|
-
var escapeHtml26 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11469
11457
|
var formatMs5 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
11470
11458
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
11471
11459
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -11493,25 +11481,25 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
11493
11481
|
};
|
|
11494
11482
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
11495
11483
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
11496
|
-
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--${
|
|
11484
|
+
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)}">
|
|
11497
11485
|
<header>
|
|
11498
|
-
<strong>${
|
|
11499
|
-
<span>${
|
|
11486
|
+
<strong>${escapeHtml(turn.label)}</strong>
|
|
11487
|
+
<span>${escapeHtml(turn.status)}</span>
|
|
11500
11488
|
</header>
|
|
11501
11489
|
<dl>${turn.rows.map((row) => `<div>
|
|
11502
|
-
<dt>${
|
|
11503
|
-
<dd>${
|
|
11490
|
+
<dt>${escapeHtml(row.label)}</dt>
|
|
11491
|
+
<dd>${escapeHtml(row.value)}</dd>
|
|
11504
11492
|
</div>`).join("")}</dl>
|
|
11505
11493
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
11506
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
11494
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml(model.status)}">
|
|
11507
11495
|
<header class="absolute-voice-turn-latency__header">
|
|
11508
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
11509
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
11496
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml(model.title)}</span>
|
|
11497
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml(model.label)}</strong>
|
|
11510
11498
|
</header>
|
|
11511
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
11512
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
11499
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml(model.description)}</p>
|
|
11500
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
11513
11501
|
${turns}
|
|
11514
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
11502
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml(model.error)}</p>` : ""}
|
|
11515
11503
|
</section>`;
|
|
11516
11504
|
};
|
|
11517
11505
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -11563,7 +11551,6 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
11563
11551
|
// src/client/traceTimelineWidget.ts
|
|
11564
11552
|
var DEFAULT_TITLE19 = "Voice Traces";
|
|
11565
11553
|
var DEFAULT_DESCRIPTION19 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
11566
|
-
var escapeHtml27 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11567
11554
|
var formatMs6 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
11568
11555
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
11569
11556
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -11593,27 +11580,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
11593
11580
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
11594
11581
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
11595
11582
|
const supportLinks = [
|
|
11596
|
-
`<a href="${
|
|
11597
|
-
session.operationsRecordHref ? `<a href="${
|
|
11598
|
-
session.incidentBundleHref ? `<a href="${
|
|
11583
|
+
`<a href="${escapeHtml(session.detailHref)}">Open timeline</a>`,
|
|
11584
|
+
session.operationsRecordHref ? `<a href="${escapeHtml(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
11585
|
+
session.incidentBundleHref ? `<a href="${escapeHtml(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
11599
11586
|
].filter(Boolean).join("");
|
|
11600
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
11587
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml(session.status)}">
|
|
11601
11588
|
<header>
|
|
11602
|
-
<strong>${
|
|
11603
|
-
<span>${
|
|
11589
|
+
<strong>${escapeHtml(session.sessionId)}</strong>
|
|
11590
|
+
<span>${escapeHtml(session.status)}</span>
|
|
11604
11591
|
</header>
|
|
11605
|
-
<p>${
|
|
11592
|
+
<p>${escapeHtml(session.label)} \xB7 ${escapeHtml(session.durationLabel)} \xB7 ${escapeHtml(session.providerLabel)}</p>
|
|
11606
11593
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
11607
11594
|
</article>`;
|
|
11608
11595
|
}).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
11609
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
11596
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml(model.status)}">
|
|
11610
11597
|
<header class="absolute-voice-trace-timeline__header">
|
|
11611
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
11612
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
11598
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml(model.title)}</span>
|
|
11599
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml(model.label)}</strong>
|
|
11613
11600
|
</header>
|
|
11614
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
11601
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml(model.description)}</p>
|
|
11615
11602
|
${sessions}
|
|
11616
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
11603
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml(model.error)}</p>` : ""}
|
|
11617
11604
|
</section>`;
|
|
11618
11605
|
};
|
|
11619
11606
|
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}`;
|
|
@@ -11661,7 +11648,6 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
|
|
|
11661
11648
|
// src/client/agentSquadStatusWidget.ts
|
|
11662
11649
|
var DEFAULT_TITLE20 = "Voice Agent Squad";
|
|
11663
11650
|
var DEFAULT_DESCRIPTION20 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
11664
|
-
var escapeHtml28 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11665
11651
|
var labelFor = (current) => {
|
|
11666
11652
|
if (!current)
|
|
11667
11653
|
return "Waiting for specialist activity";
|
|
@@ -11688,24 +11674,24 @@ var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
|
11688
11674
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
11689
11675
|
const current = model.current;
|
|
11690
11676
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
11691
|
-
<span>${
|
|
11692
|
-
<strong>${
|
|
11693
|
-
<em>${
|
|
11694
|
-
${session.summary || session.reason ? `<p>${
|
|
11677
|
+
<span>${escapeHtml(session.sessionId)}</span>
|
|
11678
|
+
<strong>${escapeHtml(session.targetAgentId ?? "none")}</strong>
|
|
11679
|
+
<em>${escapeHtml(session.status)}</em>
|
|
11680
|
+
${session.summary || session.reason ? `<p>${escapeHtml(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
11695
11681
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
11696
11682
|
return `<section class="absolute-voice-agent-squad-status">
|
|
11697
11683
|
<header>
|
|
11698
|
-
<span>${
|
|
11699
|
-
<strong>${
|
|
11684
|
+
<span>${escapeHtml(model.title)}</span>
|
|
11685
|
+
<strong>${escapeHtml(model.label)}</strong>
|
|
11700
11686
|
</header>
|
|
11701
|
-
<p>${
|
|
11687
|
+
<p>${escapeHtml(model.description)}</p>
|
|
11702
11688
|
<div>
|
|
11703
|
-
<span>Session</span><strong>${
|
|
11704
|
-
<span>From</span><strong>${
|
|
11705
|
-
<span>Status</span><strong>${
|
|
11689
|
+
<span>Session</span><strong>${escapeHtml(current?.sessionId ?? "n/a")}</strong>
|
|
11690
|
+
<span>From</span><strong>${escapeHtml(current?.fromAgentId ?? "n/a")}</strong>
|
|
11691
|
+
<span>Status</span><strong>${escapeHtml(current?.status ?? "idle")}</strong>
|
|
11706
11692
|
</div>
|
|
11707
11693
|
<ul>${rows}</ul>
|
|
11708
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
11694
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml(model.error)}</p>` : ""}
|
|
11709
11695
|
</section>`;
|
|
11710
11696
|
};
|
|
11711
11697
|
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}`;
|