@absolutejs/voice 0.0.22-beta.453 → 0.0.22-beta.455
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 +345 -224
- package/dist/angular/voice-reconnect-profile-evidence.service.d.ts +12 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +659 -240
- package/dist/client/reconnectProfileEvidence.d.ts +19 -0
- package/dist/client/reconnectProfileEvidenceWidget.d.ts +39 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +224 -0
- package/dist/proofTrends.d.ts +103 -0
- package/dist/react/VoiceReconnectProfileEvidence.d.ts +6 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +1035 -526
- package/dist/react/useVoiceReconnectProfileEvidence.d.ts +8 -0
- package/dist/svelte/createVoiceReconnectProfileEvidence.d.ts +7 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +86 -0
- package/dist/vue/VoiceReconnectProfileEvidence.d.ts +21 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.js +941 -438
- package/dist/vue/useVoiceReconnectProfileEvidence.d.ts +9 -0
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -2985,6 +2985,80 @@ var createVoiceProofTrendsStore = (path = "/api/voice/proof-trends", options = {
|
|
|
2985
2985
|
}
|
|
2986
2986
|
};
|
|
2987
2987
|
};
|
|
2988
|
+
// src/client/reconnectProfileEvidence.ts
|
|
2989
|
+
var fetchVoiceReconnectProfileEvidence = async (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
|
|
2990
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
2991
|
+
const response = await fetchImpl(path);
|
|
2992
|
+
if (!response.ok) {
|
|
2993
|
+
throw new Error(`Voice reconnect profile evidence failed: HTTP ${response.status}`);
|
|
2994
|
+
}
|
|
2995
|
+
return await response.json();
|
|
2996
|
+
};
|
|
2997
|
+
var createVoiceReconnectProfileEvidenceStore = (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
|
|
2998
|
+
const listeners = new Set;
|
|
2999
|
+
let closed = false;
|
|
3000
|
+
let timer;
|
|
3001
|
+
let snapshot = {
|
|
3002
|
+
error: null,
|
|
3003
|
+
isLoading: false
|
|
3004
|
+
};
|
|
3005
|
+
const emit = () => {
|
|
3006
|
+
for (const listener of listeners) {
|
|
3007
|
+
listener();
|
|
3008
|
+
}
|
|
3009
|
+
};
|
|
3010
|
+
const refresh = async () => {
|
|
3011
|
+
if (closed) {
|
|
3012
|
+
return snapshot.report;
|
|
3013
|
+
}
|
|
3014
|
+
snapshot = { ...snapshot, error: null, isLoading: true };
|
|
3015
|
+
emit();
|
|
3016
|
+
try {
|
|
3017
|
+
const report = await fetchVoiceReconnectProfileEvidence(path, options);
|
|
3018
|
+
snapshot = {
|
|
3019
|
+
error: null,
|
|
3020
|
+
isLoading: false,
|
|
3021
|
+
report,
|
|
3022
|
+
updatedAt: Date.now()
|
|
3023
|
+
};
|
|
3024
|
+
emit();
|
|
3025
|
+
return report;
|
|
3026
|
+
} catch (error) {
|
|
3027
|
+
snapshot = {
|
|
3028
|
+
...snapshot,
|
|
3029
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3030
|
+
isLoading: false
|
|
3031
|
+
};
|
|
3032
|
+
emit();
|
|
3033
|
+
throw error;
|
|
3034
|
+
}
|
|
3035
|
+
};
|
|
3036
|
+
const close = () => {
|
|
3037
|
+
closed = true;
|
|
3038
|
+
if (timer) {
|
|
3039
|
+
clearInterval(timer);
|
|
3040
|
+
timer = undefined;
|
|
3041
|
+
}
|
|
3042
|
+
listeners.clear();
|
|
3043
|
+
};
|
|
3044
|
+
if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
|
|
3045
|
+
timer = setInterval(() => {
|
|
3046
|
+
refresh().catch(() => {});
|
|
3047
|
+
}, options.intervalMs);
|
|
3048
|
+
}
|
|
3049
|
+
return {
|
|
3050
|
+
close,
|
|
3051
|
+
getServerSnapshot: () => snapshot,
|
|
3052
|
+
getSnapshot: () => snapshot,
|
|
3053
|
+
refresh,
|
|
3054
|
+
subscribe: (listener) => {
|
|
3055
|
+
listeners.add(listener);
|
|
3056
|
+
return () => {
|
|
3057
|
+
listeners.delete(listener);
|
|
3058
|
+
};
|
|
3059
|
+
}
|
|
3060
|
+
};
|
|
3061
|
+
};
|
|
2988
3062
|
// src/client/sessionSnapshot.ts
|
|
2989
3063
|
var withTurnId = (path, turnId) => {
|
|
2990
3064
|
if (!turnId) {
|
|
@@ -6245,6 +6319,33 @@ var maxNumber = (values) => {
|
|
|
6245
6319
|
const finite = values.filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
6246
6320
|
return finite.length > 0 ? Math.max(...finite) : undefined;
|
|
6247
6321
|
};
|
|
6322
|
+
var buildVoiceReconnectProfileEvidenceSummary = (evidence, options = {}) => {
|
|
6323
|
+
const profileId = options.profileId ?? "reconnect-resume";
|
|
6324
|
+
const filtered = evidence.filter((record) => record.profileId === profileId).sort((left, right) => {
|
|
6325
|
+
const leftAt = Date.parse(left.generatedAt ?? left.createdAt);
|
|
6326
|
+
const rightAt = Date.parse(right.generatedAt ?? right.createdAt);
|
|
6327
|
+
return (Number.isFinite(rightAt) ? rightAt : 0) - (Number.isFinite(leftAt) ? leftAt : 0);
|
|
6328
|
+
});
|
|
6329
|
+
const latest = filtered[0];
|
|
6330
|
+
const sampleCount = filtered.reduce((total, record) => total + (record.reconnect?.samples ?? 1), 0);
|
|
6331
|
+
const snapshotCount = filtered.reduce((total, record) => total + (record.reconnect?.snapshotCount ?? 0), 0);
|
|
6332
|
+
const resumeLatencyP95Ms = maxNumber(filtered.map((record) => record.reconnect?.resumeLatencyP95Ms));
|
|
6333
|
+
const failed = filtered.some((record) => record.ok === false || record.reconnect?.status === "fail");
|
|
6334
|
+
const passed = filtered.some((record) => record.ok === true && record.reconnect?.resumed === true && record.reconnect?.reconnected === true);
|
|
6335
|
+
const status = filtered.length === 0 ? "empty" : failed ? "fail" : passed ? "pass" : "warn";
|
|
6336
|
+
return {
|
|
6337
|
+
evidence: filtered,
|
|
6338
|
+
generatedAt: options.generatedAt ?? new Date().toISOString(),
|
|
6339
|
+
latest,
|
|
6340
|
+
ok: status === "pass",
|
|
6341
|
+
profileId,
|
|
6342
|
+
resumeLatencyP95Ms,
|
|
6343
|
+
sampleCount,
|
|
6344
|
+
snapshotCount,
|
|
6345
|
+
sourceHref: options.sourceHref,
|
|
6346
|
+
status
|
|
6347
|
+
};
|
|
6348
|
+
};
|
|
6248
6349
|
var percentile = (values, rank) => {
|
|
6249
6350
|
const finite = values.filter((value) => Number.isFinite(value)).sort((left, right) => left - right);
|
|
6250
6351
|
if (finite.length === 0) {
|
|
@@ -6565,6 +6666,133 @@ var buildVoiceRealCallProfileEvidenceFromReconnectProofReports = (input, options
|
|
|
6565
6666
|
};
|
|
6566
6667
|
var loadVoiceRealCallProfileEvidenceFromTraceStore = async (options) => buildVoiceRealCallProfileEvidenceFromTraceEvents(await options.store.list({ limit: options.limit ?? 5000 }), options);
|
|
6567
6668
|
var loadVoiceRealCallProfileEvidenceFromStore = async (options) => options.store.list(options);
|
|
6669
|
+
var readRealCallEvidenceRuntimeKey = (evidence) => [evidence.profileId, evidence.sessionId, evidence.generatedAt ?? ""].join("\x00");
|
|
6670
|
+
var resolveRealCallEvidenceRuntimeReconnectReports = async (reports, options) => {
|
|
6671
|
+
const resolved = typeof reports === "function" ? await reports(options) : reports;
|
|
6672
|
+
if (!resolved) {
|
|
6673
|
+
return [];
|
|
6674
|
+
}
|
|
6675
|
+
return Array.isArray(resolved) ? resolved : [resolved];
|
|
6676
|
+
};
|
|
6677
|
+
var mergeRealCallEvidenceRuntimeOptions = (base, override = {}) => ({
|
|
6678
|
+
dedupe: override.dedupe ?? base.dedupe,
|
|
6679
|
+
evidenceStore: override.evidenceStore ?? base.evidenceStore,
|
|
6680
|
+
existingEvidenceLimit: override.existingEvidenceLimit ?? base.existingEvidenceLimit,
|
|
6681
|
+
history: {
|
|
6682
|
+
...base.history ?? {},
|
|
6683
|
+
...override.history ?? {}
|
|
6684
|
+
},
|
|
6685
|
+
now: override.now ?? base.now,
|
|
6686
|
+
reconnectEvidence: {
|
|
6687
|
+
...base.reconnectEvidence ?? {},
|
|
6688
|
+
...override.reconnectEvidence ?? {}
|
|
6689
|
+
},
|
|
6690
|
+
reconnectReports: override.reconnectReports ?? base.reconnectReports,
|
|
6691
|
+
traceEvidence: mergeRealCallProfileCollectorOptions(base.traceEvidence ?? {}, override.traceEvidence ?? {}),
|
|
6692
|
+
traceStore: override.traceStore ?? base.traceStore
|
|
6693
|
+
});
|
|
6694
|
+
var buildRealCallEvidenceRuntimeReport = async (options, input = {}) => {
|
|
6695
|
+
const evidence = await options.evidenceStore.list({
|
|
6696
|
+
limit: options.existingEvidenceLimit ?? 5000
|
|
6697
|
+
});
|
|
6698
|
+
const history = await buildVoiceRealCallProfileHistoryReportFromStore({
|
|
6699
|
+
...options.history ?? {},
|
|
6700
|
+
limit: options.existingEvidenceLimit ?? 5000,
|
|
6701
|
+
store: options.evidenceStore
|
|
6702
|
+
});
|
|
6703
|
+
const generatedAt = (options.now ?? (() => new Date))().toISOString();
|
|
6704
|
+
const sessions = new Set(evidence.map((record) => record.sessionId)).size;
|
|
6705
|
+
const failedProfiles = history.summary.profiles?.filter((profile) => profile.status === "fail").length;
|
|
6706
|
+
const issues = [
|
|
6707
|
+
...evidence.length === 0 ? ["No real-call profile evidence has been collected yet."] : [],
|
|
6708
|
+
...history.issues
|
|
6709
|
+
];
|
|
6710
|
+
const status = evidence.length === 0 ? "empty" : issues.length > 0 ? history.status === "pass" ? "fail" : history.status : history.status;
|
|
6711
|
+
return {
|
|
6712
|
+
appended: input.appended ?? 0,
|
|
6713
|
+
collected: input.collected ?? [],
|
|
6714
|
+
duplicateKeys: input.duplicateKeys ?? [],
|
|
6715
|
+
evidence,
|
|
6716
|
+
generatedAt,
|
|
6717
|
+
history,
|
|
6718
|
+
issues,
|
|
6719
|
+
ok: status === "pass" && issues.length === 0,
|
|
6720
|
+
skippedDuplicates: input.skippedDuplicates ?? 0,
|
|
6721
|
+
source: "real-call-evidence-runtime",
|
|
6722
|
+
status,
|
|
6723
|
+
summary: {
|
|
6724
|
+
collectedEvidence: input.collected?.length ?? 0,
|
|
6725
|
+
failedProfiles: failedProfiles ?? 0,
|
|
6726
|
+
profiles: history.summary.profileCount,
|
|
6727
|
+
sessions,
|
|
6728
|
+
storedEvidence: evidence.length
|
|
6729
|
+
}
|
|
6730
|
+
};
|
|
6731
|
+
};
|
|
6732
|
+
var collectVoiceRealCallEvidenceRuntimeEvidence = async (options) => {
|
|
6733
|
+
const evidence = [];
|
|
6734
|
+
if (options.traceStore) {
|
|
6735
|
+
evidence.push(...buildVoiceRealCallProfileEvidenceFromTraceEvents(await options.traceStore.list({
|
|
6736
|
+
limit: options.traceEvidence?.limit ?? 5000
|
|
6737
|
+
}), options.traceEvidence));
|
|
6738
|
+
}
|
|
6739
|
+
const reconnectReports = await resolveRealCallEvidenceRuntimeReconnectReports(options.reconnectReports, options);
|
|
6740
|
+
if (reconnectReports.length > 0) {
|
|
6741
|
+
evidence.push(...buildVoiceRealCallProfileEvidenceFromReconnectProofReports(reconnectReports, options.reconnectEvidence));
|
|
6742
|
+
}
|
|
6743
|
+
return evidence;
|
|
6744
|
+
};
|
|
6745
|
+
var createVoiceRealCallEvidenceRuntime = (options) => {
|
|
6746
|
+
const appendEvidence = async (evidenceInput, collectOptions = {}) => {
|
|
6747
|
+
const merged = mergeRealCallEvidenceRuntimeOptions(options, collectOptions);
|
|
6748
|
+
const evidence = Array.isArray(evidenceInput) ? [...evidenceInput] : [evidenceInput];
|
|
6749
|
+
const dedupe = merged.dedupe ?? true;
|
|
6750
|
+
const existing = dedupe ? await merged.evidenceStore.list({
|
|
6751
|
+
limit: merged.existingEvidenceLimit ?? 5000
|
|
6752
|
+
}) : [];
|
|
6753
|
+
const seen = new Set(existing.map(readRealCallEvidenceRuntimeKey));
|
|
6754
|
+
const incomingSeen = new Set;
|
|
6755
|
+
const duplicateKeys = [];
|
|
6756
|
+
let appended = 0;
|
|
6757
|
+
for (const item of evidence) {
|
|
6758
|
+
const key = readRealCallEvidenceRuntimeKey(item);
|
|
6759
|
+
if (dedupe && (seen.has(key) || incomingSeen.has(key))) {
|
|
6760
|
+
duplicateKeys.push(key);
|
|
6761
|
+
continue;
|
|
6762
|
+
}
|
|
6763
|
+
incomingSeen.add(key);
|
|
6764
|
+
await merged.evidenceStore.append(item);
|
|
6765
|
+
appended += 1;
|
|
6766
|
+
}
|
|
6767
|
+
return buildRealCallEvidenceRuntimeReport(merged, {
|
|
6768
|
+
appended,
|
|
6769
|
+
collected: evidence,
|
|
6770
|
+
duplicateKeys,
|
|
6771
|
+
skippedDuplicates: duplicateKeys.length
|
|
6772
|
+
});
|
|
6773
|
+
};
|
|
6774
|
+
return {
|
|
6775
|
+
appendEvidence,
|
|
6776
|
+
buildHistoryReport: async (historyOptions = {}) => buildVoiceRealCallProfileHistoryReportFromStore({
|
|
6777
|
+
...options.history ?? {},
|
|
6778
|
+
...historyOptions,
|
|
6779
|
+
limit: historyOptions.limit ?? options.existingEvidenceLimit ?? 5000,
|
|
6780
|
+
store: options.evidenceStore
|
|
6781
|
+
}),
|
|
6782
|
+
buildReport: async (collectOptions = {}) => buildRealCallEvidenceRuntimeReport(mergeRealCallEvidenceRuntimeOptions(options, collectOptions)),
|
|
6783
|
+
collect: async (collectOptions = {}) => {
|
|
6784
|
+
const merged = mergeRealCallEvidenceRuntimeOptions(options, collectOptions);
|
|
6785
|
+
const evidence = await collectVoiceRealCallEvidenceRuntimeEvidence(merged);
|
|
6786
|
+
return appendEvidence(evidence, {
|
|
6787
|
+
dedupe: merged.dedupe
|
|
6788
|
+
});
|
|
6789
|
+
},
|
|
6790
|
+
listEvidence: async (listOptions = {}) => await options.evidenceStore.list({
|
|
6791
|
+
limit: options.existingEvidenceLimit ?? 5000,
|
|
6792
|
+
...listOptions
|
|
6793
|
+
})
|
|
6794
|
+
};
|
|
6795
|
+
};
|
|
6568
6796
|
var realCallProfileTraceSignalTypes = new Set([
|
|
6569
6797
|
"client.barge_in",
|
|
6570
6798
|
"client.browser_media",
|
|
@@ -8151,6 +8379,31 @@ var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Pr
|
|
|
8151
8379
|
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml9(issue)}</li>`).join("");
|
|
8152
8380
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml9(title)}</title><style>body{background:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #52624b;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</p><h1>${escapeHtml9(title)}</h1><p>Generated ${escapeHtml9(report.generatedAt)} from ${escapeHtml9(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml9(report.status)}</span><span class="pill">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml9(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
8153
8381
|
};
|
|
8382
|
+
var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Call Evidence Runtime") => [
|
|
8383
|
+
`# ${title}`,
|
|
8384
|
+
"",
|
|
8385
|
+
`- Status: ${report.status}`,
|
|
8386
|
+
`- Stored evidence: ${String(report.summary.storedEvidence)}`,
|
|
8387
|
+
`- Collected evidence: ${String(report.summary.collectedEvidence)}`,
|
|
8388
|
+
`- Appended: ${String(report.appended)}`,
|
|
8389
|
+
`- Skipped duplicates: ${String(report.skippedDuplicates)}`,
|
|
8390
|
+
`- Sessions: ${String(report.summary.sessions)}`,
|
|
8391
|
+
`- Profiles: ${String(report.summary.profiles)}`,
|
|
8392
|
+
"",
|
|
8393
|
+
"## Rolling Profile History",
|
|
8394
|
+
"",
|
|
8395
|
+
renderVoiceRealCallProfileHistoryMarkdown(report.history, "Rolling Real-Call Profile History"),
|
|
8396
|
+
"",
|
|
8397
|
+
"## Issues",
|
|
8398
|
+
"",
|
|
8399
|
+
...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
|
|
8400
|
+
].join(`
|
|
8401
|
+
`);
|
|
8402
|
+
var renderVoiceRealCallEvidenceRuntimeHTML = (report, title = "Voice Real-Call Evidence Runtime") => {
|
|
8403
|
+
const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml9(issue)}</li>`).join("");
|
|
8404
|
+
const profileRows = report.history.summary.profiles?.length ? report.history.summary.profiles.map((profile) => `<tr><td>${escapeHtml9(profile.label ?? profile.id)}</td><td>${escapeHtml9(profile.status ?? "unknown")}</td><td>${escapeHtml9(profile.sessionCount ?? "n/a")}</td><td>${escapeHtml9(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml9(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml9(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profile history has been collected yet.</td></tr>';
|
|
8405
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml9(title)}</title><style>body{background:#0f1618;color:#f2f7f2;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,.card{background:#162225;border:1px solid #2f4548;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(132,204,22,.1))}.eyebrow{color:#99f6e4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.1rem,6vw,4.3rem);letter-spacing:-.06em;line-height:.94;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #4b6669;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail,.empty,.stale{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2f4548;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call evidence runtime</p><h1>${escapeHtml9(title)}</h1><p>Generated ${escapeHtml9(report.generatedAt)} from ${escapeHtml9(report.source)}.</p><div class="summary"><span class="pill ${escapeHtml9(report.status)}">Status ${escapeHtml9(report.status)}</span><span class="pill">Stored ${String(report.summary.storedEvidence)}</span><span class="pill">Collected ${String(report.summary.collectedEvidence)}</span><span class="pill">Appended ${String(report.appended)}</span><span class="pill">Duplicates ${String(report.skippedDuplicates)}</span><span class="pill">Sessions ${String(report.summary.sessions)}</span><span class="pill">Profiles ${String(report.summary.profiles)}</span></div></section><section class="card"><h2>Rolling Profile History</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Sessions</th><th>Live p95</th><th>Provider p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Issues</h2><ul>${issueItems}</ul></section></main></body></html>`;
|
|
8406
|
+
};
|
|
8154
8407
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
8155
8408
|
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
|
8156
8409
|
const htmlPath = options.htmlPath === undefined ? "/voice/proof-trend-recommendations" : options.htmlPath;
|
|
@@ -8234,6 +8487,46 @@ var createVoiceRealCallProfileHistoryRoutes = (options = {}) => {
|
|
|
8234
8487
|
}
|
|
8235
8488
|
return routes;
|
|
8236
8489
|
};
|
|
8490
|
+
var createVoiceRealCallEvidenceRuntimeRoutes = (options) => {
|
|
8491
|
+
const path = options.jsonPath ?? "/api/voice/real-call-evidence-runtime";
|
|
8492
|
+
const collectPath = options.collectPath === undefined ? `${path}/collect` : options.collectPath;
|
|
8493
|
+
const htmlPath = options.htmlPath === undefined ? "/voice/real-call-evidence-runtime" : options.htmlPath;
|
|
8494
|
+
const markdownPath = options.markdownPath === undefined ? "/voice/real-call-evidence-runtime.md" : options.markdownPath;
|
|
8495
|
+
const title = options.title ?? "Voice Real-Call Evidence Runtime";
|
|
8496
|
+
const runtime = options.runtime ?? createVoiceRealCallEvidenceRuntime({
|
|
8497
|
+
...options
|
|
8498
|
+
});
|
|
8499
|
+
const routes = new Elysia4({
|
|
8500
|
+
name: options.name ?? "absolutejs-voice-real-call-evidence-runtime"
|
|
8501
|
+
});
|
|
8502
|
+
routes.get(path, async () => Response.json(await runtime.buildReport(), { headers: options.headers }));
|
|
8503
|
+
if (collectPath !== false) {
|
|
8504
|
+
routes.post(collectPath, async () => Response.json(await runtime.collect(), { headers: options.headers }));
|
|
8505
|
+
}
|
|
8506
|
+
if (htmlPath !== false) {
|
|
8507
|
+
routes.get(htmlPath, async () => {
|
|
8508
|
+
const report = await runtime.buildReport();
|
|
8509
|
+
return new Response(renderVoiceRealCallEvidenceRuntimeHTML(report, title), {
|
|
8510
|
+
headers: {
|
|
8511
|
+
"content-type": "text/html; charset=utf-8",
|
|
8512
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
8513
|
+
}
|
|
8514
|
+
});
|
|
8515
|
+
});
|
|
8516
|
+
}
|
|
8517
|
+
if (markdownPath !== false) {
|
|
8518
|
+
routes.get(markdownPath, async () => {
|
|
8519
|
+
const report = await runtime.buildReport();
|
|
8520
|
+
return new Response(renderVoiceRealCallEvidenceRuntimeMarkdown(report, title), {
|
|
8521
|
+
headers: {
|
|
8522
|
+
"content-type": "text/markdown; charset=utf-8",
|
|
8523
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
8524
|
+
}
|
|
8525
|
+
});
|
|
8526
|
+
});
|
|
8527
|
+
}
|
|
8528
|
+
return routes;
|
|
8529
|
+
};
|
|
8237
8530
|
var realCallProfileActionPaths = {
|
|
8238
8531
|
"collect-browser-proof": "/collect-browser-proof",
|
|
8239
8532
|
"collect-phone-proof": "/collect-phone-proof",
|
|
@@ -8568,21 +8861,140 @@ var defineVoiceProofTrendsElement = (tagName = "absolute-voice-proof-trends") =>
|
|
|
8568
8861
|
}
|
|
8569
8862
|
});
|
|
8570
8863
|
};
|
|
8571
|
-
// src/client/
|
|
8572
|
-
var DEFAULT_TITLE6 = "
|
|
8573
|
-
var DEFAULT_DESCRIPTION6 = "
|
|
8864
|
+
// src/client/reconnectProfileEvidenceWidget.ts
|
|
8865
|
+
var DEFAULT_TITLE6 = "Persisted Reconnect Evidence";
|
|
8866
|
+
var DEFAULT_DESCRIPTION6 = "Real browser reconnect/resume evidence persisted into profile history so recovery claims are backed by durable traces.";
|
|
8574
8867
|
var DEFAULT_LINKS3 = [
|
|
8575
|
-
{ href: "/voice/
|
|
8576
|
-
{
|
|
8868
|
+
{ href: "/voice/reconnect-contract", label: "Reconnect contract" },
|
|
8869
|
+
{
|
|
8870
|
+
href: "/api/voice/real-call-profile-history",
|
|
8871
|
+
label: "Profile history JSON"
|
|
8872
|
+
}
|
|
8577
8873
|
];
|
|
8578
8874
|
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8579
8875
|
var formatMs2 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
8876
|
+
var formatCount = (value) => new Intl.NumberFormat("en-US").format(value);
|
|
8877
|
+
var formatAge = (value) => {
|
|
8878
|
+
if (!value) {
|
|
8879
|
+
return "No evidence";
|
|
8880
|
+
}
|
|
8881
|
+
const elapsedMs = Date.now() - Date.parse(value);
|
|
8882
|
+
if (!Number.isFinite(elapsedMs) || elapsedMs < 0) {
|
|
8883
|
+
return "Just now";
|
|
8884
|
+
}
|
|
8885
|
+
const minutes = Math.floor(elapsedMs / 60000);
|
|
8886
|
+
if (minutes < 1) {
|
|
8887
|
+
return "Just now";
|
|
8888
|
+
}
|
|
8889
|
+
if (minutes < 60) {
|
|
8890
|
+
return `${minutes}m ago`;
|
|
8891
|
+
}
|
|
8892
|
+
const hours = Math.floor(minutes / 60);
|
|
8893
|
+
if (hours < 24) {
|
|
8894
|
+
return `${hours}h ago`;
|
|
8895
|
+
}
|
|
8896
|
+
return `${Math.floor(hours / 24)}d ago`;
|
|
8897
|
+
};
|
|
8898
|
+
var createVoiceReconnectProfileEvidenceViewModel = (snapshot, options = {}) => {
|
|
8899
|
+
const report = snapshot.report;
|
|
8900
|
+
const latest = report?.latest;
|
|
8901
|
+
const latestAt = latest?.generatedAt ?? latest?.createdAt;
|
|
8902
|
+
return {
|
|
8903
|
+
description: options.description ?? latest?.profileDescription ?? DEFAULT_DESCRIPTION6,
|
|
8904
|
+
error: snapshot.error,
|
|
8905
|
+
isLoading: snapshot.isLoading,
|
|
8906
|
+
label: snapshot.error ? "Unavailable" : report ? report.status === "pass" ? "Reconnect evidence passing" : report.status === "warn" ? "Reconnect evidence incomplete" : report.status === "fail" ? "Reconnect evidence failing" : "Waiting for reconnect evidence" : snapshot.isLoading ? "Checking" : "No reconnect evidence",
|
|
8907
|
+
latest: latest ? {
|
|
8908
|
+
profileLabel: latest.profileLabel ?? latest.profileId,
|
|
8909
|
+
sessionId: latest.sessionId,
|
|
8910
|
+
surfaces: (latest.surfaces ?? []).join(", ") || "browser"
|
|
8911
|
+
} : undefined,
|
|
8912
|
+
links: options.links ?? DEFAULT_LINKS3,
|
|
8913
|
+
metrics: [
|
|
8914
|
+
{ label: "Samples", value: formatCount(report?.sampleCount ?? 0) },
|
|
8915
|
+
{ label: "Snapshots", value: formatCount(report?.snapshotCount ?? 0) },
|
|
8916
|
+
{
|
|
8917
|
+
label: "Resume p95",
|
|
8918
|
+
value: formatMs2(report?.resumeLatencyP95Ms ?? latest?.reconnect?.resumeLatencyP95Ms)
|
|
8919
|
+
},
|
|
8920
|
+
{ label: "Last proof", value: formatAge(latestAt) }
|
|
8921
|
+
],
|
|
8922
|
+
status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : report.status === "empty" ? "empty" : "warning" : snapshot.isLoading ? "loading" : "empty",
|
|
8923
|
+
title: options.title ?? DEFAULT_TITLE6
|
|
8924
|
+
};
|
|
8925
|
+
};
|
|
8926
|
+
var renderVoiceReconnectProfileEvidenceHTML = (snapshot, options = {}) => {
|
|
8927
|
+
const model = createVoiceReconnectProfileEvidenceViewModel(snapshot, options);
|
|
8928
|
+
const metrics = `<div class="absolute-voice-reconnect-evidence__metrics">${model.metrics.map((metric) => `<article>
|
|
8929
|
+
<span>${escapeHtml11(metric.label)}</span>
|
|
8930
|
+
<strong>${escapeHtml11(metric.value)}</strong>
|
|
8931
|
+
</article>`).join("")}</div>`;
|
|
8932
|
+
const latest = model.latest ? `<p class="absolute-voice-reconnect-evidence__latest">Latest ${escapeHtml11(model.latest.profileLabel)} \xB7 ${escapeHtml11(model.latest.sessionId)} \xB7 ${escapeHtml11(model.latest.surfaces)}</p>` : `<p class="absolute-voice-reconnect-evidence__empty">No persisted reconnect profile evidence yet.</p>`;
|
|
8933
|
+
const links = model.links.length ? `<p class="absolute-voice-reconnect-evidence__links">${model.links.map((link) => `<a href="${escapeHtml11(link.href)}">${escapeHtml11(link.label)}</a>`).join("")}</p>` : "";
|
|
8934
|
+
return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${escapeHtml11(model.status)}">
|
|
8935
|
+
<header class="absolute-voice-reconnect-evidence__header">
|
|
8936
|
+
<span class="absolute-voice-reconnect-evidence__eyebrow">${escapeHtml11(model.title)}</span>
|
|
8937
|
+
<strong class="absolute-voice-reconnect-evidence__label">${escapeHtml11(model.label)}</strong>
|
|
8938
|
+
</header>
|
|
8939
|
+
<p class="absolute-voice-reconnect-evidence__description">${escapeHtml11(model.description)}</p>
|
|
8940
|
+
${metrics}
|
|
8941
|
+
${latest}
|
|
8942
|
+
${links}
|
|
8943
|
+
${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${escapeHtml11(model.error)}</p>` : ""}
|
|
8944
|
+
</section>`;
|
|
8945
|
+
};
|
|
8946
|
+
var getVoiceReconnectProfileEvidenceCSS = () => `.absolute-voice-reconnect-evidence{border:1px solid #bae6fd;border-radius:20px;background:#f0f9ff;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(14,165,233,.12);font-family:inherit}.absolute-voice-reconnect-evidence--warning,.absolute-voice-reconnect-evidence--error{border-color:#fbbf24;background:#fffbeb}.absolute-voice-reconnect-evidence__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-reconnect-evidence__eyebrow{color:#0369a1;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-reconnect-evidence__label{font-size:24px;line-height:1}.absolute-voice-reconnect-evidence__description,.absolute-voice-reconnect-evidence__empty,.absolute-voice-reconnect-evidence__latest{color:#475569}.absolute-voice-reconnect-evidence__metrics{display:grid;gap:10px;grid-template-columns:repeat(4,minmax(0,1fr));margin-top:14px}.absolute-voice-reconnect-evidence__metrics article{background:#fff;border:1px solid #bae6fd;border-radius:16px;padding:12px}.absolute-voice-reconnect-evidence__metrics span{color:#64748b;display:block;font-size:11px;font-weight:800;text-transform:uppercase}.absolute-voice-reconnect-evidence__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-reconnect-evidence__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-reconnect-evidence__links a{border:1px solid #7dd3fc;border-radius:999px;color:#0369a1;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-reconnect-evidence__error{color:#9f1239;font-weight:700}@media (max-width:720px){.absolute-voice-reconnect-evidence__metrics{grid-template-columns:repeat(2,minmax(0,1fr))}}`;
|
|
8947
|
+
var mountVoiceReconnectProfileEvidence = (element, path = "/api/voice/reconnect-profile-evidence", options = {}) => {
|
|
8948
|
+
const store = createVoiceReconnectProfileEvidenceStore(path, options);
|
|
8949
|
+
const render = () => {
|
|
8950
|
+
element.innerHTML = renderVoiceReconnectProfileEvidenceHTML(store.getSnapshot(), options);
|
|
8951
|
+
};
|
|
8952
|
+
const unsubscribe = store.subscribe(render);
|
|
8953
|
+
render();
|
|
8954
|
+
store.refresh().catch(() => {});
|
|
8955
|
+
return {
|
|
8956
|
+
close: () => {
|
|
8957
|
+
unsubscribe();
|
|
8958
|
+
store.close();
|
|
8959
|
+
},
|
|
8960
|
+
refresh: store.refresh
|
|
8961
|
+
};
|
|
8962
|
+
};
|
|
8963
|
+
var defineVoiceReconnectProfileEvidenceElement = (tagName = "absolute-voice-reconnect-profile-evidence") => {
|
|
8964
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
8965
|
+
return;
|
|
8966
|
+
}
|
|
8967
|
+
customElements.define(tagName, class AbsoluteVoiceReconnectProfileEvidenceElement extends HTMLElement {
|
|
8968
|
+
mounted;
|
|
8969
|
+
connectedCallback() {
|
|
8970
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
|
|
8971
|
+
this.mounted = mountVoiceReconnectProfileEvidence(this, this.getAttribute("path") ?? "/api/voice/reconnect-profile-evidence", {
|
|
8972
|
+
description: this.getAttribute("description") ?? undefined,
|
|
8973
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
|
|
8974
|
+
title: this.getAttribute("title") ?? undefined
|
|
8975
|
+
});
|
|
8976
|
+
}
|
|
8977
|
+
disconnectedCallback() {
|
|
8978
|
+
this.mounted?.close();
|
|
8979
|
+
this.mounted = undefined;
|
|
8980
|
+
}
|
|
8981
|
+
});
|
|
8982
|
+
};
|
|
8983
|
+
// src/client/profileComparisonWidget.ts
|
|
8984
|
+
var DEFAULT_TITLE7 = "Profile Stack Comparison";
|
|
8985
|
+
var DEFAULT_DESCRIPTION7 = "Measured real-call evidence behind each profile default: provider routes, latency, and the next move.";
|
|
8986
|
+
var DEFAULT_LINKS4 = [
|
|
8987
|
+
{ href: "/voice/real-call-profile-history", label: "Profile history" },
|
|
8988
|
+
{ href: "/api/voice/real-call-profile-history", label: "JSON" }
|
|
8989
|
+
];
|
|
8990
|
+
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8991
|
+
var formatMs3 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
8580
8992
|
var formatProviderRoutes = (profile) => Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "No complete route yet";
|
|
8581
8993
|
var createProfileView = (profile) => ({
|
|
8582
8994
|
evidence: [
|
|
8583
|
-
{ label: "Live p95", value:
|
|
8584
|
-
{ label: "Provider p95", value:
|
|
8585
|
-
{ label: "Turn p95", value:
|
|
8995
|
+
{ label: "Live p95", value: formatMs3(profile.evidence.liveP95Ms) },
|
|
8996
|
+
{ label: "Provider p95", value: formatMs3(profile.evidence.providerP95Ms) },
|
|
8997
|
+
{ label: "Turn p95", value: formatMs3(profile.evidence.turnP95Ms) }
|
|
8586
8998
|
],
|
|
8587
8999
|
label: profile.label ?? profile.profileId,
|
|
8588
9000
|
nextMove: profile.nextMove,
|
|
@@ -8594,37 +9006,37 @@ var createVoiceProfileComparisonViewModel = (snapshot, options = {}) => {
|
|
|
8594
9006
|
const report = snapshot.report;
|
|
8595
9007
|
const profiles = report?.defaults.profiles.map(createProfileView) ?? [];
|
|
8596
9008
|
return {
|
|
8597
|
-
description: options.description ??
|
|
9009
|
+
description: options.description ?? DEFAULT_DESCRIPTION7,
|
|
8598
9010
|
error: snapshot.error,
|
|
8599
9011
|
isLoading: snapshot.isLoading,
|
|
8600
9012
|
label: snapshot.error ? "Unavailable" : report ? `${report.defaults.summary.actionableProfiles}/${report.defaults.summary.profileCount} profiles ready` : snapshot.isLoading ? "Checking" : "No profile evidence",
|
|
8601
|
-
links: options.links ??
|
|
9013
|
+
links: options.links ?? DEFAULT_LINKS4,
|
|
8602
9014
|
profiles,
|
|
8603
9015
|
status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : "warning" : snapshot.isLoading ? "loading" : "empty",
|
|
8604
|
-
title: options.title ??
|
|
9016
|
+
title: options.title ?? DEFAULT_TITLE7
|
|
8605
9017
|
};
|
|
8606
9018
|
};
|
|
8607
9019
|
var renderVoiceProfileComparisonHTML = (snapshot, options = {}) => {
|
|
8608
9020
|
const model = createVoiceProfileComparisonViewModel(snapshot, options);
|
|
8609
|
-
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--${
|
|
9021
|
+
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--${escapeHtml12(profile.status)}">
|
|
8610
9022
|
<header>
|
|
8611
|
-
<span>${
|
|
8612
|
-
<strong>${
|
|
9023
|
+
<span>${escapeHtml12(profile.status)}</span>
|
|
9024
|
+
<strong>${escapeHtml12(profile.label)}</strong>
|
|
8613
9025
|
</header>
|
|
8614
|
-
<p>${
|
|
8615
|
-
<div>${profile.evidence.map((metric) => `<span><small>${
|
|
8616
|
-
<em>${
|
|
8617
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ?
|
|
8618
|
-
const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${
|
|
8619
|
-
return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${
|
|
9026
|
+
<p>${escapeHtml12(profile.providerRoutes)}</p>
|
|
9027
|
+
<div>${profile.evidence.map((metric) => `<span><small>${escapeHtml12(metric.label)}</small><b>${escapeHtml12(metric.value)}</b></span>`).join("")}</div>
|
|
9028
|
+
<em>${escapeHtml12(profile.nextMove)}</em>
|
|
9029
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ? escapeHtml12(model.error) : "Run real-call profile collection to populate profile comparisons."}</p>`;
|
|
9030
|
+
const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${escapeHtml12(link.href)}">${escapeHtml12(link.label)}</a>`).join("")}</p>` : "";
|
|
9031
|
+
return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${escapeHtml12(model.status)}">
|
|
8620
9032
|
<header class="absolute-voice-profile-comparison__header">
|
|
8621
|
-
<span class="absolute-voice-profile-comparison__eyebrow">${
|
|
8622
|
-
<strong class="absolute-voice-profile-comparison__label">${
|
|
9033
|
+
<span class="absolute-voice-profile-comparison__eyebrow">${escapeHtml12(model.title)}</span>
|
|
9034
|
+
<strong class="absolute-voice-profile-comparison__label">${escapeHtml12(model.label)}</strong>
|
|
8623
9035
|
</header>
|
|
8624
|
-
<p class="absolute-voice-profile-comparison__description">${
|
|
9036
|
+
<p class="absolute-voice-profile-comparison__description">${escapeHtml12(model.description)}</p>
|
|
8625
9037
|
${profiles}
|
|
8626
9038
|
${links}
|
|
8627
|
-
${model.error ? `<p class="absolute-voice-profile-comparison__error">${
|
|
9039
|
+
${model.error ? `<p class="absolute-voice-profile-comparison__error">${escapeHtml12(model.error)}</p>` : ""}
|
|
8628
9040
|
</section>`;
|
|
8629
9041
|
};
|
|
8630
9042
|
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}`;
|
|
@@ -8665,29 +9077,29 @@ var defineVoiceProfileComparisonElement = (tagName = "absolute-voice-profile-com
|
|
|
8665
9077
|
});
|
|
8666
9078
|
};
|
|
8667
9079
|
// src/client/profileSwitchRecommendationWidget.ts
|
|
8668
|
-
var
|
|
8669
|
-
var
|
|
8670
|
-
var
|
|
9080
|
+
var DEFAULT_TITLE8 = "Profile Switch Recommendation";
|
|
9081
|
+
var DEFAULT_DESCRIPTION8 = "Compares the current session against measured profile evidence and recommends whether to switch stacks.";
|
|
9082
|
+
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8671
9083
|
var formatRoute = (routes) => routes ? Object.entries(routes).map(([role, provider]) => `${role}: ${provider}`).join(", ") : "No route";
|
|
8672
9084
|
var renderVoiceProfileSwitchRecommendationHTML = (snapshot, options = {}) => {
|
|
8673
9085
|
const recommendation = snapshot.recommendation;
|
|
8674
9086
|
const status = snapshot.error ? "error" : recommendation ? recommendation.status : snapshot.isLoading ? "loading" : "empty";
|
|
8675
9087
|
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";
|
|
8676
9088
|
const body = recommendation ? `<div class="absolute-voice-profile-switch__body">
|
|
8677
|
-
<p><strong>Current:</strong> ${
|
|
8678
|
-
<p><strong>Recommended:</strong> ${
|
|
8679
|
-
<p><strong>Routes:</strong> ${
|
|
8680
|
-
<ul>${recommendation.reasons.map((reason) => `<li>${
|
|
8681
|
-
<em>${
|
|
8682
|
-
</div>` : `<p class="absolute-voice-profile-switch__empty">${
|
|
8683
|
-
return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${
|
|
9089
|
+
<p><strong>Current:</strong> ${escapeHtml13(recommendation.currentProfile?.label ?? recommendation.currentProfile?.profileId ?? "Unknown")}</p>
|
|
9090
|
+
<p><strong>Recommended:</strong> ${escapeHtml13(recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "None")}</p>
|
|
9091
|
+
<p><strong>Routes:</strong> ${escapeHtml13(formatRoute(recommendation.recommendedProfile?.providerRoutes))}</p>
|
|
9092
|
+
<ul>${recommendation.reasons.map((reason) => `<li>${escapeHtml13(reason)}</li>`).join("")}</ul>
|
|
9093
|
+
<em>${escapeHtml13(recommendation.nextMove)}</em>
|
|
9094
|
+
</div>` : `<p class="absolute-voice-profile-switch__empty">${escapeHtml13(snapshot.error ?? "Run session traffic to populate a recommendation.")}</p>`;
|
|
9095
|
+
return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${escapeHtml13(status)}">
|
|
8684
9096
|
<header class="absolute-voice-profile-switch__header">
|
|
8685
|
-
<span class="absolute-voice-profile-switch__eyebrow">${
|
|
8686
|
-
<strong class="absolute-voice-profile-switch__label">${
|
|
9097
|
+
<span class="absolute-voice-profile-switch__eyebrow">${escapeHtml13(options.title ?? DEFAULT_TITLE8)}</span>
|
|
9098
|
+
<strong class="absolute-voice-profile-switch__label">${escapeHtml13(label)}</strong>
|
|
8687
9099
|
</header>
|
|
8688
|
-
<p class="absolute-voice-profile-switch__description">${
|
|
9100
|
+
<p class="absolute-voice-profile-switch__description">${escapeHtml13(options.description ?? DEFAULT_DESCRIPTION8)}</p>
|
|
8689
9101
|
${body}
|
|
8690
|
-
${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${
|
|
9102
|
+
${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${escapeHtml13(snapshot.error)}</p>` : ""}
|
|
8691
9103
|
</section>`;
|
|
8692
9104
|
};
|
|
8693
9105
|
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}`;
|
|
@@ -8728,13 +9140,13 @@ var defineVoiceProfileSwitchRecommendationElement = (tagName = "absolute-voice-p
|
|
|
8728
9140
|
});
|
|
8729
9141
|
};
|
|
8730
9142
|
// src/client/readinessFailuresWidget.ts
|
|
8731
|
-
var
|
|
8732
|
-
var
|
|
8733
|
-
var
|
|
9143
|
+
var DEFAULT_TITLE9 = "Readiness Gate Explanations";
|
|
9144
|
+
var DEFAULT_DESCRIPTION9 = "Structured reasons for calibrated production-readiness warnings and failures.";
|
|
9145
|
+
var DEFAULT_LINKS5 = [
|
|
8734
9146
|
{ href: "/production-readiness", label: "Readiness page" },
|
|
8735
9147
|
{ href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
|
|
8736
9148
|
];
|
|
8737
|
-
var
|
|
9149
|
+
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8738
9150
|
var formatExplanationValue = (value, unit) => {
|
|
8739
9151
|
if (value === undefined || value === null) {
|
|
8740
9152
|
return "n/a";
|
|
@@ -8762,36 +9174,36 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
|
|
|
8762
9174
|
const failures = snapshot.report?.checks.map(toFailureView).filter((value) => !!value) ?? [];
|
|
8763
9175
|
const hasOpenIssues = failures.length > 0;
|
|
8764
9176
|
return {
|
|
8765
|
-
description: options.description ??
|
|
9177
|
+
description: options.description ?? DEFAULT_DESCRIPTION9,
|
|
8766
9178
|
error: snapshot.error,
|
|
8767
9179
|
failures,
|
|
8768
9180
|
isLoading: snapshot.isLoading,
|
|
8769
9181
|
label: snapshot.error ? "Unavailable" : snapshot.report ? hasOpenIssues ? `${failures.length} calibrated gate issue(s)` : "No calibrated gate issues" : snapshot.isLoading ? "Checking" : "No readiness report",
|
|
8770
|
-
links: options.links ??
|
|
9182
|
+
links: options.links ?? DEFAULT_LINKS5,
|
|
8771
9183
|
status: snapshot.error ? "error" : snapshot.report ? hasOpenIssues ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
8772
|
-
title: options.title ??
|
|
9184
|
+
title: options.title ?? DEFAULT_TITLE9,
|
|
8773
9185
|
updatedAt: snapshot.updatedAt
|
|
8774
9186
|
};
|
|
8775
9187
|
};
|
|
8776
9188
|
var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
|
|
8777
9189
|
const model = createVoiceReadinessFailuresViewModel(snapshot, options);
|
|
8778
|
-
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--${
|
|
8779
|
-
<span>${
|
|
8780
|
-
<strong>${
|
|
8781
|
-
<p>Observed ${
|
|
8782
|
-
<p>${
|
|
8783
|
-
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${
|
|
8784
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ?
|
|
8785
|
-
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${
|
|
8786
|
-
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${
|
|
9190
|
+
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--${escapeHtml14(failure.status)}">
|
|
9191
|
+
<span>${escapeHtml14(failure.status.toUpperCase())}</span>
|
|
9192
|
+
<strong>${escapeHtml14(failure.label)}</strong>
|
|
9193
|
+
<p>Observed ${escapeHtml14(failure.observed)} against ${escapeHtml14(failure.thresholdLabel)} ${escapeHtml14(failure.threshold)}.</p>
|
|
9194
|
+
<p>${escapeHtml14(failure.remediation)}</p>
|
|
9195
|
+
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml14(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml14(failure.sourceHref)}">Threshold source</a>` : ""}</p>
|
|
9196
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml14(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
|
|
9197
|
+
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml14(link.href)}">${escapeHtml14(link.label)}</a>`).join("")}</p>` : "";
|
|
9198
|
+
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml14(model.status)}">
|
|
8787
9199
|
<header class="absolute-voice-readiness-failures__header">
|
|
8788
|
-
<span class="absolute-voice-readiness-failures__eyebrow">${
|
|
8789
|
-
<strong class="absolute-voice-readiness-failures__label">${
|
|
9200
|
+
<span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml14(model.title)}</span>
|
|
9201
|
+
<strong class="absolute-voice-readiness-failures__label">${escapeHtml14(model.label)}</strong>
|
|
8790
9202
|
</header>
|
|
8791
|
-
<p class="absolute-voice-readiness-failures__description">${
|
|
9203
|
+
<p class="absolute-voice-readiness-failures__description">${escapeHtml14(model.description)}</p>
|
|
8792
9204
|
${failures}
|
|
8793
9205
|
${links}
|
|
8794
|
-
${model.error ? `<p class="absolute-voice-readiness-failures__error">${
|
|
9206
|
+
${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml14(model.error)}</p>` : ""}
|
|
8795
9207
|
</section>`;
|
|
8796
9208
|
};
|
|
8797
9209
|
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}`;
|
|
@@ -8831,9 +9243,9 @@ var defineVoiceReadinessFailuresElement = (tagName = "absolute-voice-readiness-f
|
|
|
8831
9243
|
});
|
|
8832
9244
|
};
|
|
8833
9245
|
// src/client/opsActionCenterWidget.ts
|
|
8834
|
-
var
|
|
8835
|
-
var
|
|
8836
|
-
var
|
|
9246
|
+
var DEFAULT_TITLE10 = "Voice Ops Action Center";
|
|
9247
|
+
var DEFAULT_DESCRIPTION10 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
9248
|
+
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
8837
9249
|
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
8838
9250
|
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
8839
9251
|
return {
|
|
@@ -8844,29 +9256,29 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
|
8844
9256
|
isRunning: snapshot.runningActionId === action.id,
|
|
8845
9257
|
label: action.label
|
|
8846
9258
|
})),
|
|
8847
|
-
description: options.description ??
|
|
9259
|
+
description: options.description ?? DEFAULT_DESCRIPTION10,
|
|
8848
9260
|
error: snapshot.error,
|
|
8849
9261
|
isRunning: snapshot.isRunning,
|
|
8850
9262
|
label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
|
|
8851
9263
|
lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
|
|
8852
9264
|
status,
|
|
8853
|
-
title: options.title ??
|
|
9265
|
+
title: options.title ?? DEFAULT_TITLE10
|
|
8854
9266
|
};
|
|
8855
9267
|
};
|
|
8856
9268
|
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
8857
9269
|
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
8858
|
-
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${
|
|
8859
|
-
${
|
|
9270
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml15(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
9271
|
+
${escapeHtml15(action.isRunning ? "Working..." : action.label)}
|
|
8860
9272
|
</button>`).join("");
|
|
8861
|
-
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${
|
|
9273
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml15(model.status)}">
|
|
8862
9274
|
<header class="absolute-voice-ops-action-center__header">
|
|
8863
|
-
<span class="absolute-voice-ops-action-center__eyebrow">${
|
|
8864
|
-
<strong class="absolute-voice-ops-action-center__label">${
|
|
9275
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml15(model.title)}</span>
|
|
9276
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml15(model.label)}</strong>
|
|
8865
9277
|
</header>
|
|
8866
|
-
<p class="absolute-voice-ops-action-center__description">${
|
|
9278
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml15(model.description)}</p>
|
|
8867
9279
|
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
8868
|
-
<p class="absolute-voice-ops-action-center__result">${
|
|
8869
|
-
${model.error ? `<p class="absolute-voice-ops-action-center__error">${
|
|
9280
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml15(model.lastResultLabel)}</p>
|
|
9281
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml15(model.error)}</p>` : ""}
|
|
8870
9282
|
</section>`;
|
|
8871
9283
|
};
|
|
8872
9284
|
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}`;
|
|
@@ -9465,7 +9877,7 @@ var ACTION_LABELS = {
|
|
|
9465
9877
|
"resume-assistant": "Resume assistant",
|
|
9466
9878
|
tag: "Tag"
|
|
9467
9879
|
};
|
|
9468
|
-
var
|
|
9880
|
+
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9469
9881
|
var createVoiceLiveOpsInput = (action, input) => ({
|
|
9470
9882
|
action,
|
|
9471
9883
|
assignee: input.assignee,
|
|
@@ -9476,17 +9888,17 @@ var createVoiceLiveOpsInput = (action, input) => ({
|
|
|
9476
9888
|
var renderVoiceLiveOpsHTML = (snapshot, options = {}) => {
|
|
9477
9889
|
const sessionId = options.getSessionId?.() ?? "";
|
|
9478
9890
|
const disabled = snapshot.isRunning || !sessionId;
|
|
9479
|
-
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${
|
|
9480
|
-
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${
|
|
9891
|
+
const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml16(action)}"${disabled ? " disabled" : ""}>${escapeHtml16(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
|
|
9892
|
+
const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml16(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml16(snapshot.lastResult.action)}. Control: ${escapeHtml16(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
|
|
9481
9893
|
return `<section class="absolute-voice-live-ops">
|
|
9482
9894
|
<header class="absolute-voice-live-ops__header">
|
|
9483
|
-
<span>${
|
|
9484
|
-
<strong>${
|
|
9895
|
+
<span>${escapeHtml16(options.title ?? "Live Ops")}</span>
|
|
9896
|
+
<strong>${escapeHtml16(sessionId || "No active session")}</strong>
|
|
9485
9897
|
</header>
|
|
9486
|
-
<p class="absolute-voice-live-ops__description">${
|
|
9487
|
-
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${
|
|
9488
|
-
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${
|
|
9489
|
-
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${
|
|
9898
|
+
<p class="absolute-voice-live-ops__description">${escapeHtml16(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
|
|
9899
|
+
<label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml16(options.defaultAssignee ?? "operator")}" /></label>
|
|
9900
|
+
<label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml16(options.defaultTag ?? "live-ops")}" /></label>
|
|
9901
|
+
<label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml16(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
|
|
9490
9902
|
<div class="absolute-voice-live-ops__actions">${actions}</div>
|
|
9491
9903
|
${result}
|
|
9492
9904
|
</section>`;
|
|
@@ -9573,16 +9985,16 @@ var defineVoiceLiveOpsElement = (tagName = "absolute-voice-live-ops", options =
|
|
|
9573
9985
|
});
|
|
9574
9986
|
};
|
|
9575
9987
|
// src/client/opsActionHistoryWidget.ts
|
|
9576
|
-
var
|
|
9988
|
+
var escapeHtml17 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9577
9989
|
var renderVoiceOpsActionHistoryWidgetHTML = (snapshot, options = {}) => {
|
|
9578
9990
|
const report = snapshot.report;
|
|
9579
9991
|
const entries = (report?.entries ?? []).slice(0, options.limit ?? 5);
|
|
9580
|
-
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${
|
|
9992
|
+
const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml17(entry.actionId)}</span><strong>${escapeHtml17(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml17(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
|
|
9581
9993
|
return `<section class="absolute-voice-ops-action-history">
|
|
9582
|
-
<header><span>Operator proof</span><strong>${
|
|
9994
|
+
<header><span>Operator proof</span><strong>${escapeHtml17(options.title ?? "Action History")}</strong></header>
|
|
9583
9995
|
<p>${String(report?.total ?? 0)} action(s), ${String(report?.failed ?? 0)} failed.</p>
|
|
9584
9996
|
<ul>${rows || "<li>No operator actions recorded yet.</li>"}</ul>
|
|
9585
|
-
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${
|
|
9997
|
+
${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml17(snapshot.error)}</p>` : ""}
|
|
9586
9998
|
</section>`;
|
|
9587
9999
|
};
|
|
9588
10000
|
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}`;
|
|
@@ -9603,9 +10015,9 @@ var mountVoiceOpsActionHistory = (element, path = "/api/voice/ops-actions/histor
|
|
|
9603
10015
|
};
|
|
9604
10016
|
};
|
|
9605
10017
|
// src/client/deliveryRuntimeWidget.ts
|
|
9606
|
-
var
|
|
9607
|
-
var
|
|
9608
|
-
var
|
|
10018
|
+
var DEFAULT_TITLE11 = "Voice Delivery Runtime";
|
|
10019
|
+
var DEFAULT_DESCRIPTION11 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
10020
|
+
var escapeHtml18 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9609
10021
|
var createSurface = (id, summary) => {
|
|
9610
10022
|
if (!summary) {
|
|
9611
10023
|
return {
|
|
@@ -9639,7 +10051,7 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
9639
10051
|
];
|
|
9640
10052
|
const hasWarnings = surfaces.some((surface) => surface.status === "warn");
|
|
9641
10053
|
return {
|
|
9642
|
-
description: options.description ??
|
|
10054
|
+
description: options.description ?? DEFAULT_DESCRIPTION11,
|
|
9643
10055
|
error: snapshot.error,
|
|
9644
10056
|
actionError: snapshot.actionError,
|
|
9645
10057
|
actionStatus: snapshot.actionStatus,
|
|
@@ -9648,32 +10060,32 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
9648
10060
|
label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
|
|
9649
10061
|
status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
|
|
9650
10062
|
surfaces,
|
|
9651
|
-
title: options.title ??
|
|
10063
|
+
title: options.title ?? DEFAULT_TITLE11,
|
|
9652
10064
|
updatedAt: snapshot.updatedAt
|
|
9653
10065
|
};
|
|
9654
10066
|
};
|
|
9655
10067
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
9656
10068
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
9657
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
9658
|
-
<span>${
|
|
9659
|
-
<strong>${
|
|
10069
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml18(surface.status)}">
|
|
10070
|
+
<span>${escapeHtml18(surface.label)}</span>
|
|
10071
|
+
<strong>${escapeHtml18(surface.detail)}</strong>
|
|
9660
10072
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
9661
10073
|
</li>`).join("");
|
|
9662
10074
|
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
9663
10075
|
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
9664
10076
|
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
9665
10077
|
</div>`;
|
|
9666
|
-
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
9667
|
-
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${
|
|
10078
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml18(model.actionError)}</p>` : "";
|
|
10079
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml18(model.status)}">
|
|
9668
10080
|
<header class="absolute-voice-delivery-runtime__header">
|
|
9669
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
9670
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
10081
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml18(model.title)}</span>
|
|
10082
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml18(model.label)}</strong>
|
|
9671
10083
|
</header>
|
|
9672
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
10084
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml18(model.description)}</p>
|
|
9673
10085
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
9674
10086
|
${actions}
|
|
9675
10087
|
${actionError}
|
|
9676
|
-
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${
|
|
10088
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml18(model.error)}</p>` : ""}
|
|
9677
10089
|
</section>`;
|
|
9678
10090
|
};
|
|
9679
10091
|
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}`;
|
|
@@ -9809,9 +10221,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
9809
10221
|
};
|
|
9810
10222
|
};
|
|
9811
10223
|
// src/client/routingStatusWidget.ts
|
|
9812
|
-
var
|
|
9813
|
-
var
|
|
9814
|
-
var
|
|
10224
|
+
var DEFAULT_TITLE12 = "Voice Routing";
|
|
10225
|
+
var DEFAULT_DESCRIPTION12 = "Latest provider routing decision from the self-hosted trace store.";
|
|
10226
|
+
var escapeHtml19 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9815
10227
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
9816
10228
|
var formatProviderRoutes2 = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
|
|
9817
10229
|
var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
|
|
@@ -9880,35 +10292,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
9880
10292
|
return {
|
|
9881
10293
|
activeStack,
|
|
9882
10294
|
decision,
|
|
9883
|
-
description: options.description ??
|
|
10295
|
+
description: options.description ?? DEFAULT_DESCRIPTION12,
|
|
9884
10296
|
error: snapshot.error,
|
|
9885
10297
|
isLoading: snapshot.isLoading,
|
|
9886
10298
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
9887
10299
|
rows,
|
|
9888
10300
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
9889
|
-
title: options.title ??
|
|
10301
|
+
title: options.title ?? DEFAULT_TITLE12,
|
|
9890
10302
|
updatedAt: snapshot.updatedAt
|
|
9891
10303
|
};
|
|
9892
10304
|
};
|
|
9893
10305
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
9894
10306
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
9895
10307
|
const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
|
|
9896
|
-
<span>${
|
|
9897
|
-
<strong>${
|
|
10308
|
+
<span>${escapeHtml19(item.label)}</span>
|
|
10309
|
+
<strong>${escapeHtml19(item.value)}</strong>
|
|
9898
10310
|
</div>`).join("")}</div>` : "";
|
|
9899
10311
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
9900
|
-
<span>${
|
|
9901
|
-
<strong>${
|
|
10312
|
+
<span>${escapeHtml19(row.label)}</span>
|
|
10313
|
+
<strong>${escapeHtml19(row.value)}</strong>
|
|
9902
10314
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
9903
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
10315
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml19(model.status)}">
|
|
9904
10316
|
<header class="absolute-voice-routing-status__header">
|
|
9905
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
9906
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
10317
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml19(model.title)}</span>
|
|
10318
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml19(model.label)}</strong>
|
|
9907
10319
|
</header>
|
|
9908
|
-
<p class="absolute-voice-routing-status__description">${
|
|
10320
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml19(model.description)}</p>
|
|
9909
10321
|
${activeStack}
|
|
9910
10322
|
${rows}
|
|
9911
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
10323
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml19(model.error)}</p>` : ""}
|
|
9912
10324
|
</section>`;
|
|
9913
10325
|
};
|
|
9914
10326
|
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}}`;
|
|
@@ -10707,7 +11119,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
10707
11119
|
};
|
|
10708
11120
|
};
|
|
10709
11121
|
// src/client/providerSimulationControlsWidget.ts
|
|
10710
|
-
var
|
|
11122
|
+
var escapeHtml20 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
10711
11123
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
10712
11124
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
10713
11125
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -10727,18 +11139,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
10727
11139
|
};
|
|
10728
11140
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
10729
11141
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
10730
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
10731
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
11142
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml20(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml20(provider.provider)} ${escapeHtml20(formatKind(options.kind))} failure</button>`).join("");
|
|
11143
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml20(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml20(provider.provider)} recovered</button>`).join("");
|
|
10732
11144
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
10733
11145
|
<header class="absolute-voice-provider-simulation__header">
|
|
10734
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
10735
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
11146
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml20(model.title)}</span>
|
|
11147
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml20(model.label)}</strong>
|
|
10736
11148
|
</header>
|
|
10737
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
10738
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
11149
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml20(model.description)}</p>
|
|
11150
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml20(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
10739
11151
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
10740
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
10741
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
11152
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml20(snapshot.error)}</p>` : ""}
|
|
11153
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml20(model.resultText)}</pre>` : ""}
|
|
10742
11154
|
</section>`;
|
|
10743
11155
|
};
|
|
10744
11156
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -10803,9 +11215,9 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
|
|
|
10803
11215
|
});
|
|
10804
11216
|
};
|
|
10805
11217
|
// src/client/providerStatusWidget.ts
|
|
10806
|
-
var
|
|
10807
|
-
var
|
|
10808
|
-
var
|
|
11218
|
+
var DEFAULT_TITLE13 = "Voice Providers";
|
|
11219
|
+
var DEFAULT_DESCRIPTION13 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
11220
|
+
var escapeHtml21 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
10809
11221
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
10810
11222
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
10811
11223
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -10849,37 +11261,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
10849
11261
|
const warningCount = providers.filter((provider) => isWarningStatus(provider.status)).length;
|
|
10850
11262
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
10851
11263
|
return {
|
|
10852
|
-
description: options.description ??
|
|
11264
|
+
description: options.description ?? DEFAULT_DESCRIPTION13,
|
|
10853
11265
|
error: snapshot.error,
|
|
10854
11266
|
isLoading: snapshot.isLoading,
|
|
10855
11267
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
10856
11268
|
providers,
|
|
10857
11269
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
10858
|
-
title: options.title ??
|
|
11270
|
+
title: options.title ?? DEFAULT_TITLE13,
|
|
10859
11271
|
updatedAt: snapshot.updatedAt
|
|
10860
11272
|
};
|
|
10861
11273
|
};
|
|
10862
11274
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
10863
11275
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
10864
|
-
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--${
|
|
11276
|
+
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--${escapeHtml21(provider.status)}">
|
|
10865
11277
|
<header>
|
|
10866
|
-
<strong>${
|
|
10867
|
-
<span>${
|
|
11278
|
+
<strong>${escapeHtml21(provider.label)}</strong>
|
|
11279
|
+
<span>${escapeHtml21(formatStatus3(provider.status))}</span>
|
|
10868
11280
|
</header>
|
|
10869
|
-
<p>${
|
|
11281
|
+
<p>${escapeHtml21(provider.detail)}</p>
|
|
10870
11282
|
<dl>${provider.rows.map((row) => `<div>
|
|
10871
|
-
<dt>${
|
|
10872
|
-
<dd>${
|
|
11283
|
+
<dt>${escapeHtml21(row.label)}</dt>
|
|
11284
|
+
<dd>${escapeHtml21(row.value)}</dd>
|
|
10873
11285
|
</div>`).join("")}</dl>
|
|
10874
11286
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
10875
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
11287
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml21(model.status)}">
|
|
10876
11288
|
<header class="absolute-voice-provider-status__header">
|
|
10877
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
10878
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
11289
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml21(model.title)}</span>
|
|
11290
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml21(model.label)}</strong>
|
|
10879
11291
|
</header>
|
|
10880
|
-
<p class="absolute-voice-provider-status__description">${
|
|
11292
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml21(model.description)}</p>
|
|
10881
11293
|
${providers}
|
|
10882
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
11294
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml21(model.error)}</p>` : ""}
|
|
10883
11295
|
</section>`;
|
|
10884
11296
|
};
|
|
10885
11297
|
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}`;
|
|
@@ -10920,9 +11332,9 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
10920
11332
|
});
|
|
10921
11333
|
};
|
|
10922
11334
|
// src/client/providerCapabilitiesWidget.ts
|
|
10923
|
-
var
|
|
10924
|
-
var
|
|
10925
|
-
var
|
|
11335
|
+
var DEFAULT_TITLE14 = "Provider Capabilities";
|
|
11336
|
+
var DEFAULT_DESCRIPTION14 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
11337
|
+
var escapeHtml22 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
10926
11338
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
10927
11339
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
10928
11340
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -10966,36 +11378,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
10966
11378
|
const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
|
|
10967
11379
|
return {
|
|
10968
11380
|
capabilities,
|
|
10969
|
-
description: options.description ??
|
|
11381
|
+
description: options.description ?? DEFAULT_DESCRIPTION14,
|
|
10970
11382
|
error: snapshot.error,
|
|
10971
11383
|
isLoading: snapshot.isLoading,
|
|
10972
11384
|
label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
|
|
10973
11385
|
status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
10974
|
-
title: options.title ??
|
|
11386
|
+
title: options.title ?? DEFAULT_TITLE14,
|
|
10975
11387
|
updatedAt: snapshot.updatedAt
|
|
10976
11388
|
};
|
|
10977
11389
|
};
|
|
10978
11390
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
10979
11391
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
10980
|
-
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--${
|
|
11392
|
+
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--${escapeHtml22(capability.status)}">
|
|
10981
11393
|
<header>
|
|
10982
|
-
<strong>${
|
|
10983
|
-
<span>${
|
|
11394
|
+
<strong>${escapeHtml22(capability.label)}</strong>
|
|
11395
|
+
<span>${escapeHtml22(formatStatus4(capability.status))}</span>
|
|
10984
11396
|
</header>
|
|
10985
|
-
<p>${
|
|
11397
|
+
<p>${escapeHtml22(capability.detail)}</p>
|
|
10986
11398
|
<dl>${capability.rows.map((row) => `<div>
|
|
10987
|
-
<dt>${
|
|
10988
|
-
<dd>${
|
|
11399
|
+
<dt>${escapeHtml22(row.label)}</dt>
|
|
11400
|
+
<dd>${escapeHtml22(row.value)}</dd>
|
|
10989
11401
|
</div>`).join("")}</dl>
|
|
10990
11402
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
10991
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
11403
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml22(model.status)}">
|
|
10992
11404
|
<header class="absolute-voice-provider-capabilities__header">
|
|
10993
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
10994
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
11405
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml22(model.title)}</span>
|
|
11406
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml22(model.label)}</strong>
|
|
10995
11407
|
</header>
|
|
10996
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
11408
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml22(model.description)}</p>
|
|
10997
11409
|
${capabilities}
|
|
10998
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
11410
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml22(model.error)}</p>` : ""}
|
|
10999
11411
|
</section>`;
|
|
11000
11412
|
};
|
|
11001
11413
|
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}`;
|
|
@@ -11036,9 +11448,9 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
|
|
|
11036
11448
|
});
|
|
11037
11449
|
};
|
|
11038
11450
|
// src/client/providerContractsWidget.ts
|
|
11039
|
-
var
|
|
11040
|
-
var
|
|
11041
|
-
var
|
|
11451
|
+
var DEFAULT_TITLE15 = "Provider Contracts";
|
|
11452
|
+
var DEFAULT_DESCRIPTION15 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
11453
|
+
var escapeHtml23 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11042
11454
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
11043
11455
|
var formatStatus5 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
11044
11456
|
var contractDetail = (row) => {
|
|
@@ -11070,38 +11482,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
11070
11482
|
}));
|
|
11071
11483
|
const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
|
|
11072
11484
|
return {
|
|
11073
|
-
description: options.description ??
|
|
11485
|
+
description: options.description ?? DEFAULT_DESCRIPTION15,
|
|
11074
11486
|
error: snapshot.error,
|
|
11075
11487
|
isLoading: snapshot.isLoading,
|
|
11076
11488
|
label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
|
|
11077
11489
|
rows,
|
|
11078
11490
|
status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
11079
|
-
title: options.title ??
|
|
11491
|
+
title: options.title ?? DEFAULT_TITLE15,
|
|
11080
11492
|
updatedAt: snapshot.updatedAt
|
|
11081
11493
|
};
|
|
11082
11494
|
};
|
|
11083
11495
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
11084
11496
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
11085
|
-
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--${
|
|
11497
|
+
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--${escapeHtml23(row.status)}">
|
|
11086
11498
|
<header>
|
|
11087
|
-
<strong>${
|
|
11088
|
-
<span>${
|
|
11499
|
+
<strong>${escapeHtml23(row.label)}</strong>
|
|
11500
|
+
<span>${escapeHtml23(formatStatus5(row.status))}</span>
|
|
11089
11501
|
</header>
|
|
11090
|
-
<p>${
|
|
11091
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
11502
|
+
<p>${escapeHtml23(row.detail)}</p>
|
|
11503
|
+
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml23(remediation.href)}">${escapeHtml23(remediation.label)}</a>` : `<strong>${escapeHtml23(remediation.label)}</strong>`}<span>${escapeHtml23(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
|
|
11092
11504
|
<dl>${row.rows.map((item) => `<div>
|
|
11093
|
-
<dt>${
|
|
11094
|
-
<dd>${
|
|
11505
|
+
<dt>${escapeHtml23(item.label)}</dt>
|
|
11506
|
+
<dd>${escapeHtml23(item.value)}</dd>
|
|
11095
11507
|
</div>`).join("")}</dl>
|
|
11096
11508
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
11097
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
11509
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml23(model.status)}">
|
|
11098
11510
|
<header class="absolute-voice-provider-contracts__header">
|
|
11099
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
11100
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
11511
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml23(model.title)}</span>
|
|
11512
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml23(model.label)}</strong>
|
|
11101
11513
|
</header>
|
|
11102
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
11514
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml23(model.description)}</p>
|
|
11103
11515
|
${rows}
|
|
11104
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
11516
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml23(model.error)}</p>` : ""}
|
|
11105
11517
|
</section>`;
|
|
11106
11518
|
};
|
|
11107
11519
|
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}`;
|
|
@@ -11142,9 +11554,9 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
|
|
|
11142
11554
|
});
|
|
11143
11555
|
};
|
|
11144
11556
|
// src/client/turnQualityWidget.ts
|
|
11145
|
-
var
|
|
11146
|
-
var
|
|
11147
|
-
var
|
|
11557
|
+
var DEFAULT_TITLE16 = "Turn Quality";
|
|
11558
|
+
var DEFAULT_DESCRIPTION16 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
11559
|
+
var escapeHtml24 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11148
11560
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
11149
11561
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
11150
11562
|
var getTurnDetail = (turn) => {
|
|
@@ -11188,37 +11600,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
11188
11600
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
11189
11601
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
11190
11602
|
return {
|
|
11191
|
-
description: options.description ??
|
|
11603
|
+
description: options.description ?? DEFAULT_DESCRIPTION16,
|
|
11192
11604
|
error: snapshot.error,
|
|
11193
11605
|
isLoading: snapshot.isLoading,
|
|
11194
11606
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
11195
11607
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
11196
|
-
title: options.title ??
|
|
11608
|
+
title: options.title ?? DEFAULT_TITLE16,
|
|
11197
11609
|
turns,
|
|
11198
11610
|
updatedAt: snapshot.updatedAt
|
|
11199
11611
|
};
|
|
11200
11612
|
};
|
|
11201
11613
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
11202
11614
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
11203
|
-
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--${
|
|
11615
|
+
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--${escapeHtml24(turn.status)}">
|
|
11204
11616
|
<header>
|
|
11205
|
-
<strong>${
|
|
11206
|
-
<span>${
|
|
11617
|
+
<strong>${escapeHtml24(turn.label)}</strong>
|
|
11618
|
+
<span>${escapeHtml24(turn.status)}</span>
|
|
11207
11619
|
</header>
|
|
11208
|
-
<p>${
|
|
11620
|
+
<p>${escapeHtml24(turn.detail)}</p>
|
|
11209
11621
|
<dl>${turn.rows.map((row) => `<div>
|
|
11210
|
-
<dt>${
|
|
11211
|
-
<dd>${
|
|
11622
|
+
<dt>${escapeHtml24(row.label)}</dt>
|
|
11623
|
+
<dd>${escapeHtml24(row.value)}</dd>
|
|
11212
11624
|
</div>`).join("")}</dl>
|
|
11213
11625
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
11214
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
11626
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml24(model.status)}">
|
|
11215
11627
|
<header class="absolute-voice-turn-quality__header">
|
|
11216
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
11217
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
11628
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml24(model.title)}</span>
|
|
11629
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml24(model.label)}</strong>
|
|
11218
11630
|
</header>
|
|
11219
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
11631
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml24(model.description)}</p>
|
|
11220
11632
|
${turns}
|
|
11221
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
11633
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml24(model.error)}</p>` : ""}
|
|
11222
11634
|
</section>`;
|
|
11223
11635
|
};
|
|
11224
11636
|
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}`;
|
|
@@ -11259,56 +11671,56 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
11259
11671
|
});
|
|
11260
11672
|
};
|
|
11261
11673
|
// src/client/turnLatencyWidget.ts
|
|
11262
|
-
var
|
|
11263
|
-
var
|
|
11674
|
+
var DEFAULT_TITLE17 = "Turn Latency";
|
|
11675
|
+
var DEFAULT_DESCRIPTION17 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
11264
11676
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
11265
|
-
var
|
|
11266
|
-
var
|
|
11677
|
+
var escapeHtml25 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11678
|
+
var formatMs4 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
11267
11679
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
11268
11680
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
11269
11681
|
...turn,
|
|
11270
11682
|
label: turn.text || "Empty turn",
|
|
11271
11683
|
rows: turn.stages.map((stage) => ({
|
|
11272
11684
|
label: stage.label,
|
|
11273
|
-
value:
|
|
11685
|
+
value: formatMs4(stage.valueMs)
|
|
11274
11686
|
}))
|
|
11275
11687
|
}));
|
|
11276
11688
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
11277
11689
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
11278
11690
|
return {
|
|
11279
|
-
description: options.description ??
|
|
11691
|
+
description: options.description ?? DEFAULT_DESCRIPTION17,
|
|
11280
11692
|
error: snapshot.error,
|
|
11281
11693
|
isLoading: snapshot.isLoading,
|
|
11282
|
-
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${
|
|
11694
|
+
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs4(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
11283
11695
|
proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
|
|
11284
11696
|
showProofAction: Boolean(options.proofPath),
|
|
11285
11697
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
11286
|
-
title: options.title ??
|
|
11698
|
+
title: options.title ?? DEFAULT_TITLE17,
|
|
11287
11699
|
turns,
|
|
11288
11700
|
updatedAt: snapshot.updatedAt
|
|
11289
11701
|
};
|
|
11290
11702
|
};
|
|
11291
11703
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
11292
11704
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
11293
|
-
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--${
|
|
11705
|
+
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--${escapeHtml25(turn.status)}">
|
|
11294
11706
|
<header>
|
|
11295
|
-
<strong>${
|
|
11296
|
-
<span>${
|
|
11707
|
+
<strong>${escapeHtml25(turn.label)}</strong>
|
|
11708
|
+
<span>${escapeHtml25(turn.status)}</span>
|
|
11297
11709
|
</header>
|
|
11298
11710
|
<dl>${turn.rows.map((row) => `<div>
|
|
11299
|
-
<dt>${
|
|
11300
|
-
<dd>${
|
|
11711
|
+
<dt>${escapeHtml25(row.label)}</dt>
|
|
11712
|
+
<dd>${escapeHtml25(row.value)}</dd>
|
|
11301
11713
|
</div>`).join("")}</dl>
|
|
11302
11714
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
11303
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
11715
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml25(model.status)}">
|
|
11304
11716
|
<header class="absolute-voice-turn-latency__header">
|
|
11305
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
11306
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
11717
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml25(model.title)}</span>
|
|
11718
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml25(model.label)}</strong>
|
|
11307
11719
|
</header>
|
|
11308
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
11309
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
11720
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml25(model.description)}</p>
|
|
11721
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml25(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
11310
11722
|
${turns}
|
|
11311
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
11723
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml25(model.error)}</p>` : ""}
|
|
11312
11724
|
</section>`;
|
|
11313
11725
|
};
|
|
11314
11726
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -11358,16 +11770,16 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
11358
11770
|
});
|
|
11359
11771
|
};
|
|
11360
11772
|
// src/client/traceTimelineWidget.ts
|
|
11361
|
-
var
|
|
11362
|
-
var
|
|
11363
|
-
var
|
|
11364
|
-
var
|
|
11773
|
+
var DEFAULT_TITLE18 = "Voice Traces";
|
|
11774
|
+
var DEFAULT_DESCRIPTION18 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
11775
|
+
var escapeHtml26 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11776
|
+
var formatMs5 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
11365
11777
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
11366
11778
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
11367
11779
|
const sessions = (snapshot.report?.sessions ?? []).slice(0, options.limit ?? 3).map((session) => ({
|
|
11368
11780
|
...session,
|
|
11369
11781
|
detailHref: `${options.detailBasePath ?? "/traces"}/${encodeURIComponent(session.sessionId)}`,
|
|
11370
|
-
durationLabel:
|
|
11782
|
+
durationLabel: formatMs5(session.summary.callDurationMs),
|
|
11371
11783
|
incidentBundleHref: options.incidentBundleBasePath === false ? undefined : `${options.incidentBundleBasePath ?? "/voice-incidents"}/${encodeURIComponent(session.sessionId)}/markdown`,
|
|
11372
11784
|
label: `${session.summary.eventCount} events / ${session.summary.turnCount} turns`,
|
|
11373
11785
|
operationsRecordHref: options.operationsRecordBasePath === false ? undefined : `${options.operationsRecordBasePath ?? "/voice-operations"}/${encodeURIComponent(session.sessionId)}`,
|
|
@@ -11376,13 +11788,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
|
11376
11788
|
const failed = sessions.filter((session) => session.status === "failed").length;
|
|
11377
11789
|
const warnings = sessions.filter((session) => session.status === "warning").length;
|
|
11378
11790
|
return {
|
|
11379
|
-
description: options.description ??
|
|
11791
|
+
description: options.description ?? DEFAULT_DESCRIPTION18,
|
|
11380
11792
|
error: snapshot.error,
|
|
11381
11793
|
isLoading: snapshot.isLoading,
|
|
11382
11794
|
label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
|
|
11383
11795
|
sessions,
|
|
11384
11796
|
status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
11385
|
-
title: options.title ??
|
|
11797
|
+
title: options.title ?? DEFAULT_TITLE18,
|
|
11386
11798
|
updatedAt: snapshot.updatedAt
|
|
11387
11799
|
};
|
|
11388
11800
|
};
|
|
@@ -11390,27 +11802,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
11390
11802
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
11391
11803
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
11392
11804
|
const supportLinks = [
|
|
11393
|
-
`<a href="${
|
|
11394
|
-
session.operationsRecordHref ? `<a href="${
|
|
11395
|
-
session.incidentBundleHref ? `<a href="${
|
|
11805
|
+
`<a href="${escapeHtml26(session.detailHref)}">Open timeline</a>`,
|
|
11806
|
+
session.operationsRecordHref ? `<a href="${escapeHtml26(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
11807
|
+
session.incidentBundleHref ? `<a href="${escapeHtml26(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
11396
11808
|
].filter(Boolean).join("");
|
|
11397
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
11809
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml26(session.status)}">
|
|
11398
11810
|
<header>
|
|
11399
|
-
<strong>${
|
|
11400
|
-
<span>${
|
|
11811
|
+
<strong>${escapeHtml26(session.sessionId)}</strong>
|
|
11812
|
+
<span>${escapeHtml26(session.status)}</span>
|
|
11401
11813
|
</header>
|
|
11402
|
-
<p>${
|
|
11814
|
+
<p>${escapeHtml26(session.label)} \xB7 ${escapeHtml26(session.durationLabel)} \xB7 ${escapeHtml26(session.providerLabel)}</p>
|
|
11403
11815
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
11404
11816
|
</article>`;
|
|
11405
11817
|
}).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
11406
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
11818
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml26(model.status)}">
|
|
11407
11819
|
<header class="absolute-voice-trace-timeline__header">
|
|
11408
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
11409
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
11820
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml26(model.title)}</span>
|
|
11821
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml26(model.label)}</strong>
|
|
11410
11822
|
</header>
|
|
11411
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
11823
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml26(model.description)}</p>
|
|
11412
11824
|
${sessions}
|
|
11413
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
11825
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml26(model.error)}</p>` : ""}
|
|
11414
11826
|
</section>`;
|
|
11415
11827
|
};
|
|
11416
11828
|
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}`;
|
|
@@ -11456,9 +11868,9 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
|
|
|
11456
11868
|
});
|
|
11457
11869
|
};
|
|
11458
11870
|
// src/client/agentSquadStatusWidget.ts
|
|
11459
|
-
var
|
|
11460
|
-
var
|
|
11461
|
-
var
|
|
11871
|
+
var DEFAULT_TITLE19 = "Voice Agent Squad";
|
|
11872
|
+
var DEFAULT_DESCRIPTION19 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
11873
|
+
var escapeHtml27 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
11462
11874
|
var labelFor = (current) => {
|
|
11463
11875
|
if (!current)
|
|
11464
11876
|
return "Waiting for specialist activity";
|
|
@@ -11472,37 +11884,37 @@ var labelFor = (current) => {
|
|
|
11472
11884
|
};
|
|
11473
11885
|
var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
|
|
11474
11886
|
current: snapshot.report.current,
|
|
11475
|
-
description: options.description ??
|
|
11887
|
+
description: options.description ?? DEFAULT_DESCRIPTION19,
|
|
11476
11888
|
error: snapshot.error,
|
|
11477
11889
|
isLoading: snapshot.isLoading,
|
|
11478
11890
|
label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
|
|
11479
11891
|
sessionCount: snapshot.report.sessionCount,
|
|
11480
11892
|
sessions: snapshot.report.sessions,
|
|
11481
|
-
title: options.title ??
|
|
11893
|
+
title: options.title ?? DEFAULT_TITLE19,
|
|
11482
11894
|
updatedAt: snapshot.updatedAt
|
|
11483
11895
|
});
|
|
11484
11896
|
var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
11485
11897
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
11486
11898
|
const current = model.current;
|
|
11487
11899
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
11488
|
-
<span>${
|
|
11489
|
-
<strong>${
|
|
11490
|
-
<em>${
|
|
11491
|
-
${session.summary || session.reason ? `<p>${
|
|
11900
|
+
<span>${escapeHtml27(session.sessionId)}</span>
|
|
11901
|
+
<strong>${escapeHtml27(session.targetAgentId ?? "none")}</strong>
|
|
11902
|
+
<em>${escapeHtml27(session.status)}</em>
|
|
11903
|
+
${session.summary || session.reason ? `<p>${escapeHtml27(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
11492
11904
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
11493
11905
|
return `<section class="absolute-voice-agent-squad-status">
|
|
11494
11906
|
<header>
|
|
11495
|
-
<span>${
|
|
11496
|
-
<strong>${
|
|
11907
|
+
<span>${escapeHtml27(model.title)}</span>
|
|
11908
|
+
<strong>${escapeHtml27(model.label)}</strong>
|
|
11497
11909
|
</header>
|
|
11498
|
-
<p>${
|
|
11910
|
+
<p>${escapeHtml27(model.description)}</p>
|
|
11499
11911
|
<div>
|
|
11500
|
-
<span>Session</span><strong>${
|
|
11501
|
-
<span>From</span><strong>${
|
|
11502
|
-
<span>Status</span><strong>${
|
|
11912
|
+
<span>Session</span><strong>${escapeHtml27(current?.sessionId ?? "n/a")}</strong>
|
|
11913
|
+
<span>From</span><strong>${escapeHtml27(current?.fromAgentId ?? "n/a")}</strong>
|
|
11914
|
+
<span>Status</span><strong>${escapeHtml27(current?.status ?? "idle")}</strong>
|
|
11503
11915
|
</div>
|
|
11504
11916
|
<ul>${rows}</ul>
|
|
11505
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
11917
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml27(model.error)}</p>` : ""}
|
|
11506
11918
|
</section>`;
|
|
11507
11919
|
};
|
|
11508
11920
|
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}`;
|
|
@@ -11633,6 +12045,7 @@ export {
|
|
|
11633
12045
|
renderVoiceTraceTimelineWidgetHTML,
|
|
11634
12046
|
renderVoiceSessionSnapshotHTML,
|
|
11635
12047
|
renderVoiceRoutingStatusHTML,
|
|
12048
|
+
renderVoiceReconnectProfileEvidenceHTML,
|
|
11636
12049
|
renderVoiceReadinessFailuresHTML,
|
|
11637
12050
|
renderVoiceProviderStatusHTML,
|
|
11638
12051
|
renderVoiceProviderSimulationControlsHTML,
|
|
@@ -11656,6 +12069,7 @@ export {
|
|
|
11656
12069
|
mountVoiceTraceTimeline,
|
|
11657
12070
|
mountVoiceSessionSnapshot,
|
|
11658
12071
|
mountVoiceRoutingStatus,
|
|
12072
|
+
mountVoiceReconnectProfileEvidence,
|
|
11659
12073
|
mountVoiceReadinessFailures,
|
|
11660
12074
|
mountVoiceProviderStatus,
|
|
11661
12075
|
mountVoiceProviderSimulationControls,
|
|
@@ -11675,6 +12089,7 @@ export {
|
|
|
11675
12089
|
getVoiceTurnQualityCSS,
|
|
11676
12090
|
getVoiceTraceTimelineCSS,
|
|
11677
12091
|
getVoiceRoutingStatusCSS,
|
|
12092
|
+
getVoiceReconnectProfileEvidenceCSS,
|
|
11678
12093
|
getVoiceReadinessFailuresCSS,
|
|
11679
12094
|
getVoiceProviderStatusCSS,
|
|
11680
12095
|
getVoiceProviderContractsCSS,
|
|
@@ -11696,6 +12111,7 @@ export {
|
|
|
11696
12111
|
fetchVoiceTraceTimeline,
|
|
11697
12112
|
fetchVoiceSessionSnapshot,
|
|
11698
12113
|
fetchVoiceRoutingStatus,
|
|
12114
|
+
fetchVoiceReconnectProfileEvidence,
|
|
11699
12115
|
fetchVoiceReadinessFailures,
|
|
11700
12116
|
fetchVoiceProviderStatus,
|
|
11701
12117
|
fetchVoiceProviderContracts,
|
|
@@ -11714,6 +12130,7 @@ export {
|
|
|
11714
12130
|
defineVoiceTraceTimelineElement,
|
|
11715
12131
|
defineVoiceSessionSnapshotElement,
|
|
11716
12132
|
defineVoiceRoutingStatusElement,
|
|
12133
|
+
defineVoiceReconnectProfileEvidenceElement,
|
|
11717
12134
|
defineVoiceReadinessFailuresElement,
|
|
11718
12135
|
defineVoiceProviderStatusElement,
|
|
11719
12136
|
defineVoiceProviderSimulationControlsElement,
|
|
@@ -11742,6 +12159,8 @@ export {
|
|
|
11742
12159
|
createVoiceSessionSnapshotStore,
|
|
11743
12160
|
createVoiceRoutingStatusViewModel,
|
|
11744
12161
|
createVoiceRoutingStatusStore,
|
|
12162
|
+
createVoiceReconnectProfileEvidenceViewModel,
|
|
12163
|
+
createVoiceReconnectProfileEvidenceStore,
|
|
11745
12164
|
createVoiceReadinessFailuresViewModel,
|
|
11746
12165
|
createVoiceReadinessFailuresStore,
|
|
11747
12166
|
createVoiceProviderStatusViewModel,
|