@absolutejs/voice 0.0.22-beta.404 → 0.0.22-beta.405
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 +333 -214
- package/dist/angular/voice-call-debugger.service.d.ts +12 -0
- package/dist/react/VoiceCallDebuggerLaunch.d.ts +6 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +739 -483
- package/dist/react/useVoiceCallDebugger.d.ts +8 -0
- package/dist/svelte/createVoiceCallDebugger.d.ts +12 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +338 -152
- package/dist/vue/VoiceCallDebuggerLaunch.d.ts +68 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.js +628 -364
- package/dist/vue/useVoiceCallDebugger.d.ts +10 -0
- package/package.json +1 -1
package/dist/svelte/index.js
CHANGED
|
@@ -2629,6 +2629,191 @@ var createVoiceProofTrends = (path = "/api/voice/proof-trends", options = {}) =>
|
|
|
2629
2629
|
subscribe: store.subscribe
|
|
2630
2630
|
};
|
|
2631
2631
|
};
|
|
2632
|
+
// src/client/callDebugger.ts
|
|
2633
|
+
var fetchVoiceCallDebugger = async (path, options = {}) => {
|
|
2634
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
2635
|
+
const response = await fetchImpl(path);
|
|
2636
|
+
if (!response.ok) {
|
|
2637
|
+
throw new Error(`Voice call debugger failed: HTTP ${response.status}`);
|
|
2638
|
+
}
|
|
2639
|
+
return await response.json();
|
|
2640
|
+
};
|
|
2641
|
+
var createVoiceCallDebuggerStore = (path, options = {}) => {
|
|
2642
|
+
const listeners = new Set;
|
|
2643
|
+
let closed = false;
|
|
2644
|
+
let timer;
|
|
2645
|
+
let snapshot = {
|
|
2646
|
+
error: null,
|
|
2647
|
+
isLoading: false
|
|
2648
|
+
};
|
|
2649
|
+
const emit = () => {
|
|
2650
|
+
for (const listener of listeners) {
|
|
2651
|
+
listener();
|
|
2652
|
+
}
|
|
2653
|
+
};
|
|
2654
|
+
const refresh = async () => {
|
|
2655
|
+
if (closed) {
|
|
2656
|
+
return snapshot.report;
|
|
2657
|
+
}
|
|
2658
|
+
snapshot = { ...snapshot, error: null, isLoading: true };
|
|
2659
|
+
emit();
|
|
2660
|
+
try {
|
|
2661
|
+
const report = await fetchVoiceCallDebugger(path, options);
|
|
2662
|
+
snapshot = {
|
|
2663
|
+
error: null,
|
|
2664
|
+
isLoading: false,
|
|
2665
|
+
report,
|
|
2666
|
+
updatedAt: Date.now()
|
|
2667
|
+
};
|
|
2668
|
+
emit();
|
|
2669
|
+
return report;
|
|
2670
|
+
} catch (error) {
|
|
2671
|
+
snapshot = {
|
|
2672
|
+
...snapshot,
|
|
2673
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2674
|
+
isLoading: false
|
|
2675
|
+
};
|
|
2676
|
+
emit();
|
|
2677
|
+
throw error;
|
|
2678
|
+
}
|
|
2679
|
+
};
|
|
2680
|
+
const close = () => {
|
|
2681
|
+
closed = true;
|
|
2682
|
+
if (timer) {
|
|
2683
|
+
clearInterval(timer);
|
|
2684
|
+
timer = undefined;
|
|
2685
|
+
}
|
|
2686
|
+
listeners.clear();
|
|
2687
|
+
};
|
|
2688
|
+
if (options.intervalMs && options.intervalMs > 0) {
|
|
2689
|
+
timer = setInterval(() => {
|
|
2690
|
+
refresh().catch(() => {});
|
|
2691
|
+
}, options.intervalMs);
|
|
2692
|
+
}
|
|
2693
|
+
return {
|
|
2694
|
+
close,
|
|
2695
|
+
getServerSnapshot: () => snapshot,
|
|
2696
|
+
getSnapshot: () => snapshot,
|
|
2697
|
+
refresh,
|
|
2698
|
+
subscribe: (listener) => {
|
|
2699
|
+
listeners.add(listener);
|
|
2700
|
+
return () => {
|
|
2701
|
+
listeners.delete(listener);
|
|
2702
|
+
};
|
|
2703
|
+
}
|
|
2704
|
+
};
|
|
2705
|
+
};
|
|
2706
|
+
|
|
2707
|
+
// src/client/callDebuggerWidget.ts
|
|
2708
|
+
var DEFAULT_TITLE4 = "Call Debugger";
|
|
2709
|
+
var DEFAULT_DESCRIPTION4 = "Open the latest call artifact with snapshot, operations record, failure replay, provider path, transcript, and incident markdown.";
|
|
2710
|
+
var DEFAULT_LINK_LABEL = "Open debugger";
|
|
2711
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2712
|
+
var defaultHref = (path, report) => {
|
|
2713
|
+
if (path.startsWith("/api/voice-call-debugger/")) {
|
|
2714
|
+
return path.replace("/api/voice-call-debugger/", "/voice-call-debugger/");
|
|
2715
|
+
}
|
|
2716
|
+
return report ? `/voice-call-debugger/${encodeURIComponent(report.sessionId)}` : path;
|
|
2717
|
+
};
|
|
2718
|
+
var resolveHref = (path, state, options) => {
|
|
2719
|
+
if (typeof options.href === "function") {
|
|
2720
|
+
return options.href({ report: state.report });
|
|
2721
|
+
}
|
|
2722
|
+
return options.href ?? defaultHref(path, state.report);
|
|
2723
|
+
};
|
|
2724
|
+
var createVoiceCallDebuggerLaunchViewModel = (path, state, options = {}) => {
|
|
2725
|
+
const report = state.report;
|
|
2726
|
+
const href = resolveHref(path, state, options);
|
|
2727
|
+
return {
|
|
2728
|
+
description: options.description ?? DEFAULT_DESCRIPTION4,
|
|
2729
|
+
error: state.error,
|
|
2730
|
+
href,
|
|
2731
|
+
isLoading: state.isLoading,
|
|
2732
|
+
label: state.error ? "Unavailable" : report ? `${report.status} \xB7 ${report.sessionId}` : state.isLoading ? "Loading" : "No call loaded",
|
|
2733
|
+
rows: report ? [
|
|
2734
|
+
{ label: "Events", value: String(report.operationsRecord.summary.eventCount) },
|
|
2735
|
+
{ label: "Turns", value: String(report.operationsRecord.summary.turnCount) },
|
|
2736
|
+
{ label: "Errors", value: String(report.operationsRecord.summary.errorCount) },
|
|
2737
|
+
{
|
|
2738
|
+
label: "Provider recovery",
|
|
2739
|
+
value: report.operationsRecord.providerDecisionSummary.recoveryStatus
|
|
2740
|
+
},
|
|
2741
|
+
{
|
|
2742
|
+
label: "Fallbacks",
|
|
2743
|
+
value: String(report.operationsRecord.providerDecisionSummary.fallbacks)
|
|
2744
|
+
},
|
|
2745
|
+
{ label: "Snapshot", value: report.snapshot.status }
|
|
2746
|
+
] : [],
|
|
2747
|
+
status: state.error ? "error" : report ? report.status === "healthy" ? "ready" : "warning" : state.isLoading ? "loading" : "empty",
|
|
2748
|
+
title: options.title ?? DEFAULT_TITLE4,
|
|
2749
|
+
updatedAt: state.updatedAt
|
|
2750
|
+
};
|
|
2751
|
+
};
|
|
2752
|
+
var renderVoiceCallDebuggerLaunchHTML = (path, state, options = {}) => {
|
|
2753
|
+
const model = createVoiceCallDebuggerLaunchViewModel(path, state, options);
|
|
2754
|
+
const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
|
|
2755
|
+
<dt>${escapeHtml6(row.label)}</dt>
|
|
2756
|
+
<dd>${escapeHtml6(row.value)}</dd>
|
|
2757
|
+
</div>`).join("")}</dl>` : '<p class="absolute-voice-call-debugger-launch__empty">Load a call debugger report to see the latest support artifact.</p>';
|
|
2758
|
+
return `<section class="absolute-voice-call-debugger-launch absolute-voice-call-debugger-launch--${escapeHtml6(model.status)}">
|
|
2759
|
+
<header class="absolute-voice-call-debugger-launch__header">
|
|
2760
|
+
<span class="absolute-voice-call-debugger-launch__eyebrow">${escapeHtml6(model.title)}</span>
|
|
2761
|
+
<strong class="absolute-voice-call-debugger-launch__label">${escapeHtml6(model.label)}</strong>
|
|
2762
|
+
</header>
|
|
2763
|
+
<p class="absolute-voice-call-debugger-launch__description">${escapeHtml6(model.description)}</p>
|
|
2764
|
+
<a class="absolute-voice-call-debugger-launch__link" href="${escapeHtml6(model.href)}">${escapeHtml6(options.linkLabel ?? DEFAULT_LINK_LABEL)}</a>
|
|
2765
|
+
${rows}
|
|
2766
|
+
${model.error ? `<p class="absolute-voice-call-debugger-launch__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
2767
|
+
</section>`;
|
|
2768
|
+
};
|
|
2769
|
+
var mountVoiceCallDebuggerLaunch = (element, path, options = {}) => {
|
|
2770
|
+
const store = createVoiceCallDebuggerStore(path, options);
|
|
2771
|
+
const render = () => {
|
|
2772
|
+
element.innerHTML = renderVoiceCallDebuggerLaunchHTML(path, store.getSnapshot(), options);
|
|
2773
|
+
};
|
|
2774
|
+
const unsubscribe = store.subscribe(render);
|
|
2775
|
+
render();
|
|
2776
|
+
store.refresh().catch(() => {});
|
|
2777
|
+
return {
|
|
2778
|
+
close: () => {
|
|
2779
|
+
unsubscribe();
|
|
2780
|
+
store.close();
|
|
2781
|
+
},
|
|
2782
|
+
refresh: store.refresh
|
|
2783
|
+
};
|
|
2784
|
+
};
|
|
2785
|
+
var defineVoiceCallDebuggerLaunchElement = (tagName = "absolute-voice-call-debugger-launch") => {
|
|
2786
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
2787
|
+
return;
|
|
2788
|
+
}
|
|
2789
|
+
customElements.define(tagName, class AbsoluteVoiceCallDebuggerLaunchElement extends HTMLElement {
|
|
2790
|
+
mounted;
|
|
2791
|
+
connectedCallback() {
|
|
2792
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 0);
|
|
2793
|
+
this.mounted = mountVoiceCallDebuggerLaunch(this, this.getAttribute("path") ?? "/api/voice-call-debugger/latest", {
|
|
2794
|
+
description: this.getAttribute("description") ?? undefined,
|
|
2795
|
+
href: this.getAttribute("href") ?? undefined,
|
|
2796
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 0,
|
|
2797
|
+
linkLabel: this.getAttribute("link-label") ?? undefined,
|
|
2798
|
+
title: this.getAttribute("title") ?? undefined
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
disconnectedCallback() {
|
|
2802
|
+
this.mounted?.close();
|
|
2803
|
+
this.mounted = undefined;
|
|
2804
|
+
}
|
|
2805
|
+
});
|
|
2806
|
+
};
|
|
2807
|
+
|
|
2808
|
+
// src/svelte/createVoiceCallDebugger.ts
|
|
2809
|
+
var createVoiceCallDebugger = (path, options = {}) => {
|
|
2810
|
+
const store = createVoiceCallDebuggerStore(path, options);
|
|
2811
|
+
return {
|
|
2812
|
+
...store,
|
|
2813
|
+
getHTML: () => renderVoiceCallDebuggerLaunchHTML(path, store.getSnapshot(), options),
|
|
2814
|
+
getViewModel: () => createVoiceCallDebuggerLaunchViewModel(path, store.getSnapshot(), options)
|
|
2815
|
+
};
|
|
2816
|
+
};
|
|
2632
2817
|
// src/client/sessionSnapshot.ts
|
|
2633
2818
|
var withTurnId = (path, turnId) => {
|
|
2634
2819
|
if (!turnId) {
|
|
@@ -2723,10 +2908,10 @@ var createVoiceSessionSnapshotStore = (path, options = {}) => {
|
|
|
2723
2908
|
};
|
|
2724
2909
|
|
|
2725
2910
|
// src/client/sessionSnapshotWidget.ts
|
|
2726
|
-
var
|
|
2727
|
-
var
|
|
2911
|
+
var DEFAULT_TITLE5 = "Session Snapshot";
|
|
2912
|
+
var DEFAULT_DESCRIPTION5 = "Portable call artifact with media graph, provider routing, proof, quality, and telephony evidence.";
|
|
2728
2913
|
var DEFAULT_DOWNLOAD_LABEL = "Download snapshot";
|
|
2729
|
-
var
|
|
2914
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2730
2915
|
var formatStatus = (status) => status ?? "n/a";
|
|
2731
2916
|
var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
2732
2917
|
const snapshot = state.snapshot;
|
|
@@ -2742,7 +2927,7 @@ var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
|
2742
2927
|
label: artifact.label,
|
|
2743
2928
|
status: formatStatus(artifact.status)
|
|
2744
2929
|
})) ?? [],
|
|
2745
|
-
description: options.description ??
|
|
2930
|
+
description: options.description ?? DEFAULT_DESCRIPTION5,
|
|
2746
2931
|
error: state.error,
|
|
2747
2932
|
isLoading: state.isLoading,
|
|
2748
2933
|
label: state.error ? "Unavailable" : snapshot ? `${snapshot.status} \xB7 ${snapshot.sessionId}` : state.isLoading ? "Loading" : "No snapshot",
|
|
@@ -2766,30 +2951,30 @@ var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
|
|
|
2766
2951
|
] : [],
|
|
2767
2952
|
showDownload: snapshot !== undefined,
|
|
2768
2953
|
status: state.error ? "error" : snapshot ? snapshot.status === "pass" ? "ready" : "warning" : state.isLoading ? "loading" : "empty",
|
|
2769
|
-
title: options.title ??
|
|
2954
|
+
title: options.title ?? DEFAULT_TITLE5,
|
|
2770
2955
|
updatedAt: state.updatedAt
|
|
2771
2956
|
};
|
|
2772
2957
|
};
|
|
2773
2958
|
var renderVoiceSessionSnapshotHTML = (state, options = {}) => {
|
|
2774
2959
|
const model = createVoiceSessionSnapshotViewModel(state, options);
|
|
2775
2960
|
const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
|
|
2776
|
-
<dt>${
|
|
2777
|
-
<dd>${
|
|
2961
|
+
<dt>${escapeHtml7(row.label)}</dt>
|
|
2962
|
+
<dd>${escapeHtml7(row.value)}</dd>
|
|
2778
2963
|
</div>`).join("")}</dl>` : '<p class="absolute-voice-session-snapshot__empty">Load a session snapshot to see support diagnostics.</p>';
|
|
2779
2964
|
const artifacts = model.artifacts.length ? `<div class="absolute-voice-session-snapshot__artifacts">${model.artifacts.map((artifact) => {
|
|
2780
|
-
const body = `<strong>${
|
|
2781
|
-
return artifact.href ? `<a href="${
|
|
2965
|
+
const body = `<strong>${escapeHtml7(artifact.label)}</strong><span>${escapeHtml7(artifact.status)}</span>`;
|
|
2966
|
+
return artifact.href ? `<a href="${escapeHtml7(artifact.href)}">${body}</a>` : `<div>${body}</div>`;
|
|
2782
2967
|
}).join("")}</div>` : "";
|
|
2783
|
-
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${
|
|
2968
|
+
return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${escapeHtml7(model.status)}">
|
|
2784
2969
|
<header class="absolute-voice-session-snapshot__header">
|
|
2785
|
-
<span class="absolute-voice-session-snapshot__eyebrow">${
|
|
2786
|
-
<strong class="absolute-voice-session-snapshot__label">${
|
|
2970
|
+
<span class="absolute-voice-session-snapshot__eyebrow">${escapeHtml7(model.title)}</span>
|
|
2971
|
+
<strong class="absolute-voice-session-snapshot__label">${escapeHtml7(model.label)}</strong>
|
|
2787
2972
|
</header>
|
|
2788
|
-
<p class="absolute-voice-session-snapshot__description">${
|
|
2789
|
-
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${
|
|
2973
|
+
<p class="absolute-voice-session-snapshot__description">${escapeHtml7(model.description)}</p>
|
|
2974
|
+
${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${escapeHtml7(options.downloadLabel ?? DEFAULT_DOWNLOAD_LABEL)}</button>` : ""}
|
|
2790
2975
|
${rows}
|
|
2791
2976
|
${artifacts}
|
|
2792
|
-
${model.error ? `<p class="absolute-voice-session-snapshot__error">${
|
|
2977
|
+
${model.error ? `<p class="absolute-voice-session-snapshot__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
2793
2978
|
</section>`;
|
|
2794
2979
|
};
|
|
2795
2980
|
var downloadBlob = (blob, filename) => {
|
|
@@ -3111,7 +3296,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
3111
3296
|
};
|
|
3112
3297
|
|
|
3113
3298
|
// src/client/providerSimulationControlsWidget.ts
|
|
3114
|
-
var
|
|
3299
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3115
3300
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
3116
3301
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
3117
3302
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -3131,18 +3316,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
3131
3316
|
};
|
|
3132
3317
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
3133
3318
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
3134
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
3135
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
3319
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml8(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml8(provider.provider)} ${escapeHtml8(formatKind(options.kind))} failure</button>`).join("");
|
|
3320
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml8(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml8(provider.provider)} recovered</button>`).join("");
|
|
3136
3321
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
3137
3322
|
<header class="absolute-voice-provider-simulation__header">
|
|
3138
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
3139
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
3323
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml8(model.title)}</span>
|
|
3324
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml8(model.label)}</strong>
|
|
3140
3325
|
</header>
|
|
3141
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
3142
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
3326
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml8(model.description)}</p>
|
|
3327
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml8(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
3143
3328
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
3144
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
3145
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
3329
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml8(snapshot.error)}</p>` : ""}
|
|
3330
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml8(model.resultText)}</pre>` : ""}
|
|
3146
3331
|
</section>`;
|
|
3147
3332
|
};
|
|
3148
3333
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -3297,9 +3482,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
|
|
|
3297
3482
|
};
|
|
3298
3483
|
|
|
3299
3484
|
// src/client/providerCapabilitiesWidget.ts
|
|
3300
|
-
var
|
|
3301
|
-
var
|
|
3302
|
-
var
|
|
3485
|
+
var DEFAULT_TITLE6 = "Provider Capabilities";
|
|
3486
|
+
var DEFAULT_DESCRIPTION6 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
3487
|
+
var escapeHtml9 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3303
3488
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
3304
3489
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
3305
3490
|
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -3343,36 +3528,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
3343
3528
|
const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
|
|
3344
3529
|
return {
|
|
3345
3530
|
capabilities,
|
|
3346
|
-
description: options.description ??
|
|
3531
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
3347
3532
|
error: snapshot.error,
|
|
3348
3533
|
isLoading: snapshot.isLoading,
|
|
3349
3534
|
label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
|
|
3350
3535
|
status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
3351
|
-
title: options.title ??
|
|
3536
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
3352
3537
|
updatedAt: snapshot.updatedAt
|
|
3353
3538
|
};
|
|
3354
3539
|
};
|
|
3355
3540
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
3356
3541
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
3357
|
-
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--${
|
|
3542
|
+
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--${escapeHtml9(capability.status)}">
|
|
3358
3543
|
<header>
|
|
3359
|
-
<strong>${
|
|
3360
|
-
<span>${
|
|
3544
|
+
<strong>${escapeHtml9(capability.label)}</strong>
|
|
3545
|
+
<span>${escapeHtml9(formatStatus2(capability.status))}</span>
|
|
3361
3546
|
</header>
|
|
3362
|
-
<p>${
|
|
3547
|
+
<p>${escapeHtml9(capability.detail)}</p>
|
|
3363
3548
|
<dl>${capability.rows.map((row) => `<div>
|
|
3364
|
-
<dt>${
|
|
3365
|
-
<dd>${
|
|
3549
|
+
<dt>${escapeHtml9(row.label)}</dt>
|
|
3550
|
+
<dd>${escapeHtml9(row.value)}</dd>
|
|
3366
3551
|
</div>`).join("")}</dl>
|
|
3367
3552
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
3368
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
3553
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml9(model.status)}">
|
|
3369
3554
|
<header class="absolute-voice-provider-capabilities__header">
|
|
3370
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
3371
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
3555
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml9(model.title)}</span>
|
|
3556
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml9(model.label)}</strong>
|
|
3372
3557
|
</header>
|
|
3373
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
3558
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml9(model.description)}</p>
|
|
3374
3559
|
${capabilities}
|
|
3375
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
3560
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml9(model.error)}</p>` : ""}
|
|
3376
3561
|
</section>`;
|
|
3377
3562
|
};
|
|
3378
3563
|
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}`;
|
|
@@ -3498,9 +3683,9 @@ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", optio
|
|
|
3498
3683
|
};
|
|
3499
3684
|
|
|
3500
3685
|
// src/client/providerContractsWidget.ts
|
|
3501
|
-
var
|
|
3502
|
-
var
|
|
3503
|
-
var
|
|
3686
|
+
var DEFAULT_TITLE7 = "Provider Contracts";
|
|
3687
|
+
var DEFAULT_DESCRIPTION7 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
3688
|
+
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3504
3689
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
3505
3690
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
3506
3691
|
var contractDetail = (row) => {
|
|
@@ -3532,38 +3717,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
3532
3717
|
}));
|
|
3533
3718
|
const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
|
|
3534
3719
|
return {
|
|
3535
|
-
description: options.description ??
|
|
3720
|
+
description: options.description ?? DEFAULT_DESCRIPTION7,
|
|
3536
3721
|
error: snapshot.error,
|
|
3537
3722
|
isLoading: snapshot.isLoading,
|
|
3538
3723
|
label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
|
|
3539
3724
|
rows,
|
|
3540
3725
|
status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
3541
|
-
title: options.title ??
|
|
3726
|
+
title: options.title ?? DEFAULT_TITLE7,
|
|
3542
3727
|
updatedAt: snapshot.updatedAt
|
|
3543
3728
|
};
|
|
3544
3729
|
};
|
|
3545
3730
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
3546
3731
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
3547
|
-
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--${
|
|
3732
|
+
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--${escapeHtml10(row.status)}">
|
|
3548
3733
|
<header>
|
|
3549
|
-
<strong>${
|
|
3550
|
-
<span>${
|
|
3734
|
+
<strong>${escapeHtml10(row.label)}</strong>
|
|
3735
|
+
<span>${escapeHtml10(formatStatus3(row.status))}</span>
|
|
3551
3736
|
</header>
|
|
3552
|
-
<p>${
|
|
3553
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
3737
|
+
<p>${escapeHtml10(row.detail)}</p>
|
|
3738
|
+
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml10(remediation.href)}">${escapeHtml10(remediation.label)}</a>` : `<strong>${escapeHtml10(remediation.label)}</strong>`}<span>${escapeHtml10(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
|
|
3554
3739
|
<dl>${row.rows.map((item) => `<div>
|
|
3555
|
-
<dt>${
|
|
3556
|
-
<dd>${
|
|
3740
|
+
<dt>${escapeHtml10(item.label)}</dt>
|
|
3741
|
+
<dd>${escapeHtml10(item.value)}</dd>
|
|
3557
3742
|
</div>`).join("")}</dl>
|
|
3558
3743
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
3559
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
3744
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml10(model.status)}">
|
|
3560
3745
|
<header class="absolute-voice-provider-contracts__header">
|
|
3561
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
3562
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
3746
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml10(model.title)}</span>
|
|
3747
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml10(model.label)}</strong>
|
|
3563
3748
|
</header>
|
|
3564
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
3749
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml10(model.description)}</p>
|
|
3565
3750
|
${rows}
|
|
3566
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
3751
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml10(model.error)}</p>` : ""}
|
|
3567
3752
|
</section>`;
|
|
3568
3753
|
};
|
|
3569
3754
|
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}`;
|
|
@@ -5086,9 +5271,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
5086
5271
|
};
|
|
5087
5272
|
|
|
5088
5273
|
// src/client/providerStatusWidget.ts
|
|
5089
|
-
var
|
|
5090
|
-
var
|
|
5091
|
-
var
|
|
5274
|
+
var DEFAULT_TITLE8 = "Voice Providers";
|
|
5275
|
+
var DEFAULT_DESCRIPTION8 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
5276
|
+
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5092
5277
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
5093
5278
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
5094
5279
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -5132,37 +5317,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
5132
5317
|
const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
|
|
5133
5318
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
5134
5319
|
return {
|
|
5135
|
-
description: options.description ??
|
|
5320
|
+
description: options.description ?? DEFAULT_DESCRIPTION8,
|
|
5136
5321
|
error: snapshot.error,
|
|
5137
5322
|
isLoading: snapshot.isLoading,
|
|
5138
5323
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
5139
5324
|
providers,
|
|
5140
5325
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
5141
|
-
title: options.title ??
|
|
5326
|
+
title: options.title ?? DEFAULT_TITLE8,
|
|
5142
5327
|
updatedAt: snapshot.updatedAt
|
|
5143
5328
|
};
|
|
5144
5329
|
};
|
|
5145
5330
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
5146
5331
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
5147
|
-
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--${
|
|
5332
|
+
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--${escapeHtml11(provider.status)}">
|
|
5148
5333
|
<header>
|
|
5149
|
-
<strong>${
|
|
5150
|
-
<span>${
|
|
5334
|
+
<strong>${escapeHtml11(provider.label)}</strong>
|
|
5335
|
+
<span>${escapeHtml11(formatStatus4(provider.status))}</span>
|
|
5151
5336
|
</header>
|
|
5152
|
-
<p>${
|
|
5337
|
+
<p>${escapeHtml11(provider.detail)}</p>
|
|
5153
5338
|
<dl>${provider.rows.map((row) => `<div>
|
|
5154
|
-
<dt>${
|
|
5155
|
-
<dd>${
|
|
5339
|
+
<dt>${escapeHtml11(row.label)}</dt>
|
|
5340
|
+
<dd>${escapeHtml11(row.value)}</dd>
|
|
5156
5341
|
</div>`).join("")}</dl>
|
|
5157
5342
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
5158
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
5343
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml11(model.status)}">
|
|
5159
5344
|
<header class="absolute-voice-provider-status__header">
|
|
5160
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
5161
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
5345
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml11(model.title)}</span>
|
|
5346
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml11(model.label)}</strong>
|
|
5162
5347
|
</header>
|
|
5163
|
-
<p class="absolute-voice-provider-status__description">${
|
|
5348
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml11(model.description)}</p>
|
|
5164
5349
|
${providers}
|
|
5165
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
5350
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml11(model.error)}</p>` : ""}
|
|
5166
5351
|
</section>`;
|
|
5167
5352
|
};
|
|
5168
5353
|
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}`;
|
|
@@ -5293,9 +5478,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
5293
5478
|
};
|
|
5294
5479
|
|
|
5295
5480
|
// src/client/routingStatusWidget.ts
|
|
5296
|
-
var
|
|
5297
|
-
var
|
|
5298
|
-
var
|
|
5481
|
+
var DEFAULT_TITLE9 = "Voice Routing";
|
|
5482
|
+
var DEFAULT_DESCRIPTION9 = "Latest provider routing decision from the self-hosted trace store.";
|
|
5483
|
+
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5299
5484
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
5300
5485
|
var formatProviderRoutes = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
|
|
5301
5486
|
var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
|
|
@@ -5364,35 +5549,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
5364
5549
|
return {
|
|
5365
5550
|
activeStack,
|
|
5366
5551
|
decision,
|
|
5367
|
-
description: options.description ??
|
|
5552
|
+
description: options.description ?? DEFAULT_DESCRIPTION9,
|
|
5368
5553
|
error: snapshot.error,
|
|
5369
5554
|
isLoading: snapshot.isLoading,
|
|
5370
5555
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
5371
5556
|
rows,
|
|
5372
5557
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
5373
|
-
title: options.title ??
|
|
5558
|
+
title: options.title ?? DEFAULT_TITLE9,
|
|
5374
5559
|
updatedAt: snapshot.updatedAt
|
|
5375
5560
|
};
|
|
5376
5561
|
};
|
|
5377
5562
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
5378
5563
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
5379
5564
|
const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
|
|
5380
|
-
<span>${
|
|
5381
|
-
<strong>${
|
|
5565
|
+
<span>${escapeHtml12(item.label)}</span>
|
|
5566
|
+
<strong>${escapeHtml12(item.value)}</strong>
|
|
5382
5567
|
</div>`).join("")}</div>` : "";
|
|
5383
5568
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
5384
|
-
<span>${
|
|
5385
|
-
<strong>${
|
|
5569
|
+
<span>${escapeHtml12(row.label)}</span>
|
|
5570
|
+
<strong>${escapeHtml12(row.value)}</strong>
|
|
5386
5571
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
5387
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
5572
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml12(model.status)}">
|
|
5388
5573
|
<header class="absolute-voice-routing-status__header">
|
|
5389
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
5390
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
5574
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml12(model.title)}</span>
|
|
5575
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml12(model.label)}</strong>
|
|
5391
5576
|
</header>
|
|
5392
|
-
<p class="absolute-voice-routing-status__description">${
|
|
5577
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml12(model.description)}</p>
|
|
5393
5578
|
${activeStack}
|
|
5394
5579
|
${rows}
|
|
5395
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
5580
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml12(model.error)}</p>` : ""}
|
|
5396
5581
|
</section>`;
|
|
5397
5582
|
};
|
|
5398
5583
|
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}}`;
|
|
@@ -5523,9 +5708,9 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
|
|
|
5523
5708
|
};
|
|
5524
5709
|
|
|
5525
5710
|
// src/client/traceTimelineWidget.ts
|
|
5526
|
-
var
|
|
5527
|
-
var
|
|
5528
|
-
var
|
|
5711
|
+
var DEFAULT_TITLE10 = "Voice Traces";
|
|
5712
|
+
var DEFAULT_DESCRIPTION10 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
5713
|
+
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5529
5714
|
var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
5530
5715
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
5531
5716
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -5541,13 +5726,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
|
5541
5726
|
const failed = sessions.filter((session) => session.status === "failed").length;
|
|
5542
5727
|
const warnings = sessions.filter((session) => session.status === "warning").length;
|
|
5543
5728
|
return {
|
|
5544
|
-
description: options.description ??
|
|
5729
|
+
description: options.description ?? DEFAULT_DESCRIPTION10,
|
|
5545
5730
|
error: snapshot.error,
|
|
5546
5731
|
isLoading: snapshot.isLoading,
|
|
5547
5732
|
label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
|
|
5548
5733
|
sessions,
|
|
5549
5734
|
status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
5550
|
-
title: options.title ??
|
|
5735
|
+
title: options.title ?? DEFAULT_TITLE10,
|
|
5551
5736
|
updatedAt: snapshot.updatedAt
|
|
5552
5737
|
};
|
|
5553
5738
|
};
|
|
@@ -5555,27 +5740,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
5555
5740
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
5556
5741
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
5557
5742
|
const supportLinks = [
|
|
5558
|
-
`<a href="${
|
|
5559
|
-
session.operationsRecordHref ? `<a href="${
|
|
5560
|
-
session.incidentBundleHref ? `<a href="${
|
|
5743
|
+
`<a href="${escapeHtml13(session.detailHref)}">Open timeline</a>`,
|
|
5744
|
+
session.operationsRecordHref ? `<a href="${escapeHtml13(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
5745
|
+
session.incidentBundleHref ? `<a href="${escapeHtml13(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
5561
5746
|
].filter(Boolean).join("");
|
|
5562
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
5747
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml13(session.status)}">
|
|
5563
5748
|
<header>
|
|
5564
|
-
<strong>${
|
|
5565
|
-
<span>${
|
|
5749
|
+
<strong>${escapeHtml13(session.sessionId)}</strong>
|
|
5750
|
+
<span>${escapeHtml13(session.status)}</span>
|
|
5566
5751
|
</header>
|
|
5567
|
-
<p>${
|
|
5752
|
+
<p>${escapeHtml13(session.label)} \xB7 ${escapeHtml13(session.durationLabel)} \xB7 ${escapeHtml13(session.providerLabel)}</p>
|
|
5568
5753
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
5569
5754
|
</article>`;
|
|
5570
5755
|
}).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
5571
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
5756
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml13(model.status)}">
|
|
5572
5757
|
<header class="absolute-voice-trace-timeline__header">
|
|
5573
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
5574
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
5758
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml13(model.title)}</span>
|
|
5759
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml13(model.label)}</strong>
|
|
5575
5760
|
</header>
|
|
5576
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
5761
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml13(model.description)}</p>
|
|
5577
5762
|
${sessions}
|
|
5578
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
5763
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml13(model.error)}</p>` : ""}
|
|
5579
5764
|
</section>`;
|
|
5580
5765
|
};
|
|
5581
5766
|
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}`;
|
|
@@ -5705,9 +5890,9 @@ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}
|
|
|
5705
5890
|
};
|
|
5706
5891
|
|
|
5707
5892
|
// src/client/agentSquadStatusWidget.ts
|
|
5708
|
-
var
|
|
5709
|
-
var
|
|
5710
|
-
var
|
|
5893
|
+
var DEFAULT_TITLE11 = "Voice Agent Squad";
|
|
5894
|
+
var DEFAULT_DESCRIPTION11 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
5895
|
+
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5711
5896
|
var labelFor = (current) => {
|
|
5712
5897
|
if (!current)
|
|
5713
5898
|
return "Waiting for specialist activity";
|
|
@@ -5721,37 +5906,37 @@ var labelFor = (current) => {
|
|
|
5721
5906
|
};
|
|
5722
5907
|
var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
|
|
5723
5908
|
current: snapshot.report.current,
|
|
5724
|
-
description: options.description ??
|
|
5909
|
+
description: options.description ?? DEFAULT_DESCRIPTION11,
|
|
5725
5910
|
error: snapshot.error,
|
|
5726
5911
|
isLoading: snapshot.isLoading,
|
|
5727
5912
|
label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
|
|
5728
5913
|
sessionCount: snapshot.report.sessionCount,
|
|
5729
5914
|
sessions: snapshot.report.sessions,
|
|
5730
|
-
title: options.title ??
|
|
5915
|
+
title: options.title ?? DEFAULT_TITLE11,
|
|
5731
5916
|
updatedAt: snapshot.updatedAt
|
|
5732
5917
|
});
|
|
5733
5918
|
var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
5734
5919
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
5735
5920
|
const current = model.current;
|
|
5736
5921
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
5737
|
-
<span>${
|
|
5738
|
-
<strong>${
|
|
5739
|
-
<em>${
|
|
5740
|
-
${session.summary || session.reason ? `<p>${
|
|
5922
|
+
<span>${escapeHtml14(session.sessionId)}</span>
|
|
5923
|
+
<strong>${escapeHtml14(session.targetAgentId ?? "none")}</strong>
|
|
5924
|
+
<em>${escapeHtml14(session.status)}</em>
|
|
5925
|
+
${session.summary || session.reason ? `<p>${escapeHtml14(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
5741
5926
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
5742
5927
|
return `<section class="absolute-voice-agent-squad-status">
|
|
5743
5928
|
<header>
|
|
5744
|
-
<span>${
|
|
5745
|
-
<strong>${
|
|
5929
|
+
<span>${escapeHtml14(model.title)}</span>
|
|
5930
|
+
<strong>${escapeHtml14(model.label)}</strong>
|
|
5746
5931
|
</header>
|
|
5747
|
-
<p>${
|
|
5932
|
+
<p>${escapeHtml14(model.description)}</p>
|
|
5748
5933
|
<div>
|
|
5749
|
-
<span>Session</span><strong>${
|
|
5750
|
-
<span>From</span><strong>${
|
|
5751
|
-
<span>Status</span><strong>${
|
|
5934
|
+
<span>Session</span><strong>${escapeHtml14(current?.sessionId ?? "n/a")}</strong>
|
|
5935
|
+
<span>From</span><strong>${escapeHtml14(current?.fromAgentId ?? "n/a")}</strong>
|
|
5936
|
+
<span>Status</span><strong>${escapeHtml14(current?.status ?? "idle")}</strong>
|
|
5752
5937
|
</div>
|
|
5753
5938
|
<ul>${rows}</ul>
|
|
5754
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
5939
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml14(model.error)}</p>` : ""}
|
|
5755
5940
|
</section>`;
|
|
5756
5941
|
};
|
|
5757
5942
|
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}`;
|
|
@@ -5911,10 +6096,10 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
|
|
|
5911
6096
|
};
|
|
5912
6097
|
|
|
5913
6098
|
// src/client/turnLatencyWidget.ts
|
|
5914
|
-
var
|
|
5915
|
-
var
|
|
6099
|
+
var DEFAULT_TITLE12 = "Turn Latency";
|
|
6100
|
+
var DEFAULT_DESCRIPTION12 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
5916
6101
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
5917
|
-
var
|
|
6102
|
+
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
5918
6103
|
var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
5919
6104
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
5920
6105
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -5928,39 +6113,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
5928
6113
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
5929
6114
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
5930
6115
|
return {
|
|
5931
|
-
description: options.description ??
|
|
6116
|
+
description: options.description ?? DEFAULT_DESCRIPTION12,
|
|
5932
6117
|
error: snapshot.error,
|
|
5933
6118
|
isLoading: snapshot.isLoading,
|
|
5934
6119
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
5935
6120
|
proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
|
|
5936
6121
|
showProofAction: Boolean(options.proofPath),
|
|
5937
6122
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
5938
|
-
title: options.title ??
|
|
6123
|
+
title: options.title ?? DEFAULT_TITLE12,
|
|
5939
6124
|
turns,
|
|
5940
6125
|
updatedAt: snapshot.updatedAt
|
|
5941
6126
|
};
|
|
5942
6127
|
};
|
|
5943
6128
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
5944
6129
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
5945
|
-
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--${
|
|
6130
|
+
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--${escapeHtml15(turn.status)}">
|
|
5946
6131
|
<header>
|
|
5947
|
-
<strong>${
|
|
5948
|
-
<span>${
|
|
6132
|
+
<strong>${escapeHtml15(turn.label)}</strong>
|
|
6133
|
+
<span>${escapeHtml15(turn.status)}</span>
|
|
5949
6134
|
</header>
|
|
5950
6135
|
<dl>${turn.rows.map((row) => `<div>
|
|
5951
|
-
<dt>${
|
|
5952
|
-
<dd>${
|
|
6136
|
+
<dt>${escapeHtml15(row.label)}</dt>
|
|
6137
|
+
<dd>${escapeHtml15(row.value)}</dd>
|
|
5953
6138
|
</div>`).join("")}</dl>
|
|
5954
6139
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
5955
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
6140
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml15(model.status)}">
|
|
5956
6141
|
<header class="absolute-voice-turn-latency__header">
|
|
5957
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
5958
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
6142
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml15(model.title)}</span>
|
|
6143
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml15(model.label)}</strong>
|
|
5959
6144
|
</header>
|
|
5960
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
5961
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
6145
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml15(model.description)}</p>
|
|
6146
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml15(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
5962
6147
|
${turns}
|
|
5963
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
6148
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml15(model.error)}</p>` : ""}
|
|
5964
6149
|
</section>`;
|
|
5965
6150
|
};
|
|
5966
6151
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -6099,9 +6284,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
6099
6284
|
};
|
|
6100
6285
|
|
|
6101
6286
|
// src/client/turnQualityWidget.ts
|
|
6102
|
-
var
|
|
6103
|
-
var
|
|
6104
|
-
var
|
|
6287
|
+
var DEFAULT_TITLE13 = "Turn Quality";
|
|
6288
|
+
var DEFAULT_DESCRIPTION13 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
6289
|
+
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
6105
6290
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
6106
6291
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
6107
6292
|
var getTurnDetail = (turn) => {
|
|
@@ -6139,37 +6324,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
6139
6324
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
6140
6325
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
6141
6326
|
return {
|
|
6142
|
-
description: options.description ??
|
|
6327
|
+
description: options.description ?? DEFAULT_DESCRIPTION13,
|
|
6143
6328
|
error: snapshot.error,
|
|
6144
6329
|
isLoading: snapshot.isLoading,
|
|
6145
6330
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
6146
6331
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
6147
|
-
title: options.title ??
|
|
6332
|
+
title: options.title ?? DEFAULT_TITLE13,
|
|
6148
6333
|
turns,
|
|
6149
6334
|
updatedAt: snapshot.updatedAt
|
|
6150
6335
|
};
|
|
6151
6336
|
};
|
|
6152
6337
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
6153
6338
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
6154
|
-
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--${
|
|
6339
|
+
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--${escapeHtml16(turn.status)}">
|
|
6155
6340
|
<header>
|
|
6156
|
-
<strong>${
|
|
6157
|
-
<span>${
|
|
6341
|
+
<strong>${escapeHtml16(turn.label)}</strong>
|
|
6342
|
+
<span>${escapeHtml16(turn.status)}</span>
|
|
6158
6343
|
</header>
|
|
6159
|
-
<p>${
|
|
6344
|
+
<p>${escapeHtml16(turn.detail)}</p>
|
|
6160
6345
|
<dl>${turn.rows.map((row) => `<div>
|
|
6161
|
-
<dt>${
|
|
6162
|
-
<dd>${
|
|
6346
|
+
<dt>${escapeHtml16(row.label)}</dt>
|
|
6347
|
+
<dd>${escapeHtml16(row.value)}</dd>
|
|
6163
6348
|
</div>`).join("")}</dl>
|
|
6164
6349
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
6165
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
6350
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml16(model.status)}">
|
|
6166
6351
|
<header class="absolute-voice-turn-quality__header">
|
|
6167
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
6168
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
6352
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml16(model.title)}</span>
|
|
6353
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml16(model.label)}</strong>
|
|
6169
6354
|
</header>
|
|
6170
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
6355
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml16(model.description)}</p>
|
|
6171
6356
|
${turns}
|
|
6172
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
6357
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml16(model.error)}</p>` : ""}
|
|
6173
6358
|
</section>`;
|
|
6174
6359
|
};
|
|
6175
6360
|
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}`;
|
|
@@ -6967,5 +7152,6 @@ export {
|
|
|
6967
7152
|
createVoiceDeliveryRuntime,
|
|
6968
7153
|
createVoiceController,
|
|
6969
7154
|
createVoiceCampaignDialerProof,
|
|
7155
|
+
createVoiceCallDebugger,
|
|
6970
7156
|
createVoiceAgentSquadStatus
|
|
6971
7157
|
};
|