@absolutejs/voice 0.0.22-beta.352 → 0.0.22-beta.354
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.d.ts +1 -0
- package/dist/angular/index.js +313 -192
- package/dist/angular/voice-profile-comparison.service.d.ts +12 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.js +532 -212
- package/dist/client/profileComparison.d.ts +19 -0
- package/dist/client/profileComparisonWidget.d.ts +41 -0
- package/dist/client/profileSwitchRecommendation.d.ts +19 -0
- package/dist/client/profileSwitchRecommendationWidget.d.ts +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +67 -0
- package/dist/profileSwitchRecommendation.d.ts +38 -0
- package/dist/react/VoiceProfileComparison.d.ts +6 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +675 -397
- package/dist/react/useVoiceProfileComparison.d.ts +8 -0
- package/dist/svelte/createVoiceProfileComparison.d.ts +7 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +86 -0
- package/dist/vue/index.d.ts +1 -0
- package/dist/vue/index.js +161 -51
- package/dist/vue/useVoiceProfileComparison.d.ts +9 -0
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -2960,6 +2960,154 @@ var createVoiceProofTrendsStore = (path = "/api/voice/proof-trends", options = {
|
|
|
2960
2960
|
}
|
|
2961
2961
|
};
|
|
2962
2962
|
};
|
|
2963
|
+
// src/client/profileComparison.ts
|
|
2964
|
+
var fetchVoiceProfileComparison = async (path = "/api/voice/real-call-profile-history", options = {}) => {
|
|
2965
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
2966
|
+
const response = await fetchImpl(path);
|
|
2967
|
+
if (!response.ok) {
|
|
2968
|
+
throw new Error(`Voice profile comparison failed: HTTP ${response.status}`);
|
|
2969
|
+
}
|
|
2970
|
+
return await response.json();
|
|
2971
|
+
};
|
|
2972
|
+
var createVoiceProfileComparisonStore = (path = "/api/voice/real-call-profile-history", options = {}) => {
|
|
2973
|
+
const listeners = new Set;
|
|
2974
|
+
let closed = false;
|
|
2975
|
+
let timer;
|
|
2976
|
+
let snapshot = {
|
|
2977
|
+
error: null,
|
|
2978
|
+
isLoading: false
|
|
2979
|
+
};
|
|
2980
|
+
const emit = () => {
|
|
2981
|
+
for (const listener of listeners) {
|
|
2982
|
+
listener();
|
|
2983
|
+
}
|
|
2984
|
+
};
|
|
2985
|
+
const refresh = async () => {
|
|
2986
|
+
if (closed) {
|
|
2987
|
+
return snapshot.report;
|
|
2988
|
+
}
|
|
2989
|
+
snapshot = { ...snapshot, error: null, isLoading: true };
|
|
2990
|
+
emit();
|
|
2991
|
+
try {
|
|
2992
|
+
const report = await fetchVoiceProfileComparison(path, options);
|
|
2993
|
+
snapshot = {
|
|
2994
|
+
error: null,
|
|
2995
|
+
isLoading: false,
|
|
2996
|
+
report,
|
|
2997
|
+
updatedAt: Date.now()
|
|
2998
|
+
};
|
|
2999
|
+
emit();
|
|
3000
|
+
return report;
|
|
3001
|
+
} catch (error) {
|
|
3002
|
+
snapshot = {
|
|
3003
|
+
...snapshot,
|
|
3004
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3005
|
+
isLoading: false
|
|
3006
|
+
};
|
|
3007
|
+
emit();
|
|
3008
|
+
throw error;
|
|
3009
|
+
}
|
|
3010
|
+
};
|
|
3011
|
+
const close = () => {
|
|
3012
|
+
closed = true;
|
|
3013
|
+
if (timer) {
|
|
3014
|
+
clearInterval(timer);
|
|
3015
|
+
timer = undefined;
|
|
3016
|
+
}
|
|
3017
|
+
listeners.clear();
|
|
3018
|
+
};
|
|
3019
|
+
if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
|
|
3020
|
+
timer = setInterval(() => {
|
|
3021
|
+
refresh().catch(() => {});
|
|
3022
|
+
}, options.intervalMs);
|
|
3023
|
+
}
|
|
3024
|
+
return {
|
|
3025
|
+
close,
|
|
3026
|
+
getServerSnapshot: () => snapshot,
|
|
3027
|
+
getSnapshot: () => snapshot,
|
|
3028
|
+
refresh,
|
|
3029
|
+
subscribe: (listener) => {
|
|
3030
|
+
listeners.add(listener);
|
|
3031
|
+
return () => {
|
|
3032
|
+
listeners.delete(listener);
|
|
3033
|
+
};
|
|
3034
|
+
}
|
|
3035
|
+
};
|
|
3036
|
+
};
|
|
3037
|
+
// src/client/profileSwitchRecommendation.ts
|
|
3038
|
+
var fetchVoiceProfileSwitchRecommendation = async (path = "/api/voice/profile-switch-recommendation", options = {}) => {
|
|
3039
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
3040
|
+
const response = await fetchImpl(path);
|
|
3041
|
+
if (!response.ok) {
|
|
3042
|
+
throw new Error(`Voice profile switch recommendation failed: HTTP ${response.status}`);
|
|
3043
|
+
}
|
|
3044
|
+
return await response.json();
|
|
3045
|
+
};
|
|
3046
|
+
var createVoiceProfileSwitchRecommendationStore = (path = "/api/voice/profile-switch-recommendation", options = {}) => {
|
|
3047
|
+
const listeners = new Set;
|
|
3048
|
+
let closed = false;
|
|
3049
|
+
let timer;
|
|
3050
|
+
let snapshot = {
|
|
3051
|
+
error: null,
|
|
3052
|
+
isLoading: false
|
|
3053
|
+
};
|
|
3054
|
+
const emit = () => {
|
|
3055
|
+
for (const listener of listeners) {
|
|
3056
|
+
listener();
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
const refresh = async () => {
|
|
3060
|
+
if (closed) {
|
|
3061
|
+
return snapshot.recommendation;
|
|
3062
|
+
}
|
|
3063
|
+
snapshot = { ...snapshot, error: null, isLoading: true };
|
|
3064
|
+
emit();
|
|
3065
|
+
try {
|
|
3066
|
+
const recommendation = await fetchVoiceProfileSwitchRecommendation(path, options);
|
|
3067
|
+
snapshot = {
|
|
3068
|
+
error: null,
|
|
3069
|
+
isLoading: false,
|
|
3070
|
+
recommendation,
|
|
3071
|
+
updatedAt: Date.now()
|
|
3072
|
+
};
|
|
3073
|
+
emit();
|
|
3074
|
+
return recommendation;
|
|
3075
|
+
} catch (error) {
|
|
3076
|
+
snapshot = {
|
|
3077
|
+
...snapshot,
|
|
3078
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3079
|
+
isLoading: false
|
|
3080
|
+
};
|
|
3081
|
+
emit();
|
|
3082
|
+
throw error;
|
|
3083
|
+
}
|
|
3084
|
+
};
|
|
3085
|
+
const close = () => {
|
|
3086
|
+
closed = true;
|
|
3087
|
+
if (timer) {
|
|
3088
|
+
clearInterval(timer);
|
|
3089
|
+
timer = undefined;
|
|
3090
|
+
}
|
|
3091
|
+
listeners.clear();
|
|
3092
|
+
};
|
|
3093
|
+
if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
|
|
3094
|
+
timer = setInterval(() => {
|
|
3095
|
+
refresh().catch(() => {});
|
|
3096
|
+
}, options.intervalMs);
|
|
3097
|
+
}
|
|
3098
|
+
return {
|
|
3099
|
+
close,
|
|
3100
|
+
getServerSnapshot: () => snapshot,
|
|
3101
|
+
getSnapshot: () => snapshot,
|
|
3102
|
+
refresh,
|
|
3103
|
+
subscribe: (listener) => {
|
|
3104
|
+
listeners.add(listener);
|
|
3105
|
+
return () => {
|
|
3106
|
+
listeners.delete(listener);
|
|
3107
|
+
};
|
|
3108
|
+
}
|
|
3109
|
+
};
|
|
3110
|
+
};
|
|
2963
3111
|
// src/client/readinessFailures.ts
|
|
2964
3112
|
var fetchVoiceReadinessFailures = async (path = "/api/production-readiness", options = {}) => {
|
|
2965
3113
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -4901,14 +5049,173 @@ var defineVoiceProofTrendsElement = (tagName = "absolute-voice-proof-trends") =>
|
|
|
4901
5049
|
}
|
|
4902
5050
|
});
|
|
4903
5051
|
};
|
|
4904
|
-
// src/client/
|
|
4905
|
-
var DEFAULT_TITLE4 = "
|
|
4906
|
-
var DEFAULT_DESCRIPTION4 = "
|
|
5052
|
+
// src/client/profileComparisonWidget.ts
|
|
5053
|
+
var DEFAULT_TITLE4 = "Profile Stack Comparison";
|
|
5054
|
+
var DEFAULT_DESCRIPTION4 = "Measured real-call evidence behind each profile default: provider routes, latency, and the next move.";
|
|
4907
5055
|
var DEFAULT_LINKS3 = [
|
|
5056
|
+
{ href: "/voice/real-call-profile-history", label: "Profile history" },
|
|
5057
|
+
{ href: "/api/voice/real-call-profile-history", label: "JSON" }
|
|
5058
|
+
];
|
|
5059
|
+
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5060
|
+
var formatMs2 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
5061
|
+
var formatProviderRoutes = (profile) => Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "No complete route yet";
|
|
5062
|
+
var createProfileView = (profile) => ({
|
|
5063
|
+
evidence: [
|
|
5064
|
+
{ label: "Live p95", value: formatMs2(profile.evidence.liveP95Ms) },
|
|
5065
|
+
{ label: "Provider p95", value: formatMs2(profile.evidence.providerP95Ms) },
|
|
5066
|
+
{ label: "Turn p95", value: formatMs2(profile.evidence.turnP95Ms) }
|
|
5067
|
+
],
|
|
5068
|
+
label: profile.label ?? profile.profileId,
|
|
5069
|
+
nextMove: profile.nextMove,
|
|
5070
|
+
profileId: profile.profileId,
|
|
5071
|
+
providerRoutes: formatProviderRoutes(profile),
|
|
5072
|
+
status: profile.status
|
|
5073
|
+
});
|
|
5074
|
+
var createVoiceProfileComparisonViewModel = (snapshot, options = {}) => {
|
|
5075
|
+
const report = snapshot.report;
|
|
5076
|
+
const profiles = report?.defaults.profiles.map(createProfileView) ?? [];
|
|
5077
|
+
return {
|
|
5078
|
+
description: options.description ?? DEFAULT_DESCRIPTION4,
|
|
5079
|
+
error: snapshot.error,
|
|
5080
|
+
isLoading: snapshot.isLoading,
|
|
5081
|
+
label: snapshot.error ? "Unavailable" : report ? `${report.defaults.summary.actionableProfiles}/${report.defaults.summary.profileCount} profiles ready` : snapshot.isLoading ? "Checking" : "No profile evidence",
|
|
5082
|
+
links: options.links ?? DEFAULT_LINKS3,
|
|
5083
|
+
profiles,
|
|
5084
|
+
status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : "warning" : snapshot.isLoading ? "loading" : "empty",
|
|
5085
|
+
title: options.title ?? DEFAULT_TITLE4
|
|
5086
|
+
};
|
|
5087
|
+
};
|
|
5088
|
+
var renderVoiceProfileComparisonHTML = (snapshot, options = {}) => {
|
|
5089
|
+
const model = createVoiceProfileComparisonViewModel(snapshot, options);
|
|
5090
|
+
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--${escapeHtml5(profile.status)}">
|
|
5091
|
+
<header>
|
|
5092
|
+
<span>${escapeHtml5(profile.status)}</span>
|
|
5093
|
+
<strong>${escapeHtml5(profile.label)}</strong>
|
|
5094
|
+
</header>
|
|
5095
|
+
<p>${escapeHtml5(profile.providerRoutes)}</p>
|
|
5096
|
+
<div>${profile.evidence.map((metric) => `<span><small>${escapeHtml5(metric.label)}</small><b>${escapeHtml5(metric.value)}</b></span>`).join("")}</div>
|
|
5097
|
+
<em>${escapeHtml5(profile.nextMove)}</em>
|
|
5098
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ? escapeHtml5(model.error) : "Run real-call profile collection to populate profile comparisons."}</p>`;
|
|
5099
|
+
const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${escapeHtml5(link.href)}">${escapeHtml5(link.label)}</a>`).join("")}</p>` : "";
|
|
5100
|
+
return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${escapeHtml5(model.status)}">
|
|
5101
|
+
<header class="absolute-voice-profile-comparison__header">
|
|
5102
|
+
<span class="absolute-voice-profile-comparison__eyebrow">${escapeHtml5(model.title)}</span>
|
|
5103
|
+
<strong class="absolute-voice-profile-comparison__label">${escapeHtml5(model.label)}</strong>
|
|
5104
|
+
</header>
|
|
5105
|
+
<p class="absolute-voice-profile-comparison__description">${escapeHtml5(model.description)}</p>
|
|
5106
|
+
${profiles}
|
|
5107
|
+
${links}
|
|
5108
|
+
${model.error ? `<p class="absolute-voice-profile-comparison__error">${escapeHtml5(model.error)}</p>` : ""}
|
|
5109
|
+
</section>`;
|
|
5110
|
+
};
|
|
5111
|
+
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}`;
|
|
5112
|
+
var mountVoiceProfileComparison = (element, path = "/api/voice/real-call-profile-history", options = {}) => {
|
|
5113
|
+
const store = createVoiceProfileComparisonStore(path, options);
|
|
5114
|
+
const render = () => {
|
|
5115
|
+
element.innerHTML = renderVoiceProfileComparisonHTML(store.getSnapshot(), options);
|
|
5116
|
+
};
|
|
5117
|
+
const unsubscribe = store.subscribe(render);
|
|
5118
|
+
render();
|
|
5119
|
+
store.refresh().catch(() => {});
|
|
5120
|
+
return {
|
|
5121
|
+
close: () => {
|
|
5122
|
+
unsubscribe();
|
|
5123
|
+
store.close();
|
|
5124
|
+
},
|
|
5125
|
+
refresh: store.refresh
|
|
5126
|
+
};
|
|
5127
|
+
};
|
|
5128
|
+
var defineVoiceProfileComparisonElement = (tagName = "absolute-voice-profile-comparison") => {
|
|
5129
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
5130
|
+
return;
|
|
5131
|
+
}
|
|
5132
|
+
customElements.define(tagName, class AbsoluteVoiceProfileComparisonElement extends HTMLElement {
|
|
5133
|
+
mounted;
|
|
5134
|
+
connectedCallback() {
|
|
5135
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
|
|
5136
|
+
this.mounted = mountVoiceProfileComparison(this, this.getAttribute("path") ?? "/api/voice/real-call-profile-history", {
|
|
5137
|
+
description: this.getAttribute("description") ?? undefined,
|
|
5138
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
|
|
5139
|
+
title: this.getAttribute("title") ?? undefined
|
|
5140
|
+
});
|
|
5141
|
+
}
|
|
5142
|
+
disconnectedCallback() {
|
|
5143
|
+
this.mounted?.close();
|
|
5144
|
+
this.mounted = undefined;
|
|
5145
|
+
}
|
|
5146
|
+
});
|
|
5147
|
+
};
|
|
5148
|
+
// src/client/profileSwitchRecommendationWidget.ts
|
|
5149
|
+
var DEFAULT_TITLE5 = "Profile Switch Recommendation";
|
|
5150
|
+
var DEFAULT_DESCRIPTION5 = "Compares the current session against measured profile evidence and recommends whether to switch stacks.";
|
|
5151
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5152
|
+
var formatRoute = (routes) => routes ? Object.entries(routes).map(([role, provider]) => `${role}: ${provider}`).join(", ") : "No route";
|
|
5153
|
+
var renderVoiceProfileSwitchRecommendationHTML = (snapshot, options = {}) => {
|
|
5154
|
+
const recommendation = snapshot.recommendation;
|
|
5155
|
+
const status = snapshot.error ? "error" : recommendation ? recommendation.status : snapshot.isLoading ? "loading" : "empty";
|
|
5156
|
+
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";
|
|
5157
|
+
const body = recommendation ? `<div class="absolute-voice-profile-switch__body">
|
|
5158
|
+
<p><strong>Current:</strong> ${escapeHtml6(recommendation.currentProfile?.label ?? recommendation.currentProfile?.profileId ?? "Unknown")}</p>
|
|
5159
|
+
<p><strong>Recommended:</strong> ${escapeHtml6(recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "None")}</p>
|
|
5160
|
+
<p><strong>Routes:</strong> ${escapeHtml6(formatRoute(recommendation.recommendedProfile?.providerRoutes))}</p>
|
|
5161
|
+
<ul>${recommendation.reasons.map((reason) => `<li>${escapeHtml6(reason)}</li>`).join("")}</ul>
|
|
5162
|
+
<em>${escapeHtml6(recommendation.nextMove)}</em>
|
|
5163
|
+
</div>` : `<p class="absolute-voice-profile-switch__empty">${escapeHtml6(snapshot.error ?? "Run session traffic to populate a recommendation.")}</p>`;
|
|
5164
|
+
return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${escapeHtml6(status)}">
|
|
5165
|
+
<header class="absolute-voice-profile-switch__header">
|
|
5166
|
+
<span class="absolute-voice-profile-switch__eyebrow">${escapeHtml6(options.title ?? DEFAULT_TITLE5)}</span>
|
|
5167
|
+
<strong class="absolute-voice-profile-switch__label">${escapeHtml6(label)}</strong>
|
|
5168
|
+
</header>
|
|
5169
|
+
<p class="absolute-voice-profile-switch__description">${escapeHtml6(options.description ?? DEFAULT_DESCRIPTION5)}</p>
|
|
5170
|
+
${body}
|
|
5171
|
+
${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${escapeHtml6(snapshot.error)}</p>` : ""}
|
|
5172
|
+
</section>`;
|
|
5173
|
+
};
|
|
5174
|
+
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}`;
|
|
5175
|
+
var mountVoiceProfileSwitchRecommendation = (element, path = "/api/voice/profile-switch-recommendation", options = {}) => {
|
|
5176
|
+
const store = createVoiceProfileSwitchRecommendationStore(path, options);
|
|
5177
|
+
const render = () => {
|
|
5178
|
+
element.innerHTML = renderVoiceProfileSwitchRecommendationHTML(store.getSnapshot(), options);
|
|
5179
|
+
};
|
|
5180
|
+
const unsubscribe = store.subscribe(render);
|
|
5181
|
+
render();
|
|
5182
|
+
store.refresh().catch(() => {});
|
|
5183
|
+
return {
|
|
5184
|
+
close: () => {
|
|
5185
|
+
unsubscribe();
|
|
5186
|
+
store.close();
|
|
5187
|
+
},
|
|
5188
|
+
refresh: store.refresh
|
|
5189
|
+
};
|
|
5190
|
+
};
|
|
5191
|
+
var defineVoiceProfileSwitchRecommendationElement = (tagName = "absolute-voice-profile-switch") => {
|
|
5192
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
5193
|
+
return;
|
|
5194
|
+
}
|
|
5195
|
+
customElements.define(tagName, class AbsoluteVoiceProfileSwitchElement extends HTMLElement {
|
|
5196
|
+
mounted;
|
|
5197
|
+
connectedCallback() {
|
|
5198
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
|
|
5199
|
+
this.mounted = mountVoiceProfileSwitchRecommendation(this, this.getAttribute("path") ?? "/api/voice/profile-switch-recommendation", {
|
|
5200
|
+
description: this.getAttribute("description") ?? undefined,
|
|
5201
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
|
|
5202
|
+
title: this.getAttribute("title") ?? undefined
|
|
5203
|
+
});
|
|
5204
|
+
}
|
|
5205
|
+
disconnectedCallback() {
|
|
5206
|
+
this.mounted?.close();
|
|
5207
|
+
this.mounted = undefined;
|
|
5208
|
+
}
|
|
5209
|
+
});
|
|
5210
|
+
};
|
|
5211
|
+
// src/client/readinessFailuresWidget.ts
|
|
5212
|
+
var DEFAULT_TITLE6 = "Readiness Gate Explanations";
|
|
5213
|
+
var DEFAULT_DESCRIPTION6 = "Structured reasons for calibrated production-readiness warnings and failures.";
|
|
5214
|
+
var DEFAULT_LINKS4 = [
|
|
4908
5215
|
{ href: "/production-readiness", label: "Readiness page" },
|
|
4909
5216
|
{ href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
|
|
4910
5217
|
];
|
|
4911
|
-
var
|
|
5218
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4912
5219
|
var formatExplanationValue = (value, unit) => {
|
|
4913
5220
|
if (value === undefined || value === null) {
|
|
4914
5221
|
return "n/a";
|
|
@@ -4936,36 +5243,36 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
|
|
|
4936
5243
|
const failures = snapshot.report?.checks.map(toFailureView).filter((value) => !!value) ?? [];
|
|
4937
5244
|
const hasOpenIssues = failures.length > 0;
|
|
4938
5245
|
return {
|
|
4939
|
-
description: options.description ??
|
|
5246
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
4940
5247
|
error: snapshot.error,
|
|
4941
5248
|
failures,
|
|
4942
5249
|
isLoading: snapshot.isLoading,
|
|
4943
5250
|
label: snapshot.error ? "Unavailable" : snapshot.report ? hasOpenIssues ? `${failures.length} calibrated gate issue(s)` : "No calibrated gate issues" : snapshot.isLoading ? "Checking" : "No readiness report",
|
|
4944
|
-
links: options.links ??
|
|
5251
|
+
links: options.links ?? DEFAULT_LINKS4,
|
|
4945
5252
|
status: snapshot.error ? "error" : snapshot.report ? hasOpenIssues ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
4946
|
-
title: options.title ??
|
|
5253
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
4947
5254
|
updatedAt: snapshot.updatedAt
|
|
4948
5255
|
};
|
|
4949
5256
|
};
|
|
4950
5257
|
var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
|
|
4951
5258
|
const model = createVoiceReadinessFailuresViewModel(snapshot, options);
|
|
4952
|
-
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--${
|
|
4953
|
-
<span>${
|
|
4954
|
-
<strong>${
|
|
4955
|
-
<p>Observed ${
|
|
4956
|
-
<p>${
|
|
4957
|
-
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${
|
|
4958
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ?
|
|
4959
|
-
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${
|
|
4960
|
-
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${
|
|
5259
|
+
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--${escapeHtml7(failure.status)}">
|
|
5260
|
+
<span>${escapeHtml7(failure.status.toUpperCase())}</span>
|
|
5261
|
+
<strong>${escapeHtml7(failure.label)}</strong>
|
|
5262
|
+
<p>Observed ${escapeHtml7(failure.observed)} against ${escapeHtml7(failure.thresholdLabel)} ${escapeHtml7(failure.threshold)}.</p>
|
|
5263
|
+
<p>${escapeHtml7(failure.remediation)}</p>
|
|
5264
|
+
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml7(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml7(failure.sourceHref)}">Threshold source</a>` : ""}</p>
|
|
5265
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml7(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
|
|
5266
|
+
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml7(link.href)}">${escapeHtml7(link.label)}</a>`).join("")}</p>` : "";
|
|
5267
|
+
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml7(model.status)}">
|
|
4961
5268
|
<header class="absolute-voice-readiness-failures__header">
|
|
4962
|
-
<span class="absolute-voice-readiness-failures__eyebrow">${
|
|
4963
|
-
<strong class="absolute-voice-readiness-failures__label">${
|
|
5269
|
+
<span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml7(model.title)}</span>
|
|
5270
|
+
<strong class="absolute-voice-readiness-failures__label">${escapeHtml7(model.label)}</strong>
|
|
4964
5271
|
</header>
|
|
4965
|
-
<p class="absolute-voice-readiness-failures__description">${
|
|
5272
|
+
<p class="absolute-voice-readiness-failures__description">${escapeHtml7(model.description)}</p>
|
|
4966
5273
|
${failures}
|
|
4967
5274
|
${links}
|
|
4968
|
-
${model.error ? `<p class="absolute-voice-readiness-failures__error">${
|
|
5275
|
+
${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
4969
5276
|
</section>`;
|
|
4970
5277
|
};
|
|
4971
5278
|
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}`;
|
|
@@ -5005,9 +5312,9 @@ var defineVoiceReadinessFailuresElement = (tagName = "absolute-voice-readiness-f
|
|
|
5005
5312
|
});
|
|
5006
5313
|
};
|
|
5007
5314
|
// src/client/opsActionCenterWidget.ts
|
|
5008
|
-
var
|
|
5009
|
-
var
|
|
5010
|
-
var
|
|
5315
|
+
var DEFAULT_TITLE7 = "Voice Ops Action Center";
|
|
5316
|
+
var DEFAULT_DESCRIPTION7 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
5317
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5011
5318
|
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
5012
5319
|
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
5013
5320
|
return {
|
|
@@ -5018,29 +5325,29 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
|
5018
5325
|
isRunning: snapshot.runningActionId === action.id,
|
|
5019
5326
|
label: action.label
|
|
5020
5327
|
})),
|
|
5021
|
-
description: options.description ??
|
|
5328
|
+
description: options.description ?? DEFAULT_DESCRIPTION7,
|
|
5022
5329
|
error: snapshot.error,
|
|
5023
5330
|
isRunning: snapshot.isRunning,
|
|
5024
5331
|
label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
|
|
5025
5332
|
lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
|
|
5026
5333
|
status,
|
|
5027
|
-
title: options.title ??
|
|
5334
|
+
title: options.title ?? DEFAULT_TITLE7
|
|
5028
5335
|
};
|
|
5029
5336
|
};
|
|
5030
5337
|
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
5031
5338
|
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
5032
|
-
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${
|
|
5033
|
-
${
|
|
5339
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml8(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
5340
|
+
${escapeHtml8(action.isRunning ? "Working..." : action.label)}
|
|
5034
5341
|
</button>`).join("");
|
|
5035
|
-
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${
|
|
5342
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml8(model.status)}">
|
|
5036
5343
|
<header class="absolute-voice-ops-action-center__header">
|
|
5037
|
-
<span class="absolute-voice-ops-action-center__eyebrow">${
|
|
5038
|
-
<strong class="absolute-voice-ops-action-center__label">${
|
|
5344
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml8(model.title)}</span>
|
|
5345
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml8(model.label)}</strong>
|
|
5039
5346
|
</header>
|
|
5040
|
-
<p class="absolute-voice-ops-action-center__description">${
|
|
5347
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml8(model.description)}</p>
|
|
5041
5348
|
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
5042
|
-
<p class="absolute-voice-ops-action-center__result">${
|
|
5043
|
-
${model.error ? `<p class="absolute-voice-ops-action-center__error">${
|
|
5349
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml8(model.lastResultLabel)}</p>
|
|
5350
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml8(model.error)}</p>` : ""}
|
|
5044
5351
|
</section>`;
|
|
5045
5352
|
};
|
|
5046
5353
|
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}`;
|
|
@@ -5641,7 +5948,7 @@ var exportVoiceTrace = async (input) => {
|
|
|
5641
5948
|
};
|
|
5642
5949
|
};
|
|
5643
5950
|
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
5644
|
-
var
|
|
5951
|
+
var escapeHtml9 = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5645
5952
|
var formatTraceValue = (value) => {
|
|
5646
5953
|
if (value === undefined || value === null) {
|
|
5647
5954
|
return "";
|
|
@@ -5921,10 +6228,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5921
6228
|
const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
|
|
5922
6229
|
return [
|
|
5923
6230
|
"<tr>",
|
|
5924
|
-
`<td>${
|
|
5925
|
-
`<td>${
|
|
5926
|
-
`<td>${
|
|
5927
|
-
`<td><code>${
|
|
6231
|
+
`<td>${escapeHtml9(String(offset))}</td>`,
|
|
6232
|
+
`<td>${escapeHtml9(event.type)}</td>`,
|
|
6233
|
+
`<td>${escapeHtml9(event.turnId ?? "")}</td>`,
|
|
6234
|
+
`<td><code>${escapeHtml9(JSON.stringify(event.payload))}</code></td>`,
|
|
5928
6235
|
"</tr>"
|
|
5929
6236
|
].join("");
|
|
5930
6237
|
}).join(`
|
|
@@ -5935,7 +6242,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5935
6242
|
"<head>",
|
|
5936
6243
|
'<meta charset="utf-8" />',
|
|
5937
6244
|
'<meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
5938
|
-
`<title>${
|
|
6245
|
+
`<title>${escapeHtml9(options.title ?? "Voice Trace")}</title>`,
|
|
5939
6246
|
"<style>",
|
|
5940
6247
|
"body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
|
|
5941
6248
|
"main{max-width:1100px;margin:auto}",
|
|
@@ -5949,7 +6256,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5949
6256
|
"</style>",
|
|
5950
6257
|
"</head>",
|
|
5951
6258
|
"<body><main>",
|
|
5952
|
-
`<h1>${
|
|
6259
|
+
`<h1>${escapeHtml9(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
|
|
5953
6260
|
`<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
|
|
5954
6261
|
'<section class="summary">',
|
|
5955
6262
|
`<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
|
|
@@ -5963,7 +6270,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
|
|
|
5963
6270
|
eventRows,
|
|
5964
6271
|
"</tbody></table>",
|
|
5965
6272
|
"<h2>Markdown Export</h2>",
|
|
5966
|
-
`<pre>${
|
|
6273
|
+
`<pre>${escapeHtml9(markdown)}</pre>`,
|
|
5967
6274
|
"</main></body></html>"
|
|
5968
6275
|
].join(`
|
|
5969
6276
|
`);
|
|
@@ -6319,7 +6626,7 @@ var ACTION_LABELS = {
|
|
|
6319
6626
|
"resume-assistant": "Resume assistant",
|
|
6320
6627
|
tag: "Tag"
|
|
6321
6628
|
};
|
|
6322
|
-
var
|
|
6629
|
+
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6323
6630
|
var createVoiceLiveOpsInput = (action, input) => ({
|
|
6324
6631
|
action,
|
|
6325
6632
|
assignee: input.assignee,
|
|
@@ -6330,17 +6637,17 @@ var createVoiceLiveOpsInput = (action, input) => ({
|
|
|
6330
6637
|
var renderVoiceLiveOpsHTML = (snapshot, options = {}) => {
|
|
6331
6638
|
const sessionId = options.getSessionId?.() ?? "";
|
|
6332
6639
|
const disabled = snapshot.isRunning || !sessionId;
|
|
6333
|
-
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${
|
|
6334
|
-
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${
|
|
6640
|
+
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml10(action)}"${disabled ? " disabled" : ""}>${escapeHtml10(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
|
|
6641
|
+
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml10(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml10(snapshot.lastResult.action)}. Control: ${escapeHtml10(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
|
|
6335
6642
|
return `<section class="absolute-voice-live-ops">
|
|
6336
6643
|
<header class="absolute-voice-live-ops__header">
|
|
6337
|
-
<span>${
|
|
6338
|
-
<strong>${
|
|
6644
|
+
<span>${escapeHtml10(options.title ?? "Live Ops")}</span>
|
|
6645
|
+
<strong>${escapeHtml10(sessionId || "No active session")}</strong>
|
|
6339
6646
|
</header>
|
|
6340
|
-
<p class="absolute-voice-live-ops__description">${
|
|
6341
|
-
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${
|
|
6342
|
-
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${
|
|
6343
|
-
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${
|
|
6647
|
+
<p class="absolute-voice-live-ops__description">${escapeHtml10(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
|
|
6648
|
+
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml10(options.defaultAssignee ?? "operator")}" /></label>
|
|
6649
|
+
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml10(options.defaultTag ?? "live-ops")}" /></label>
|
|
6650
|
+
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml10(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
|
|
6344
6651
|
<div class="absolute-voice-live-ops__actions">${actions}</div>
|
|
6345
6652
|
${result}
|
|
6346
6653
|
</section>`;
|
|
@@ -6427,16 +6734,16 @@ var defineVoiceLiveOpsElement = (tagName = "absolute-voice-live-ops", options =
|
|
|
6427
6734
|
});
|
|
6428
6735
|
};
|
|
6429
6736
|
// src/client/opsActionHistoryWidget.ts
|
|
6430
|
-
var
|
|
6737
|
+
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6431
6738
|
var renderVoiceOpsActionHistoryWidgetHTML = (snapshot, options = {}) => {
|
|
6432
6739
|
const report = snapshot.report;
|
|
6433
6740
|
const entries = (report?.entries ?? []).slice(0, options.limit ?? 5);
|
|
6434
|
-
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${
|
|
6741
|
+
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml11(entry.actionId)}</span><strong>${escapeHtml11(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml11(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
|
|
6435
6742
|
return `<section class="absolute-voice-ops-action-history">
|
|
6436
|
-
<header><span>Operator proof</span><strong>${
|
|
6743
|
+
<header><span>Operator proof</span><strong>${escapeHtml11(options.title ?? "Action History")}</strong></header>
|
|
6437
6744
|
<p>${String(report?.total ?? 0)} action(s), ${String(report?.failed ?? 0)} failed.</p>
|
|
6438
6745
|
<ul>${rows || "<li>No operator actions recorded yet.</li>"}</ul>
|
|
6439
|
-
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${
|
|
6746
|
+
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml11(snapshot.error)}</p>` : ""}
|
|
6440
6747
|
</section>`;
|
|
6441
6748
|
};
|
|
6442
6749
|
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}`;
|
|
@@ -6457,9 +6764,9 @@ var mountVoiceOpsActionHistory = (element, path = "/api/voice/ops-actions/histor
|
|
|
6457
6764
|
};
|
|
6458
6765
|
};
|
|
6459
6766
|
// src/client/deliveryRuntimeWidget.ts
|
|
6460
|
-
var
|
|
6461
|
-
var
|
|
6462
|
-
var
|
|
6767
|
+
var DEFAULT_TITLE8 = "Voice Delivery Runtime";
|
|
6768
|
+
var DEFAULT_DESCRIPTION8 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
6769
|
+
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6463
6770
|
var createSurface = (id, summary) => {
|
|
6464
6771
|
if (!summary) {
|
|
6465
6772
|
return {
|
|
@@ -6493,7 +6800,7 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
6493
6800
|
];
|
|
6494
6801
|
const hasWarnings = surfaces.some((surface) => surface.status === "warn");
|
|
6495
6802
|
return {
|
|
6496
|
-
description: options.description ??
|
|
6803
|
+
description: options.description ?? DEFAULT_DESCRIPTION8,
|
|
6497
6804
|
error: snapshot.error,
|
|
6498
6805
|
actionError: snapshot.actionError,
|
|
6499
6806
|
actionStatus: snapshot.actionStatus,
|
|
@@ -6502,32 +6809,32 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
6502
6809
|
label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
|
|
6503
6810
|
status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
|
|
6504
6811
|
surfaces,
|
|
6505
|
-
title: options.title ??
|
|
6812
|
+
title: options.title ?? DEFAULT_TITLE8,
|
|
6506
6813
|
updatedAt: snapshot.updatedAt
|
|
6507
6814
|
};
|
|
6508
6815
|
};
|
|
6509
6816
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
6510
6817
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
6511
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
6512
|
-
<span>${
|
|
6513
|
-
<strong>${
|
|
6818
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml12(surface.status)}">
|
|
6819
|
+
<span>${escapeHtml12(surface.label)}</span>
|
|
6820
|
+
<strong>${escapeHtml12(surface.detail)}</strong>
|
|
6514
6821
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
6515
6822
|
</li>`).join("");
|
|
6516
6823
|
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
6517
6824
|
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
6518
6825
|
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
6519
6826
|
</div>`;
|
|
6520
|
-
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
6521
|
-
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${
|
|
6827
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml12(model.actionError)}</p>` : "";
|
|
6828
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml12(model.status)}">
|
|
6522
6829
|
<header class="absolute-voice-delivery-runtime__header">
|
|
6523
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
6524
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
6830
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml12(model.title)}</span>
|
|
6831
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml12(model.label)}</strong>
|
|
6525
6832
|
</header>
|
|
6526
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
6833
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml12(model.description)}</p>
|
|
6527
6834
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
6528
6835
|
${actions}
|
|
6529
6836
|
${actionError}
|
|
6530
|
-
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
6837
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml12(model.error)}</p>` : ""}
|
|
6531
6838
|
</section>`;
|
|
6532
6839
|
};
|
|
6533
6840
|
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}`;
|
|
@@ -6663,11 +6970,11 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
6663
6970
|
};
|
|
6664
6971
|
};
|
|
6665
6972
|
// src/client/routingStatusWidget.ts
|
|
6666
|
-
var
|
|
6667
|
-
var
|
|
6668
|
-
var
|
|
6973
|
+
var DEFAULT_TITLE9 = "Voice Routing";
|
|
6974
|
+
var DEFAULT_DESCRIPTION9 = "Latest provider routing decision from the self-hosted trace store.";
|
|
6975
|
+
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6669
6976
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
6670
|
-
var
|
|
6977
|
+
var formatProviderRoutes2 = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
|
|
6671
6978
|
var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
|
|
6672
6979
|
var formatFallbackPath = (decision) => {
|
|
6673
6980
|
const provider = formatValue(decision.provider, "Unknown");
|
|
@@ -6724,7 +7031,7 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
6724
7031
|
},
|
|
6725
7032
|
{
|
|
6726
7033
|
label: "Default routes",
|
|
6727
|
-
value:
|
|
7034
|
+
value: formatProviderRoutes2(decision.providerRoutes)
|
|
6728
7035
|
},
|
|
6729
7036
|
{
|
|
6730
7037
|
label: "Latency budget",
|
|
@@ -6734,35 +7041,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
6734
7041
|
return {
|
|
6735
7042
|
activeStack,
|
|
6736
7043
|
decision,
|
|
6737
|
-
description: options.description ??
|
|
7044
|
+
description: options.description ?? DEFAULT_DESCRIPTION9,
|
|
6738
7045
|
error: snapshot.error,
|
|
6739
7046
|
isLoading: snapshot.isLoading,
|
|
6740
7047
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
6741
7048
|
rows,
|
|
6742
7049
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
6743
|
-
title: options.title ??
|
|
7050
|
+
title: options.title ?? DEFAULT_TITLE9,
|
|
6744
7051
|
updatedAt: snapshot.updatedAt
|
|
6745
7052
|
};
|
|
6746
7053
|
};
|
|
6747
7054
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
6748
7055
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
6749
7056
|
const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
|
|
6750
|
-
<span>${
|
|
6751
|
-
<strong>${
|
|
7057
|
+
<span>${escapeHtml13(item.label)}</span>
|
|
7058
|
+
<strong>${escapeHtml13(item.value)}</strong>
|
|
6752
7059
|
</div>`).join("")}</div>` : "";
|
|
6753
7060
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
6754
|
-
<span>${
|
|
6755
|
-
<strong>${
|
|
7061
|
+
<span>${escapeHtml13(row.label)}</span>
|
|
7062
|
+
<strong>${escapeHtml13(row.value)}</strong>
|
|
6756
7063
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
6757
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
7064
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml13(model.status)}">
|
|
6758
7065
|
<header class="absolute-voice-routing-status__header">
|
|
6759
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
6760
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
7066
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml13(model.title)}</span>
|
|
7067
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml13(model.label)}</strong>
|
|
6761
7068
|
</header>
|
|
6762
|
-
<p class="absolute-voice-routing-status__description">${
|
|
7069
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml13(model.description)}</p>
|
|
6763
7070
|
${activeStack}
|
|
6764
7071
|
${rows}
|
|
6765
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
7072
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml13(model.error)}</p>` : ""}
|
|
6766
7073
|
</section>`;
|
|
6767
7074
|
};
|
|
6768
7075
|
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}}`;
|
|
@@ -7561,7 +7868,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
7561
7868
|
};
|
|
7562
7869
|
};
|
|
7563
7870
|
// src/client/providerSimulationControlsWidget.ts
|
|
7564
|
-
var
|
|
7871
|
+
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7565
7872
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
7566
7873
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
7567
7874
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -7581,18 +7888,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
7581
7888
|
};
|
|
7582
7889
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
7583
7890
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
7584
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
7585
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
7891
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml14(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml14(provider.provider)} ${escapeHtml14(formatKind(options.kind))} failure</button>`).join("");
|
|
7892
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml14(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml14(provider.provider)} recovered</button>`).join("");
|
|
7586
7893
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
7587
7894
|
<header class="absolute-voice-provider-simulation__header">
|
|
7588
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
7589
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
7895
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml14(model.title)}</span>
|
|
7896
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml14(model.label)}</strong>
|
|
7590
7897
|
</header>
|
|
7591
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
7592
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
7898
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml14(model.description)}</p>
|
|
7899
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml14(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
7593
7900
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
7594
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
7595
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
7901
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml14(snapshot.error)}</p>` : ""}
|
|
7902
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml14(model.resultText)}</pre>` : ""}
|
|
7596
7903
|
</section>`;
|
|
7597
7904
|
};
|
|
7598
7905
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -7657,9 +7964,9 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
|
|
|
7657
7964
|
});
|
|
7658
7965
|
};
|
|
7659
7966
|
// src/client/providerStatusWidget.ts
|
|
7660
|
-
var
|
|
7661
|
-
var
|
|
7662
|
-
var
|
|
7967
|
+
var DEFAULT_TITLE10 = "Voice Providers";
|
|
7968
|
+
var DEFAULT_DESCRIPTION10 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
7969
|
+
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7663
7970
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
7664
7971
|
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
7665
7972
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -7703,37 +8010,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
7703
8010
|
const warningCount = providers.filter((provider) => isWarningStatus(provider.status)).length;
|
|
7704
8011
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
7705
8012
|
return {
|
|
7706
|
-
description: options.description ??
|
|
8013
|
+
description: options.description ?? DEFAULT_DESCRIPTION10,
|
|
7707
8014
|
error: snapshot.error,
|
|
7708
8015
|
isLoading: snapshot.isLoading,
|
|
7709
8016
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
7710
8017
|
providers,
|
|
7711
8018
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
7712
|
-
title: options.title ??
|
|
8019
|
+
title: options.title ?? DEFAULT_TITLE10,
|
|
7713
8020
|
updatedAt: snapshot.updatedAt
|
|
7714
8021
|
};
|
|
7715
8022
|
};
|
|
7716
8023
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
7717
8024
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
7718
|
-
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--${
|
|
8025
|
+
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--${escapeHtml15(provider.status)}">
|
|
7719
8026
|
<header>
|
|
7720
|
-
<strong>${
|
|
7721
|
-
<span>${
|
|
8027
|
+
<strong>${escapeHtml15(provider.label)}</strong>
|
|
8028
|
+
<span>${escapeHtml15(formatStatus2(provider.status))}</span>
|
|
7722
8029
|
</header>
|
|
7723
|
-
<p>${
|
|
8030
|
+
<p>${escapeHtml15(provider.detail)}</p>
|
|
7724
8031
|
<dl>${provider.rows.map((row) => `<div>
|
|
7725
|
-
<dt>${
|
|
7726
|
-
<dd>${
|
|
8032
|
+
<dt>${escapeHtml15(row.label)}</dt>
|
|
8033
|
+
<dd>${escapeHtml15(row.value)}</dd>
|
|
7727
8034
|
</div>`).join("")}</dl>
|
|
7728
8035
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
7729
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
8036
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml15(model.status)}">
|
|
7730
8037
|
<header class="absolute-voice-provider-status__header">
|
|
7731
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
7732
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
8038
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml15(model.title)}</span>
|
|
8039
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml15(model.label)}</strong>
|
|
7733
8040
|
</header>
|
|
7734
|
-
<p class="absolute-voice-provider-status__description">${
|
|
8041
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml15(model.description)}</p>
|
|
7735
8042
|
${providers}
|
|
7736
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
8043
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml15(model.error)}</p>` : ""}
|
|
7737
8044
|
</section>`;
|
|
7738
8045
|
};
|
|
7739
8046
|
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}`;
|
|
@@ -7774,9 +8081,9 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
7774
8081
|
});
|
|
7775
8082
|
};
|
|
7776
8083
|
// src/client/providerCapabilitiesWidget.ts
|
|
7777
|
-
var
|
|
7778
|
-
var
|
|
7779
|
-
var
|
|
8084
|
+
var DEFAULT_TITLE11 = "Provider Capabilities";
|
|
8085
|
+
var DEFAULT_DESCRIPTION11 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
8086
|
+
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7780
8087
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
7781
8088
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
7782
8089
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -7820,36 +8127,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
7820
8127
|
const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
|
|
7821
8128
|
return {
|
|
7822
8129
|
capabilities,
|
|
7823
|
-
description: options.description ??
|
|
8130
|
+
description: options.description ?? DEFAULT_DESCRIPTION11,
|
|
7824
8131
|
error: snapshot.error,
|
|
7825
8132
|
isLoading: snapshot.isLoading,
|
|
7826
8133
|
label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
|
|
7827
8134
|
status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
7828
|
-
title: options.title ??
|
|
8135
|
+
title: options.title ?? DEFAULT_TITLE11,
|
|
7829
8136
|
updatedAt: snapshot.updatedAt
|
|
7830
8137
|
};
|
|
7831
8138
|
};
|
|
7832
8139
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
7833
8140
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
7834
|
-
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--${
|
|
8141
|
+
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--${escapeHtml16(capability.status)}">
|
|
7835
8142
|
<header>
|
|
7836
|
-
<strong>${
|
|
7837
|
-
<span>${
|
|
8143
|
+
<strong>${escapeHtml16(capability.label)}</strong>
|
|
8144
|
+
<span>${escapeHtml16(formatStatus3(capability.status))}</span>
|
|
7838
8145
|
</header>
|
|
7839
|
-
<p>${
|
|
8146
|
+
<p>${escapeHtml16(capability.detail)}</p>
|
|
7840
8147
|
<dl>${capability.rows.map((row) => `<div>
|
|
7841
|
-
<dt>${
|
|
7842
|
-
<dd>${
|
|
8148
|
+
<dt>${escapeHtml16(row.label)}</dt>
|
|
8149
|
+
<dd>${escapeHtml16(row.value)}</dd>
|
|
7843
8150
|
</div>`).join("")}</dl>
|
|
7844
8151
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
7845
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
8152
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml16(model.status)}">
|
|
7846
8153
|
<header class="absolute-voice-provider-capabilities__header">
|
|
7847
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
7848
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
8154
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml16(model.title)}</span>
|
|
8155
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml16(model.label)}</strong>
|
|
7849
8156
|
</header>
|
|
7850
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
8157
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml16(model.description)}</p>
|
|
7851
8158
|
${capabilities}
|
|
7852
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
8159
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml16(model.error)}</p>` : ""}
|
|
7853
8160
|
</section>`;
|
|
7854
8161
|
};
|
|
7855
8162
|
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}`;
|
|
@@ -7890,9 +8197,9 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
|
|
|
7890
8197
|
});
|
|
7891
8198
|
};
|
|
7892
8199
|
// src/client/providerContractsWidget.ts
|
|
7893
|
-
var
|
|
7894
|
-
var
|
|
7895
|
-
var
|
|
8200
|
+
var DEFAULT_TITLE12 = "Provider Contracts";
|
|
8201
|
+
var DEFAULT_DESCRIPTION12 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
8202
|
+
var escapeHtml17 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7896
8203
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
7897
8204
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
7898
8205
|
var contractDetail = (row) => {
|
|
@@ -7924,38 +8231,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
7924
8231
|
}));
|
|
7925
8232
|
const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
|
|
7926
8233
|
return {
|
|
7927
|
-
description: options.description ??
|
|
8234
|
+
description: options.description ?? DEFAULT_DESCRIPTION12,
|
|
7928
8235
|
error: snapshot.error,
|
|
7929
8236
|
isLoading: snapshot.isLoading,
|
|
7930
8237
|
label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
|
|
7931
8238
|
rows,
|
|
7932
8239
|
status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
7933
|
-
title: options.title ??
|
|
8240
|
+
title: options.title ?? DEFAULT_TITLE12,
|
|
7934
8241
|
updatedAt: snapshot.updatedAt
|
|
7935
8242
|
};
|
|
7936
8243
|
};
|
|
7937
8244
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
7938
8245
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
7939
|
-
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--${
|
|
8246
|
+
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--${escapeHtml17(row.status)}">
|
|
7940
8247
|
<header>
|
|
7941
|
-
<strong>${
|
|
7942
|
-
<span>${
|
|
8248
|
+
<strong>${escapeHtml17(row.label)}</strong>
|
|
8249
|
+
<span>${escapeHtml17(formatStatus4(row.status))}</span>
|
|
7943
8250
|
</header>
|
|
7944
|
-
<p>${
|
|
7945
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
8251
|
+
<p>${escapeHtml17(row.detail)}</p>
|
|
8252
|
+
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml17(remediation.href)}">${escapeHtml17(remediation.label)}</a>` : `<strong>${escapeHtml17(remediation.label)}</strong>`}<span>${escapeHtml17(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
|
|
7946
8253
|
<dl>${row.rows.map((item) => `<div>
|
|
7947
|
-
<dt>${
|
|
7948
|
-
<dd>${
|
|
8254
|
+
<dt>${escapeHtml17(item.label)}</dt>
|
|
8255
|
+
<dd>${escapeHtml17(item.value)}</dd>
|
|
7949
8256
|
</div>`).join("")}</dl>
|
|
7950
8257
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
7951
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
8258
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml17(model.status)}">
|
|
7952
8259
|
<header class="absolute-voice-provider-contracts__header">
|
|
7953
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
7954
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
8260
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml17(model.title)}</span>
|
|
8261
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml17(model.label)}</strong>
|
|
7955
8262
|
</header>
|
|
7956
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
8263
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml17(model.description)}</p>
|
|
7957
8264
|
${rows}
|
|
7958
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
8265
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml17(model.error)}</p>` : ""}
|
|
7959
8266
|
</section>`;
|
|
7960
8267
|
};
|
|
7961
8268
|
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}`;
|
|
@@ -7996,9 +8303,9 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
|
|
|
7996
8303
|
});
|
|
7997
8304
|
};
|
|
7998
8305
|
// src/client/turnQualityWidget.ts
|
|
7999
|
-
var
|
|
8000
|
-
var
|
|
8001
|
-
var
|
|
8306
|
+
var DEFAULT_TITLE13 = "Turn Quality";
|
|
8307
|
+
var DEFAULT_DESCRIPTION13 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
8308
|
+
var escapeHtml18 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8002
8309
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
8003
8310
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
8004
8311
|
var getTurnDetail = (turn) => {
|
|
@@ -8036,37 +8343,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
8036
8343
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
8037
8344
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
8038
8345
|
return {
|
|
8039
|
-
description: options.description ??
|
|
8346
|
+
description: options.description ?? DEFAULT_DESCRIPTION13,
|
|
8040
8347
|
error: snapshot.error,
|
|
8041
8348
|
isLoading: snapshot.isLoading,
|
|
8042
8349
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
8043
8350
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
8044
|
-
title: options.title ??
|
|
8351
|
+
title: options.title ?? DEFAULT_TITLE13,
|
|
8045
8352
|
turns,
|
|
8046
8353
|
updatedAt: snapshot.updatedAt
|
|
8047
8354
|
};
|
|
8048
8355
|
};
|
|
8049
8356
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
8050
8357
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
8051
|
-
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--${
|
|
8358
|
+
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--${escapeHtml18(turn.status)}">
|
|
8052
8359
|
<header>
|
|
8053
|
-
<strong>${
|
|
8054
|
-
<span>${
|
|
8360
|
+
<strong>${escapeHtml18(turn.label)}</strong>
|
|
8361
|
+
<span>${escapeHtml18(turn.status)}</span>
|
|
8055
8362
|
</header>
|
|
8056
|
-
<p>${
|
|
8363
|
+
<p>${escapeHtml18(turn.detail)}</p>
|
|
8057
8364
|
<dl>${turn.rows.map((row) => `<div>
|
|
8058
|
-
<dt>${
|
|
8059
|
-
<dd>${
|
|
8365
|
+
<dt>${escapeHtml18(row.label)}</dt>
|
|
8366
|
+
<dd>${escapeHtml18(row.value)}</dd>
|
|
8060
8367
|
</div>`).join("")}</dl>
|
|
8061
8368
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
8062
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
8369
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml18(model.status)}">
|
|
8063
8370
|
<header class="absolute-voice-turn-quality__header">
|
|
8064
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
8065
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
8371
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml18(model.title)}</span>
|
|
8372
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml18(model.label)}</strong>
|
|
8066
8373
|
</header>
|
|
8067
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
8374
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml18(model.description)}</p>
|
|
8068
8375
|
${turns}
|
|
8069
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
8376
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml18(model.error)}</p>` : ""}
|
|
8070
8377
|
</section>`;
|
|
8071
8378
|
};
|
|
8072
8379
|
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}`;
|
|
@@ -8107,56 +8414,56 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
8107
8414
|
});
|
|
8108
8415
|
};
|
|
8109
8416
|
// src/client/turnLatencyWidget.ts
|
|
8110
|
-
var
|
|
8111
|
-
var
|
|
8417
|
+
var DEFAULT_TITLE14 = "Turn Latency";
|
|
8418
|
+
var DEFAULT_DESCRIPTION14 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
8112
8419
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
8113
|
-
var
|
|
8114
|
-
var
|
|
8420
|
+
var escapeHtml19 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8421
|
+
var formatMs3 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
8115
8422
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
8116
8423
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
8117
8424
|
...turn,
|
|
8118
8425
|
label: turn.text || "Empty turn",
|
|
8119
8426
|
rows: turn.stages.map((stage) => ({
|
|
8120
8427
|
label: stage.label,
|
|
8121
|
-
value:
|
|
8428
|
+
value: formatMs3(stage.valueMs)
|
|
8122
8429
|
}))
|
|
8123
8430
|
}));
|
|
8124
8431
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
8125
8432
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
8126
8433
|
return {
|
|
8127
|
-
description: options.description ??
|
|
8434
|
+
description: options.description ?? DEFAULT_DESCRIPTION14,
|
|
8128
8435
|
error: snapshot.error,
|
|
8129
8436
|
isLoading: snapshot.isLoading,
|
|
8130
|
-
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${
|
|
8437
|
+
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs3(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
8131
8438
|
proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
|
|
8132
8439
|
showProofAction: Boolean(options.proofPath),
|
|
8133
8440
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
8134
|
-
title: options.title ??
|
|
8441
|
+
title: options.title ?? DEFAULT_TITLE14,
|
|
8135
8442
|
turns,
|
|
8136
8443
|
updatedAt: snapshot.updatedAt
|
|
8137
8444
|
};
|
|
8138
8445
|
};
|
|
8139
8446
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
8140
8447
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
8141
|
-
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--${
|
|
8448
|
+
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--${escapeHtml19(turn.status)}">
|
|
8142
8449
|
<header>
|
|
8143
|
-
<strong>${
|
|
8144
|
-
<span>${
|
|
8450
|
+
<strong>${escapeHtml19(turn.label)}</strong>
|
|
8451
|
+
<span>${escapeHtml19(turn.status)}</span>
|
|
8145
8452
|
</header>
|
|
8146
8453
|
<dl>${turn.rows.map((row) => `<div>
|
|
8147
|
-
<dt>${
|
|
8148
|
-
<dd>${
|
|
8454
|
+
<dt>${escapeHtml19(row.label)}</dt>
|
|
8455
|
+
<dd>${escapeHtml19(row.value)}</dd>
|
|
8149
8456
|
</div>`).join("")}</dl>
|
|
8150
8457
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
8151
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
8458
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml19(model.status)}">
|
|
8152
8459
|
<header class="absolute-voice-turn-latency__header">
|
|
8153
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
8154
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
8460
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml19(model.title)}</span>
|
|
8461
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml19(model.label)}</strong>
|
|
8155
8462
|
</header>
|
|
8156
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
8157
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
8463
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml19(model.description)}</p>
|
|
8464
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml19(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
8158
8465
|
${turns}
|
|
8159
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
8466
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml19(model.error)}</p>` : ""}
|
|
8160
8467
|
</section>`;
|
|
8161
8468
|
};
|
|
8162
8469
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -8206,16 +8513,16 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
8206
8513
|
});
|
|
8207
8514
|
};
|
|
8208
8515
|
// src/client/traceTimelineWidget.ts
|
|
8209
|
-
var
|
|
8210
|
-
var
|
|
8211
|
-
var
|
|
8212
|
-
var
|
|
8516
|
+
var DEFAULT_TITLE15 = "Voice Traces";
|
|
8517
|
+
var DEFAULT_DESCRIPTION15 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
8518
|
+
var escapeHtml20 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8519
|
+
var formatMs4 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
8213
8520
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
8214
8521
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
8215
8522
|
const sessions = (snapshot.report?.sessions ?? []).slice(0, options.limit ?? 3).map((session) => ({
|
|
8216
8523
|
...session,
|
|
8217
8524
|
detailHref: `${options.detailBasePath ?? "/traces"}/${encodeURIComponent(session.sessionId)}`,
|
|
8218
|
-
durationLabel:
|
|
8525
|
+
durationLabel: formatMs4(session.summary.callDurationMs),
|
|
8219
8526
|
incidentBundleHref: options.incidentBundleBasePath === false ? undefined : `${options.incidentBundleBasePath ?? "/voice-incidents"}/${encodeURIComponent(session.sessionId)}/markdown`,
|
|
8220
8527
|
label: `${session.summary.eventCount} events / ${session.summary.turnCount} turns`,
|
|
8221
8528
|
operationsRecordHref: options.operationsRecordBasePath === false ? undefined : `${options.operationsRecordBasePath ?? "/voice-operations"}/${encodeURIComponent(session.sessionId)}`,
|
|
@@ -8224,13 +8531,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
|
8224
8531
|
const failed = sessions.filter((session) => session.status === "failed").length;
|
|
8225
8532
|
const warnings = sessions.filter((session) => session.status === "warning").length;
|
|
8226
8533
|
return {
|
|
8227
|
-
description: options.description ??
|
|
8534
|
+
description: options.description ?? DEFAULT_DESCRIPTION15,
|
|
8228
8535
|
error: snapshot.error,
|
|
8229
8536
|
isLoading: snapshot.isLoading,
|
|
8230
8537
|
label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
|
|
8231
8538
|
sessions,
|
|
8232
8539
|
status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
8233
|
-
title: options.title ??
|
|
8540
|
+
title: options.title ?? DEFAULT_TITLE15,
|
|
8234
8541
|
updatedAt: snapshot.updatedAt
|
|
8235
8542
|
};
|
|
8236
8543
|
};
|
|
@@ -8238,27 +8545,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
8238
8545
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
8239
8546
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
8240
8547
|
const supportLinks = [
|
|
8241
|
-
`<a href="${
|
|
8242
|
-
session.operationsRecordHref ? `<a href="${
|
|
8243
|
-
session.incidentBundleHref ? `<a href="${
|
|
8548
|
+
`<a href="${escapeHtml20(session.detailHref)}">Open timeline</a>`,
|
|
8549
|
+
session.operationsRecordHref ? `<a href="${escapeHtml20(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
8550
|
+
session.incidentBundleHref ? `<a href="${escapeHtml20(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
8244
8551
|
].filter(Boolean).join("");
|
|
8245
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
8552
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml20(session.status)}">
|
|
8246
8553
|
<header>
|
|
8247
|
-
<strong>${
|
|
8248
|
-
<span>${
|
|
8554
|
+
<strong>${escapeHtml20(session.sessionId)}</strong>
|
|
8555
|
+
<span>${escapeHtml20(session.status)}</span>
|
|
8249
8556
|
</header>
|
|
8250
|
-
<p>${
|
|
8557
|
+
<p>${escapeHtml20(session.label)} \xB7 ${escapeHtml20(session.durationLabel)} \xB7 ${escapeHtml20(session.providerLabel)}</p>
|
|
8251
8558
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
8252
8559
|
</article>`;
|
|
8253
8560
|
}).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
8254
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
8561
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml20(model.status)}">
|
|
8255
8562
|
<header class="absolute-voice-trace-timeline__header">
|
|
8256
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
8257
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
8563
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml20(model.title)}</span>
|
|
8564
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml20(model.label)}</strong>
|
|
8258
8565
|
</header>
|
|
8259
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
8566
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml20(model.description)}</p>
|
|
8260
8567
|
${sessions}
|
|
8261
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
8568
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml20(model.error)}</p>` : ""}
|
|
8262
8569
|
</section>`;
|
|
8263
8570
|
};
|
|
8264
8571
|
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}`;
|
|
@@ -8304,9 +8611,9 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
|
|
|
8304
8611
|
});
|
|
8305
8612
|
};
|
|
8306
8613
|
// src/client/agentSquadStatusWidget.ts
|
|
8307
|
-
var
|
|
8308
|
-
var
|
|
8309
|
-
var
|
|
8614
|
+
var DEFAULT_TITLE16 = "Voice Agent Squad";
|
|
8615
|
+
var DEFAULT_DESCRIPTION16 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
8616
|
+
var escapeHtml21 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8310
8617
|
var labelFor = (current) => {
|
|
8311
8618
|
if (!current)
|
|
8312
8619
|
return "Waiting for specialist activity";
|
|
@@ -8320,37 +8627,37 @@ var labelFor = (current) => {
|
|
|
8320
8627
|
};
|
|
8321
8628
|
var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
|
|
8322
8629
|
current: snapshot.report.current,
|
|
8323
|
-
description: options.description ??
|
|
8630
|
+
description: options.description ?? DEFAULT_DESCRIPTION16,
|
|
8324
8631
|
error: snapshot.error,
|
|
8325
8632
|
isLoading: snapshot.isLoading,
|
|
8326
8633
|
label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
|
|
8327
8634
|
sessionCount: snapshot.report.sessionCount,
|
|
8328
8635
|
sessions: snapshot.report.sessions,
|
|
8329
|
-
title: options.title ??
|
|
8636
|
+
title: options.title ?? DEFAULT_TITLE16,
|
|
8330
8637
|
updatedAt: snapshot.updatedAt
|
|
8331
8638
|
});
|
|
8332
8639
|
var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
8333
8640
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
8334
8641
|
const current = model.current;
|
|
8335
8642
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
8336
|
-
<span>${
|
|
8337
|
-
<strong>${
|
|
8338
|
-
<em>${
|
|
8339
|
-
${session.summary || session.reason ? `<p>${
|
|
8643
|
+
<span>${escapeHtml21(session.sessionId)}</span>
|
|
8644
|
+
<strong>${escapeHtml21(session.targetAgentId ?? "none")}</strong>
|
|
8645
|
+
<em>${escapeHtml21(session.status)}</em>
|
|
8646
|
+
${session.summary || session.reason ? `<p>${escapeHtml21(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
8340
8647
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
8341
8648
|
return `<section class="absolute-voice-agent-squad-status">
|
|
8342
8649
|
<header>
|
|
8343
|
-
<span>${
|
|
8344
|
-
<strong>${
|
|
8650
|
+
<span>${escapeHtml21(model.title)}</span>
|
|
8651
|
+
<strong>${escapeHtml21(model.label)}</strong>
|
|
8345
8652
|
</header>
|
|
8346
|
-
<p>${
|
|
8653
|
+
<p>${escapeHtml21(model.description)}</p>
|
|
8347
8654
|
<div>
|
|
8348
|
-
<span>Session</span><strong>${
|
|
8349
|
-
<span>From</span><strong>${
|
|
8350
|
-
<span>Status</span><strong>${
|
|
8655
|
+
<span>Session</span><strong>${escapeHtml21(current?.sessionId ?? "n/a")}</strong>
|
|
8656
|
+
<span>From</span><strong>${escapeHtml21(current?.fromAgentId ?? "n/a")}</strong>
|
|
8657
|
+
<span>Status</span><strong>${escapeHtml21(current?.status ?? "idle")}</strong>
|
|
8351
8658
|
</div>
|
|
8352
8659
|
<ul>${rows}</ul>
|
|
8353
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
8660
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml21(model.error)}</p>` : ""}
|
|
8354
8661
|
</section>`;
|
|
8355
8662
|
};
|
|
8356
8663
|
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}`;
|
|
@@ -8486,6 +8793,8 @@ export {
|
|
|
8486
8793
|
renderVoiceProviderContractsHTML,
|
|
8487
8794
|
renderVoiceProviderCapabilitiesHTML,
|
|
8488
8795
|
renderVoiceProofTrendsHTML,
|
|
8796
|
+
renderVoiceProfileSwitchRecommendationHTML,
|
|
8797
|
+
renderVoiceProfileComparisonHTML,
|
|
8489
8798
|
renderVoicePlatformCoverageHTML,
|
|
8490
8799
|
renderVoiceOpsStatusHTML,
|
|
8491
8800
|
renderVoiceOpsActionHistoryWidgetHTML,
|
|
@@ -8505,6 +8814,8 @@ export {
|
|
|
8505
8814
|
mountVoiceProviderContracts,
|
|
8506
8815
|
mountVoiceProviderCapabilities,
|
|
8507
8816
|
mountVoiceProofTrends,
|
|
8817
|
+
mountVoiceProfileSwitchRecommendation,
|
|
8818
|
+
mountVoiceProfileComparison,
|
|
8508
8819
|
mountVoicePlatformCoverage,
|
|
8509
8820
|
mountVoiceOpsStatus,
|
|
8510
8821
|
mountVoiceOpsActionHistory,
|
|
@@ -8520,6 +8831,8 @@ export {
|
|
|
8520
8831
|
getVoiceProviderContractsCSS,
|
|
8521
8832
|
getVoiceProviderCapabilitiesCSS,
|
|
8522
8833
|
getVoiceProofTrendsCSS,
|
|
8834
|
+
getVoiceProfileSwitchRecommendationCSS,
|
|
8835
|
+
getVoiceProfileComparisonCSS,
|
|
8523
8836
|
getVoicePlatformCoverageCSS,
|
|
8524
8837
|
getVoiceOpsStatusLabel,
|
|
8525
8838
|
getVoiceOpsStatusCSS,
|
|
@@ -8538,6 +8851,8 @@ export {
|
|
|
8538
8851
|
fetchVoiceProviderContracts,
|
|
8539
8852
|
fetchVoiceProviderCapabilities,
|
|
8540
8853
|
fetchVoiceProofTrends,
|
|
8854
|
+
fetchVoiceProfileSwitchRecommendation,
|
|
8855
|
+
fetchVoiceProfileComparison,
|
|
8541
8856
|
fetchVoicePlatformCoverage,
|
|
8542
8857
|
fetchVoiceOpsStatus,
|
|
8543
8858
|
fetchVoiceOpsActionHistory,
|
|
@@ -8553,6 +8868,8 @@ export {
|
|
|
8553
8868
|
defineVoiceProviderContractsElement,
|
|
8554
8869
|
defineVoiceProviderCapabilitiesElement,
|
|
8555
8870
|
defineVoiceProofTrendsElement,
|
|
8871
|
+
defineVoiceProfileSwitchRecommendationElement,
|
|
8872
|
+
defineVoiceProfileComparisonElement,
|
|
8556
8873
|
defineVoicePlatformCoverageElement,
|
|
8557
8874
|
defineVoiceOpsStatusElement,
|
|
8558
8875
|
defineVoiceOpsActionCenterElement,
|
|
@@ -8582,6 +8899,9 @@ export {
|
|
|
8582
8899
|
createVoiceProviderCapabilitiesStore,
|
|
8583
8900
|
createVoiceProofTrendsViewModel,
|
|
8584
8901
|
createVoiceProofTrendsStore,
|
|
8902
|
+
createVoiceProfileSwitchRecommendationStore,
|
|
8903
|
+
createVoiceProfileComparisonViewModel,
|
|
8904
|
+
createVoiceProfileComparisonStore,
|
|
8585
8905
|
createVoicePlatformCoverageViewModel,
|
|
8586
8906
|
createVoicePlatformCoverageStore,
|
|
8587
8907
|
createVoiceOpsStatusViewModel,
|