@absolutejs/voice 0.0.22-beta.239 → 0.0.22-beta.240
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/client/index.d.ts +1 -0
- package/dist/client/index.js +295 -189
- package/dist/client/platformCoverageWidget.d.ts +37 -0
- package/dist/react/VoicePlatformCoverage.d.ts +6 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +615 -429
- package/dist/vue/VoicePlatformCoverage.d.ts +23 -0
- package/dist/vue/index.d.ts +1 -0
- package/dist/vue/index.js +556 -386
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -1110,6 +1110,289 @@ var VoiceDeliveryRuntime = ({
|
|
|
1110
1110
|
]
|
|
1111
1111
|
}, undefined, true, undefined, this);
|
|
1112
1112
|
};
|
|
1113
|
+
// src/react/useVoicePlatformCoverage.tsx
|
|
1114
|
+
import { useEffect as useEffect4, useRef as useRef4, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
1115
|
+
|
|
1116
|
+
// src/client/platformCoverage.ts
|
|
1117
|
+
var fetchVoicePlatformCoverage = async (path = "/api/voice/platform-coverage", options = {}) => {
|
|
1118
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1119
|
+
const response = await fetchImpl(path);
|
|
1120
|
+
if (!response.ok) {
|
|
1121
|
+
throw new Error(`Voice platform coverage failed: HTTP ${response.status}`);
|
|
1122
|
+
}
|
|
1123
|
+
return await response.json();
|
|
1124
|
+
};
|
|
1125
|
+
var createVoicePlatformCoverageStore = (path = "/api/voice/platform-coverage", options = {}) => {
|
|
1126
|
+
const listeners = new Set;
|
|
1127
|
+
let closed = false;
|
|
1128
|
+
let timer;
|
|
1129
|
+
let snapshot = {
|
|
1130
|
+
error: null,
|
|
1131
|
+
isLoading: false
|
|
1132
|
+
};
|
|
1133
|
+
const emit = () => {
|
|
1134
|
+
for (const listener of listeners) {
|
|
1135
|
+
listener();
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
const refresh = async () => {
|
|
1139
|
+
if (closed) {
|
|
1140
|
+
return snapshot.report;
|
|
1141
|
+
}
|
|
1142
|
+
snapshot = {
|
|
1143
|
+
...snapshot,
|
|
1144
|
+
error: null,
|
|
1145
|
+
isLoading: true
|
|
1146
|
+
};
|
|
1147
|
+
emit();
|
|
1148
|
+
try {
|
|
1149
|
+
const report = await fetchVoicePlatformCoverage(path, options);
|
|
1150
|
+
snapshot = {
|
|
1151
|
+
error: null,
|
|
1152
|
+
isLoading: false,
|
|
1153
|
+
report,
|
|
1154
|
+
updatedAt: Date.now()
|
|
1155
|
+
};
|
|
1156
|
+
emit();
|
|
1157
|
+
return report;
|
|
1158
|
+
} catch (error) {
|
|
1159
|
+
snapshot = {
|
|
1160
|
+
...snapshot,
|
|
1161
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1162
|
+
isLoading: false
|
|
1163
|
+
};
|
|
1164
|
+
emit();
|
|
1165
|
+
throw error;
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
|
+
const close = () => {
|
|
1169
|
+
closed = true;
|
|
1170
|
+
if (timer) {
|
|
1171
|
+
clearInterval(timer);
|
|
1172
|
+
timer = undefined;
|
|
1173
|
+
}
|
|
1174
|
+
listeners.clear();
|
|
1175
|
+
};
|
|
1176
|
+
if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
|
|
1177
|
+
timer = setInterval(() => {
|
|
1178
|
+
refresh().catch(() => {});
|
|
1179
|
+
}, options.intervalMs);
|
|
1180
|
+
}
|
|
1181
|
+
return {
|
|
1182
|
+
close,
|
|
1183
|
+
getServerSnapshot: () => snapshot,
|
|
1184
|
+
getSnapshot: () => snapshot,
|
|
1185
|
+
refresh,
|
|
1186
|
+
subscribe: (listener) => {
|
|
1187
|
+
listeners.add(listener);
|
|
1188
|
+
return () => {
|
|
1189
|
+
listeners.delete(listener);
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
};
|
|
1194
|
+
|
|
1195
|
+
// src/react/useVoicePlatformCoverage.tsx
|
|
1196
|
+
var useVoicePlatformCoverage = (path = "/api/voice/platform-coverage", options = {}) => {
|
|
1197
|
+
const storeRef = useRef4(null);
|
|
1198
|
+
if (!storeRef.current) {
|
|
1199
|
+
storeRef.current = createVoicePlatformCoverageStore(path, options);
|
|
1200
|
+
}
|
|
1201
|
+
const store = storeRef.current;
|
|
1202
|
+
useEffect4(() => {
|
|
1203
|
+
store.refresh().catch(() => {});
|
|
1204
|
+
return () => store.close();
|
|
1205
|
+
}, [store]);
|
|
1206
|
+
return {
|
|
1207
|
+
...useSyncExternalStore4(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1208
|
+
refresh: store.refresh
|
|
1209
|
+
};
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
// src/client/platformCoverageWidget.ts
|
|
1213
|
+
var DEFAULT_TITLE4 = "Platform Replacement Coverage";
|
|
1214
|
+
var DEFAULT_DESCRIPTION4 = "Code-owned coverage for hosted voice-platform surfaces, backed by the same proof routes used by release evidence.";
|
|
1215
|
+
var DEFAULT_LINKS = [
|
|
1216
|
+
{ href: "/switching-from-vapi", label: "Switching guide" },
|
|
1217
|
+
{ href: "/api/voice/vapi-coverage", label: "Coverage JSON" }
|
|
1218
|
+
];
|
|
1219
|
+
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1220
|
+
var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1221
|
+
var surfaceDetail2 = (surface) => {
|
|
1222
|
+
if (surface.status === "pass") {
|
|
1223
|
+
return surface.replacement;
|
|
1224
|
+
}
|
|
1225
|
+
if (surface.gap) {
|
|
1226
|
+
return surface.gap;
|
|
1227
|
+
}
|
|
1228
|
+
if (surface.missingEvidence?.length) {
|
|
1229
|
+
return `Missing evidence: ${surface.missingEvidence.join(", ")}`;
|
|
1230
|
+
}
|
|
1231
|
+
return surface.replacement;
|
|
1232
|
+
};
|
|
1233
|
+
var createVoicePlatformCoverageViewModel = (snapshot, options = {}) => {
|
|
1234
|
+
const allSurfaces = snapshot.report?.coverage ?? [];
|
|
1235
|
+
const failing = allSurfaces.filter((surface) => surface.status !== "pass");
|
|
1236
|
+
const limit = options.limit ?? 6;
|
|
1237
|
+
const surfaces = allSurfaces.slice(0, limit).map((surface) => ({
|
|
1238
|
+
...surface,
|
|
1239
|
+
detail: surfaceDetail2(surface),
|
|
1240
|
+
label: surface.surface
|
|
1241
|
+
}));
|
|
1242
|
+
return {
|
|
1243
|
+
description: options.description ?? DEFAULT_DESCRIPTION4,
|
|
1244
|
+
error: snapshot.error,
|
|
1245
|
+
isLoading: snapshot.isLoading,
|
|
1246
|
+
label: snapshot.error ? "Unavailable" : snapshot.report ? failing.length ? `${failing.length} gaps` : `${snapshot.report.total} surfaces passing` : snapshot.isLoading ? "Checking" : "No coverage report",
|
|
1247
|
+
links: options.links ?? DEFAULT_LINKS,
|
|
1248
|
+
status: snapshot.error ? "error" : snapshot.report ? failing.length ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1249
|
+
surfaces,
|
|
1250
|
+
title: options.title ?? DEFAULT_TITLE4,
|
|
1251
|
+
updatedAt: snapshot.updatedAt
|
|
1252
|
+
};
|
|
1253
|
+
};
|
|
1254
|
+
var renderVoicePlatformCoverageHTML = (snapshot, options = {}) => {
|
|
1255
|
+
const model = createVoicePlatformCoverageViewModel(snapshot, options);
|
|
1256
|
+
const surfaces = model.surfaces.length ? `<div class="absolute-voice-platform-coverage__surfaces">${model.surfaces.map((surface) => `<article class="absolute-voice-platform-coverage__surface absolute-voice-platform-coverage__surface--${escapeHtml4(surface.status)}">
|
|
1257
|
+
<header>
|
|
1258
|
+
<strong>${escapeHtml4(surface.label)}</strong>
|
|
1259
|
+
<span>${escapeHtml4(formatStatus(surface.status))}</span>
|
|
1260
|
+
</header>
|
|
1261
|
+
<p>${escapeHtml4(surface.detail)}</p>
|
|
1262
|
+
<small>${surface.evidence.filter((item) => item.ok).length}/${surface.evidence.length} evidence checks passing</small>
|
|
1263
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-platform-coverage__empty">${model.error ? escapeHtml4(model.error) : "Run the proof pack to populate platform coverage evidence."}</p>`;
|
|
1264
|
+
const links = model.links.length ? `<p class="absolute-voice-platform-coverage__links">${model.links.map((link) => `<a href="${escapeHtml4(link.href)}">${escapeHtml4(link.label)}</a>`).join("")}</p>` : "";
|
|
1265
|
+
return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${escapeHtml4(model.status)}">
|
|
1266
|
+
<header class="absolute-voice-platform-coverage__header">
|
|
1267
|
+
<span class="absolute-voice-platform-coverage__eyebrow">${escapeHtml4(model.title)}</span>
|
|
1268
|
+
<strong class="absolute-voice-platform-coverage__label">${escapeHtml4(model.label)}</strong>
|
|
1269
|
+
</header>
|
|
1270
|
+
<p class="absolute-voice-platform-coverage__description">${escapeHtml4(model.description)}</p>
|
|
1271
|
+
${surfaces}
|
|
1272
|
+
${links}
|
|
1273
|
+
${model.error ? `<p class="absolute-voice-platform-coverage__error">${escapeHtml4(model.error)}</p>` : ""}
|
|
1274
|
+
</section>`;
|
|
1275
|
+
};
|
|
1276
|
+
var getVoicePlatformCoverageCSS = () => `.absolute-voice-platform-coverage{border:1px solid #c7d2fe;border-radius:20px;background:#f8fbff;color:#111827;padding:18px;box-shadow:0 18px 40px rgba(30,64,175,.12);font-family:inherit}.absolute-voice-platform-coverage--warning,.absolute-voice-platform-coverage--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-platform-coverage__header,.absolute-voice-platform-coverage__surface header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-platform-coverage__eyebrow{color:#1d4ed8;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-platform-coverage__label{font-size:24px;line-height:1}.absolute-voice-platform-coverage__description,.absolute-voice-platform-coverage__surface p,.absolute-voice-platform-coverage__surface small,.absolute-voice-platform-coverage__empty{color:#475569}.absolute-voice-platform-coverage__surfaces{display:grid;gap:10px;margin-top:14px}.absolute-voice-platform-coverage__surface{background:#fff;border:1px solid #dbeafe;border-radius:16px;padding:12px}.absolute-voice-platform-coverage__surface--pass{border-color:#86efac}.absolute-voice-platform-coverage__surface--fail,.absolute-voice-platform-coverage__surface--missing,.absolute-voice-platform-coverage__surface--stale{border-color:#f2a7a7}.absolute-voice-platform-coverage__surface p{margin:8px 0}.absolute-voice-platform-coverage__surface span{text-transform:capitalize}.absolute-voice-platform-coverage__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-platform-coverage__links a{border:1px solid #bfdbfe;border-radius:999px;color:#1d4ed8;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-platform-coverage__error{color:#9f1239;font-weight:700}`;
|
|
1277
|
+
var mountVoicePlatformCoverage = (element, path = "/api/voice/platform-coverage", options = {}) => {
|
|
1278
|
+
const store = createVoicePlatformCoverageStore(path, options);
|
|
1279
|
+
const render = () => {
|
|
1280
|
+
element.innerHTML = renderVoicePlatformCoverageHTML(store.getSnapshot(), options);
|
|
1281
|
+
};
|
|
1282
|
+
const unsubscribe = store.subscribe(render);
|
|
1283
|
+
render();
|
|
1284
|
+
store.refresh().catch(() => {});
|
|
1285
|
+
return {
|
|
1286
|
+
close: () => {
|
|
1287
|
+
unsubscribe();
|
|
1288
|
+
store.close();
|
|
1289
|
+
},
|
|
1290
|
+
refresh: store.refresh
|
|
1291
|
+
};
|
|
1292
|
+
};
|
|
1293
|
+
var defineVoicePlatformCoverageElement = (tagName = "absolute-voice-platform-coverage") => {
|
|
1294
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
customElements.define(tagName, class AbsoluteVoicePlatformCoverageElement extends HTMLElement {
|
|
1298
|
+
mounted;
|
|
1299
|
+
connectedCallback() {
|
|
1300
|
+
this.mounted = mountVoicePlatformCoverage(this, this.getAttribute("path") ?? "/api/voice/platform-coverage", {
|
|
1301
|
+
description: this.getAttribute("description") ?? undefined,
|
|
1302
|
+
intervalMs: Number(this.getAttribute("interval-ms") ?? 0) || undefined,
|
|
1303
|
+
limit: Number(this.getAttribute("limit") ?? 0) || undefined,
|
|
1304
|
+
title: this.getAttribute("title") ?? undefined
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
disconnectedCallback() {
|
|
1308
|
+
this.mounted?.close();
|
|
1309
|
+
this.mounted = undefined;
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
};
|
|
1313
|
+
|
|
1314
|
+
// src/react/VoicePlatformCoverage.tsx
|
|
1315
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
1316
|
+
var VoicePlatformCoverage = ({
|
|
1317
|
+
className,
|
|
1318
|
+
path = "/api/voice/platform-coverage",
|
|
1319
|
+
...options
|
|
1320
|
+
}) => {
|
|
1321
|
+
const snapshot = useVoicePlatformCoverage(path, options);
|
|
1322
|
+
const model = createVoicePlatformCoverageViewModel(snapshot, options);
|
|
1323
|
+
return /* @__PURE__ */ jsxDEV4("section", {
|
|
1324
|
+
className: [
|
|
1325
|
+
"absolute-voice-platform-coverage",
|
|
1326
|
+
`absolute-voice-platform-coverage--${model.status}`,
|
|
1327
|
+
className
|
|
1328
|
+
].filter(Boolean).join(" "),
|
|
1329
|
+
children: [
|
|
1330
|
+
/* @__PURE__ */ jsxDEV4("header", {
|
|
1331
|
+
className: "absolute-voice-platform-coverage__header",
|
|
1332
|
+
children: [
|
|
1333
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
1334
|
+
className: "absolute-voice-platform-coverage__eyebrow",
|
|
1335
|
+
children: model.title
|
|
1336
|
+
}, undefined, false, undefined, this),
|
|
1337
|
+
/* @__PURE__ */ jsxDEV4("strong", {
|
|
1338
|
+
className: "absolute-voice-platform-coverage__label",
|
|
1339
|
+
children: model.label
|
|
1340
|
+
}, undefined, false, undefined, this)
|
|
1341
|
+
]
|
|
1342
|
+
}, undefined, true, undefined, this),
|
|
1343
|
+
/* @__PURE__ */ jsxDEV4("p", {
|
|
1344
|
+
className: "absolute-voice-platform-coverage__description",
|
|
1345
|
+
children: model.description
|
|
1346
|
+
}, undefined, false, undefined, this),
|
|
1347
|
+
model.surfaces.length ? /* @__PURE__ */ jsxDEV4("div", {
|
|
1348
|
+
className: "absolute-voice-platform-coverage__surfaces",
|
|
1349
|
+
children: model.surfaces.map((surface) => /* @__PURE__ */ jsxDEV4("article", {
|
|
1350
|
+
className: [
|
|
1351
|
+
"absolute-voice-platform-coverage__surface",
|
|
1352
|
+
`absolute-voice-platform-coverage__surface--${surface.status}`
|
|
1353
|
+
].join(" "),
|
|
1354
|
+
children: [
|
|
1355
|
+
/* @__PURE__ */ jsxDEV4("header", {
|
|
1356
|
+
children: [
|
|
1357
|
+
/* @__PURE__ */ jsxDEV4("strong", {
|
|
1358
|
+
children: surface.label
|
|
1359
|
+
}, undefined, false, undefined, this),
|
|
1360
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
1361
|
+
children: surface.status
|
|
1362
|
+
}, undefined, false, undefined, this)
|
|
1363
|
+
]
|
|
1364
|
+
}, undefined, true, undefined, this),
|
|
1365
|
+
/* @__PURE__ */ jsxDEV4("p", {
|
|
1366
|
+
children: surface.detail
|
|
1367
|
+
}, undefined, false, undefined, this),
|
|
1368
|
+
/* @__PURE__ */ jsxDEV4("small", {
|
|
1369
|
+
children: [
|
|
1370
|
+
surface.evidence.filter((item) => item.ok).length,
|
|
1371
|
+
"/",
|
|
1372
|
+
surface.evidence.length,
|
|
1373
|
+
" evidence checks passing"
|
|
1374
|
+
]
|
|
1375
|
+
}, undefined, true, undefined, this)
|
|
1376
|
+
]
|
|
1377
|
+
}, surface.surface, true, undefined, this))
|
|
1378
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4("p", {
|
|
1379
|
+
className: "absolute-voice-platform-coverage__empty",
|
|
1380
|
+
children: model.error ?? "Run the proof pack to populate platform coverage evidence."
|
|
1381
|
+
}, undefined, false, undefined, this),
|
|
1382
|
+
model.links.length ? /* @__PURE__ */ jsxDEV4("p", {
|
|
1383
|
+
className: "absolute-voice-platform-coverage__links",
|
|
1384
|
+
children: model.links.map((link) => /* @__PURE__ */ jsxDEV4("a", {
|
|
1385
|
+
href: link.href,
|
|
1386
|
+
children: link.label
|
|
1387
|
+
}, link.href, false, undefined, this))
|
|
1388
|
+
}, undefined, false, undefined, this) : null,
|
|
1389
|
+
model.error ? /* @__PURE__ */ jsxDEV4("p", {
|
|
1390
|
+
className: "absolute-voice-platform-coverage__error",
|
|
1391
|
+
children: model.error
|
|
1392
|
+
}, undefined, false, undefined, this) : null
|
|
1393
|
+
]
|
|
1394
|
+
}, undefined, true, undefined, this);
|
|
1395
|
+
};
|
|
1113
1396
|
// src/client/providerSimulationControls.ts
|
|
1114
1397
|
var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
|
|
1115
1398
|
const response = await fetchImpl(`${pathPrefix}/${mode}?provider=${encodeURIComponent(provider)}`, { method: "POST" });
|
|
@@ -1190,7 +1473,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
1190
1473
|
};
|
|
1191
1474
|
|
|
1192
1475
|
// src/client/providerSimulationControlsWidget.ts
|
|
1193
|
-
var
|
|
1476
|
+
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1194
1477
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
1195
1478
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
1196
1479
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -1210,18 +1493,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
1210
1493
|
};
|
|
1211
1494
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
1212
1495
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
1213
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
1214
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
1496
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml5(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml5(provider.provider)} ${escapeHtml5(formatKind(options.kind))} failure</button>`).join("");
|
|
1497
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml5(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml5(provider.provider)} recovered</button>`).join("");
|
|
1215
1498
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
1216
1499
|
<header class="absolute-voice-provider-simulation__header">
|
|
1217
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
1218
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
1500
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml5(model.title)}</span>
|
|
1501
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml5(model.label)}</strong>
|
|
1219
1502
|
</header>
|
|
1220
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
1221
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
1503
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml5(model.description)}</p>
|
|
1504
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml5(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
1222
1505
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
1223
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
1224
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
1506
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml5(snapshot.error)}</p>` : ""}
|
|
1507
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml5(model.resultText)}</pre>` : ""}
|
|
1225
1508
|
</section>`;
|
|
1226
1509
|
};
|
|
1227
1510
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -1287,22 +1570,22 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
|
|
|
1287
1570
|
};
|
|
1288
1571
|
|
|
1289
1572
|
// src/react/useVoiceProviderSimulationControls.tsx
|
|
1290
|
-
import { useEffect as
|
|
1573
|
+
import { useEffect as useEffect5, useRef as useRef5, useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
1291
1574
|
var useVoiceProviderSimulationControls = (options) => {
|
|
1292
|
-
const storeRef =
|
|
1575
|
+
const storeRef = useRef5(null);
|
|
1293
1576
|
if (!storeRef.current) {
|
|
1294
1577
|
storeRef.current = createVoiceProviderSimulationControlsStore(options);
|
|
1295
1578
|
}
|
|
1296
1579
|
const store = storeRef.current;
|
|
1297
|
-
|
|
1580
|
+
useEffect5(() => () => store.close(), [store]);
|
|
1298
1581
|
return {
|
|
1299
|
-
...
|
|
1582
|
+
...useSyncExternalStore5(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1300
1583
|
run: store.run
|
|
1301
1584
|
};
|
|
1302
1585
|
};
|
|
1303
1586
|
|
|
1304
1587
|
// src/react/VoiceProviderSimulationControls.tsx
|
|
1305
|
-
import { jsxDEV as
|
|
1588
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
1306
1589
|
var VoiceProviderSimulationControls = ({
|
|
1307
1590
|
className,
|
|
1308
1591
|
...options
|
|
@@ -1312,38 +1595,38 @@ var VoiceProviderSimulationControls = ({
|
|
|
1312
1595
|
const run = (provider, mode) => {
|
|
1313
1596
|
snapshot.run(provider, mode).catch(() => {});
|
|
1314
1597
|
};
|
|
1315
|
-
return /* @__PURE__ */
|
|
1598
|
+
return /* @__PURE__ */ jsxDEV5("section", {
|
|
1316
1599
|
className: [
|
|
1317
1600
|
"absolute-voice-provider-simulation",
|
|
1318
1601
|
`absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}`,
|
|
1319
1602
|
className
|
|
1320
1603
|
].filter(Boolean).join(" "),
|
|
1321
1604
|
children: [
|
|
1322
|
-
/* @__PURE__ */
|
|
1605
|
+
/* @__PURE__ */ jsxDEV5("header", {
|
|
1323
1606
|
className: "absolute-voice-provider-simulation__header",
|
|
1324
1607
|
children: [
|
|
1325
|
-
/* @__PURE__ */
|
|
1608
|
+
/* @__PURE__ */ jsxDEV5("span", {
|
|
1326
1609
|
className: "absolute-voice-provider-simulation__eyebrow",
|
|
1327
1610
|
children: model.title
|
|
1328
1611
|
}, undefined, false, undefined, this),
|
|
1329
|
-
/* @__PURE__ */
|
|
1612
|
+
/* @__PURE__ */ jsxDEV5("strong", {
|
|
1330
1613
|
className: "absolute-voice-provider-simulation__label",
|
|
1331
1614
|
children: model.label
|
|
1332
1615
|
}, undefined, false, undefined, this)
|
|
1333
1616
|
]
|
|
1334
1617
|
}, undefined, true, undefined, this),
|
|
1335
|
-
/* @__PURE__ */
|
|
1618
|
+
/* @__PURE__ */ jsxDEV5("p", {
|
|
1336
1619
|
className: "absolute-voice-provider-simulation__description",
|
|
1337
1620
|
children: model.description
|
|
1338
1621
|
}, undefined, false, undefined, this),
|
|
1339
|
-
model.canSimulateFailure ? null : /* @__PURE__ */
|
|
1622
|
+
model.canSimulateFailure ? null : /* @__PURE__ */ jsxDEV5("p", {
|
|
1340
1623
|
className: "absolute-voice-provider-simulation__empty",
|
|
1341
1624
|
children: options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."
|
|
1342
1625
|
}, undefined, false, undefined, this),
|
|
1343
|
-
/* @__PURE__ */
|
|
1626
|
+
/* @__PURE__ */ jsxDEV5("div", {
|
|
1344
1627
|
className: "absolute-voice-provider-simulation__actions",
|
|
1345
1628
|
children: [
|
|
1346
|
-
model.failureProviders.map((provider) => /* @__PURE__ */
|
|
1629
|
+
model.failureProviders.map((provider) => /* @__PURE__ */ jsxDEV5("button", {
|
|
1347
1630
|
disabled: !model.canSimulateFailure || snapshot.isRunning,
|
|
1348
1631
|
onClick: () => run(provider.provider, "failure"),
|
|
1349
1632
|
type: "button",
|
|
@@ -1356,7 +1639,7 @@ var VoiceProviderSimulationControls = ({
|
|
|
1356
1639
|
"failure"
|
|
1357
1640
|
]
|
|
1358
1641
|
}, `fail-${provider.provider}`, true, undefined, this)),
|
|
1359
|
-
model.providers.map((provider) => /* @__PURE__ */
|
|
1642
|
+
model.providers.map((provider) => /* @__PURE__ */ jsxDEV5("button", {
|
|
1360
1643
|
disabled: snapshot.isRunning,
|
|
1361
1644
|
onClick: () => run(provider.provider, "recovery"),
|
|
1362
1645
|
type: "button",
|
|
@@ -1368,11 +1651,11 @@ var VoiceProviderSimulationControls = ({
|
|
|
1368
1651
|
}, `recover-${provider.provider}`, true, undefined, this))
|
|
1369
1652
|
]
|
|
1370
1653
|
}, undefined, true, undefined, this),
|
|
1371
|
-
snapshot.error ? /* @__PURE__ */
|
|
1654
|
+
snapshot.error ? /* @__PURE__ */ jsxDEV5("p", {
|
|
1372
1655
|
className: "absolute-voice-provider-simulation__error",
|
|
1373
1656
|
children: snapshot.error
|
|
1374
1657
|
}, undefined, false, undefined, this) : null,
|
|
1375
|
-
model.resultText ? /* @__PURE__ */
|
|
1658
|
+
model.resultText ? /* @__PURE__ */ jsxDEV5("pre", {
|
|
1376
1659
|
className: "absolute-voice-provider-simulation__result",
|
|
1377
1660
|
children: model.resultText
|
|
1378
1661
|
}, undefined, false, undefined, this) : null
|
|
@@ -1380,7 +1663,7 @@ var VoiceProviderSimulationControls = ({
|
|
|
1380
1663
|
}, undefined, true, undefined, this);
|
|
1381
1664
|
};
|
|
1382
1665
|
// src/react/useVoiceProviderCapabilities.tsx
|
|
1383
|
-
import { useEffect as
|
|
1666
|
+
import { useEffect as useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
|
|
1384
1667
|
|
|
1385
1668
|
// src/client/providerCapabilities.ts
|
|
1386
1669
|
var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
|
|
@@ -1463,28 +1746,28 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
|
|
|
1463
1746
|
|
|
1464
1747
|
// src/react/useVoiceProviderCapabilities.tsx
|
|
1465
1748
|
var useVoiceProviderCapabilities = (path = "/api/provider-capabilities", options = {}) => {
|
|
1466
|
-
const storeRef =
|
|
1749
|
+
const storeRef = useRef6(null);
|
|
1467
1750
|
if (!storeRef.current) {
|
|
1468
1751
|
storeRef.current = createVoiceProviderCapabilitiesStore(path, options);
|
|
1469
1752
|
}
|
|
1470
1753
|
const store = storeRef.current;
|
|
1471
|
-
|
|
1754
|
+
useEffect6(() => {
|
|
1472
1755
|
store.refresh().catch(() => {});
|
|
1473
1756
|
return () => store.close();
|
|
1474
1757
|
}, [store]);
|
|
1475
1758
|
return {
|
|
1476
|
-
...
|
|
1759
|
+
...useSyncExternalStore6(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1477
1760
|
refresh: store.refresh
|
|
1478
1761
|
};
|
|
1479
1762
|
};
|
|
1480
1763
|
|
|
1481
1764
|
// src/client/providerCapabilitiesWidget.ts
|
|
1482
|
-
var
|
|
1483
|
-
var
|
|
1484
|
-
var
|
|
1765
|
+
var DEFAULT_TITLE5 = "Provider Capabilities";
|
|
1766
|
+
var DEFAULT_DESCRIPTION5 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
1767
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1485
1768
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1486
1769
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
1487
|
-
var
|
|
1770
|
+
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1488
1771
|
var getCapabilityDetail = (capability) => {
|
|
1489
1772
|
if (!capability.configured) {
|
|
1490
1773
|
return "Not configured in this deployment.";
|
|
@@ -1510,7 +1793,7 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
1510
1793
|
detail: getCapabilityDetail(capability),
|
|
1511
1794
|
label: `${formatProvider(capability.provider)} ${formatKind2(capability.kind)}`,
|
|
1512
1795
|
rows: [
|
|
1513
|
-
{ label: "Status", value:
|
|
1796
|
+
{ label: "Status", value: formatStatus2(capability.status) },
|
|
1514
1797
|
{ label: "Selected", value: capability.selected ? "Yes" : "No" },
|
|
1515
1798
|
{ label: "Model", value: capability.model ?? "Default" },
|
|
1516
1799
|
{
|
|
@@ -1525,36 +1808,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
1525
1808
|
const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
|
|
1526
1809
|
return {
|
|
1527
1810
|
capabilities,
|
|
1528
|
-
description: options.description ??
|
|
1811
|
+
description: options.description ?? DEFAULT_DESCRIPTION5,
|
|
1529
1812
|
error: snapshot.error,
|
|
1530
1813
|
isLoading: snapshot.isLoading,
|
|
1531
1814
|
label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
|
|
1532
1815
|
status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1533
|
-
title: options.title ??
|
|
1816
|
+
title: options.title ?? DEFAULT_TITLE5,
|
|
1534
1817
|
updatedAt: snapshot.updatedAt
|
|
1535
1818
|
};
|
|
1536
1819
|
};
|
|
1537
1820
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
1538
1821
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
1539
|
-
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--${
|
|
1822
|
+
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--${escapeHtml6(capability.status)}">
|
|
1540
1823
|
<header>
|
|
1541
|
-
<strong>${
|
|
1542
|
-
<span>${
|
|
1824
|
+
<strong>${escapeHtml6(capability.label)}</strong>
|
|
1825
|
+
<span>${escapeHtml6(formatStatus2(capability.status))}</span>
|
|
1543
1826
|
</header>
|
|
1544
|
-
<p>${
|
|
1827
|
+
<p>${escapeHtml6(capability.detail)}</p>
|
|
1545
1828
|
<dl>${capability.rows.map((row) => `<div>
|
|
1546
|
-
<dt>${
|
|
1547
|
-
<dd>${
|
|
1829
|
+
<dt>${escapeHtml6(row.label)}</dt>
|
|
1830
|
+
<dd>${escapeHtml6(row.value)}</dd>
|
|
1548
1831
|
</div>`).join("")}</dl>
|
|
1549
1832
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
1550
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
1833
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml6(model.status)}">
|
|
1551
1834
|
<header class="absolute-voice-provider-capabilities__header">
|
|
1552
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
1553
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
1835
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml6(model.title)}</span>
|
|
1836
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml6(model.label)}</strong>
|
|
1554
1837
|
</header>
|
|
1555
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
1838
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml6(model.description)}</p>
|
|
1556
1839
|
${capabilities}
|
|
1557
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
1840
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
1558
1841
|
</section>`;
|
|
1559
1842
|
};
|
|
1560
1843
|
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}`;
|
|
@@ -1596,7 +1879,7 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
|
|
|
1596
1879
|
};
|
|
1597
1880
|
|
|
1598
1881
|
// src/react/VoiceProviderCapabilities.tsx
|
|
1599
|
-
import { jsxDEV as
|
|
1882
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
1600
1883
|
var VoiceProviderCapabilities = ({
|
|
1601
1884
|
className,
|
|
1602
1885
|
path = "/api/provider-capabilities",
|
|
@@ -1604,58 +1887,58 @@ var VoiceProviderCapabilities = ({
|
|
|
1604
1887
|
}) => {
|
|
1605
1888
|
const snapshot = useVoiceProviderCapabilities(path, options);
|
|
1606
1889
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
1607
|
-
return /* @__PURE__ */
|
|
1890
|
+
return /* @__PURE__ */ jsxDEV6("section", {
|
|
1608
1891
|
className: [
|
|
1609
1892
|
"absolute-voice-provider-capabilities",
|
|
1610
1893
|
`absolute-voice-provider-capabilities--${model.status}`,
|
|
1611
1894
|
className
|
|
1612
1895
|
].filter(Boolean).join(" "),
|
|
1613
1896
|
children: [
|
|
1614
|
-
/* @__PURE__ */
|
|
1897
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1615
1898
|
className: "absolute-voice-provider-capabilities__header",
|
|
1616
1899
|
children: [
|
|
1617
|
-
/* @__PURE__ */
|
|
1900
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1618
1901
|
className: "absolute-voice-provider-capabilities__eyebrow",
|
|
1619
1902
|
children: model.title
|
|
1620
1903
|
}, undefined, false, undefined, this),
|
|
1621
|
-
/* @__PURE__ */
|
|
1904
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1622
1905
|
className: "absolute-voice-provider-capabilities__label",
|
|
1623
1906
|
children: model.label
|
|
1624
1907
|
}, undefined, false, undefined, this)
|
|
1625
1908
|
]
|
|
1626
1909
|
}, undefined, true, undefined, this),
|
|
1627
|
-
/* @__PURE__ */
|
|
1910
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1628
1911
|
className: "absolute-voice-provider-capabilities__description",
|
|
1629
1912
|
children: model.description
|
|
1630
1913
|
}, undefined, false, undefined, this),
|
|
1631
|
-
model.capabilities.length ? /* @__PURE__ */
|
|
1914
|
+
model.capabilities.length ? /* @__PURE__ */ jsxDEV6("div", {
|
|
1632
1915
|
className: "absolute-voice-provider-capabilities__providers",
|
|
1633
|
-
children: model.capabilities.map((capability) => /* @__PURE__ */
|
|
1916
|
+
children: model.capabilities.map((capability) => /* @__PURE__ */ jsxDEV6("article", {
|
|
1634
1917
|
className: [
|
|
1635
1918
|
"absolute-voice-provider-capabilities__provider",
|
|
1636
1919
|
`absolute-voice-provider-capabilities__provider--${capability.status}`
|
|
1637
1920
|
].join(" "),
|
|
1638
1921
|
children: [
|
|
1639
|
-
/* @__PURE__ */
|
|
1922
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1640
1923
|
children: [
|
|
1641
|
-
/* @__PURE__ */
|
|
1924
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1642
1925
|
children: capability.label
|
|
1643
1926
|
}, undefined, false, undefined, this),
|
|
1644
|
-
/* @__PURE__ */
|
|
1927
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1645
1928
|
children: capability.status
|
|
1646
1929
|
}, undefined, false, undefined, this)
|
|
1647
1930
|
]
|
|
1648
1931
|
}, undefined, true, undefined, this),
|
|
1649
|
-
/* @__PURE__ */
|
|
1932
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1650
1933
|
children: capability.detail
|
|
1651
1934
|
}, undefined, false, undefined, this),
|
|
1652
|
-
/* @__PURE__ */
|
|
1653
|
-
children: capability.rows.map((row) => /* @__PURE__ */
|
|
1935
|
+
/* @__PURE__ */ jsxDEV6("dl", {
|
|
1936
|
+
children: capability.rows.map((row) => /* @__PURE__ */ jsxDEV6("div", {
|
|
1654
1937
|
children: [
|
|
1655
|
-
/* @__PURE__ */
|
|
1938
|
+
/* @__PURE__ */ jsxDEV6("dt", {
|
|
1656
1939
|
children: row.label
|
|
1657
1940
|
}, undefined, false, undefined, this),
|
|
1658
|
-
/* @__PURE__ */
|
|
1941
|
+
/* @__PURE__ */ jsxDEV6("dd", {
|
|
1659
1942
|
children: row.value
|
|
1660
1943
|
}, undefined, false, undefined, this)
|
|
1661
1944
|
]
|
|
@@ -1663,11 +1946,11 @@ var VoiceProviderCapabilities = ({
|
|
|
1663
1946
|
}, undefined, false, undefined, this)
|
|
1664
1947
|
]
|
|
1665
1948
|
}, `${capability.kind}:${capability.provider}`, true, undefined, this))
|
|
1666
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
1949
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV6("p", {
|
|
1667
1950
|
className: "absolute-voice-provider-capabilities__empty",
|
|
1668
1951
|
children: "Configure provider capabilities to see deployment coverage."
|
|
1669
1952
|
}, undefined, false, undefined, this),
|
|
1670
|
-
model.error ? /* @__PURE__ */
|
|
1953
|
+
model.error ? /* @__PURE__ */ jsxDEV6("p", {
|
|
1671
1954
|
className: "absolute-voice-provider-capabilities__error",
|
|
1672
1955
|
children: model.error
|
|
1673
1956
|
}, undefined, false, undefined, this) : null
|
|
@@ -1675,7 +1958,7 @@ var VoiceProviderCapabilities = ({
|
|
|
1675
1958
|
}, undefined, true, undefined, this);
|
|
1676
1959
|
};
|
|
1677
1960
|
// src/react/useVoiceProviderContracts.tsx
|
|
1678
|
-
import { useEffect as
|
|
1961
|
+
import { useEffect as useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
|
|
1679
1962
|
|
|
1680
1963
|
// src/client/providerContracts.ts
|
|
1681
1964
|
var fetchVoiceProviderContracts = async (path = "/api/provider-contracts", options = {}) => {
|
|
@@ -1754,27 +2037,27 @@ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", optio
|
|
|
1754
2037
|
|
|
1755
2038
|
// src/react/useVoiceProviderContracts.tsx
|
|
1756
2039
|
var useVoiceProviderContracts = (path = "/api/provider-contracts", options = {}) => {
|
|
1757
|
-
const storeRef =
|
|
2040
|
+
const storeRef = useRef7(null);
|
|
1758
2041
|
if (!storeRef.current) {
|
|
1759
2042
|
storeRef.current = createVoiceProviderContractsStore(path, options);
|
|
1760
2043
|
}
|
|
1761
2044
|
const store = storeRef.current;
|
|
1762
|
-
|
|
2045
|
+
useEffect7(() => {
|
|
1763
2046
|
store.refresh().catch(() => {});
|
|
1764
2047
|
return () => store.close();
|
|
1765
2048
|
}, [store]);
|
|
1766
2049
|
return {
|
|
1767
|
-
...
|
|
2050
|
+
...useSyncExternalStore7(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1768
2051
|
refresh: store.refresh
|
|
1769
2052
|
};
|
|
1770
2053
|
};
|
|
1771
2054
|
|
|
1772
2055
|
// src/client/providerContractsWidget.ts
|
|
1773
|
-
var
|
|
1774
|
-
var
|
|
1775
|
-
var
|
|
2056
|
+
var DEFAULT_TITLE6 = "Provider Contracts";
|
|
2057
|
+
var DEFAULT_DESCRIPTION6 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
2058
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1776
2059
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1777
|
-
var
|
|
2060
|
+
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1778
2061
|
var contractDetail = (row) => {
|
|
1779
2062
|
const failing = row.checks.filter((check) => check.status !== "pass");
|
|
1780
2063
|
if (failing.length === 0) {
|
|
@@ -1793,49 +2076,49 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
1793
2076
|
label: check.remediation?.label ?? check.label
|
|
1794
2077
|
})),
|
|
1795
2078
|
rows: [
|
|
1796
|
-
{ label: "Status", value:
|
|
2079
|
+
{ label: "Status", value: formatStatus3(row.status) },
|
|
1797
2080
|
{ label: "Selected", value: row.selected ? "Yes" : "No" },
|
|
1798
2081
|
{ label: "Configured", value: row.configured ? "Yes" : "No" },
|
|
1799
2082
|
{
|
|
1800
2083
|
label: "Checks",
|
|
1801
|
-
value: row.checks.map((check) => `${check.label}: ${
|
|
2084
|
+
value: row.checks.map((check) => `${check.label}: ${formatStatus3(check.status)}`).join(", ")
|
|
1802
2085
|
}
|
|
1803
2086
|
]
|
|
1804
2087
|
}));
|
|
1805
2088
|
const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
|
|
1806
2089
|
return {
|
|
1807
|
-
description: options.description ??
|
|
2090
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
1808
2091
|
error: snapshot.error,
|
|
1809
2092
|
isLoading: snapshot.isLoading,
|
|
1810
2093
|
label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
|
|
1811
2094
|
rows,
|
|
1812
2095
|
status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1813
|
-
title: options.title ??
|
|
2096
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
1814
2097
|
updatedAt: snapshot.updatedAt
|
|
1815
2098
|
};
|
|
1816
2099
|
};
|
|
1817
2100
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
1818
2101
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
1819
|
-
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--${
|
|
2102
|
+
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--${escapeHtml7(row.status)}">
|
|
1820
2103
|
<header>
|
|
1821
|
-
<strong>${
|
|
1822
|
-
<span>${
|
|
2104
|
+
<strong>${escapeHtml7(row.label)}</strong>
|
|
2105
|
+
<span>${escapeHtml7(formatStatus3(row.status))}</span>
|
|
1823
2106
|
</header>
|
|
1824
|
-
<p>${
|
|
1825
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
2107
|
+
<p>${escapeHtml7(row.detail)}</p>
|
|
2108
|
+
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml7(remediation.href)}">${escapeHtml7(remediation.label)}</a>` : `<strong>${escapeHtml7(remediation.label)}</strong>`}<span>${escapeHtml7(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
|
|
1826
2109
|
<dl>${row.rows.map((item) => `<div>
|
|
1827
|
-
<dt>${
|
|
1828
|
-
<dd>${
|
|
2110
|
+
<dt>${escapeHtml7(item.label)}</dt>
|
|
2111
|
+
<dd>${escapeHtml7(item.value)}</dd>
|
|
1829
2112
|
</div>`).join("")}</dl>
|
|
1830
2113
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
1831
|
-
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${
|
|
2114
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml7(model.status)}">
|
|
1832
2115
|
<header class="absolute-voice-provider-contracts__header">
|
|
1833
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
1834
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
2116
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml7(model.title)}</span>
|
|
2117
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml7(model.label)}</strong>
|
|
1835
2118
|
</header>
|
|
1836
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
2119
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml7(model.description)}</p>
|
|
1837
2120
|
${rows}
|
|
1838
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
2121
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
1839
2122
|
</section>`;
|
|
1840
2123
|
};
|
|
1841
2124
|
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}`;
|
|
@@ -1877,7 +2160,7 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
|
|
|
1877
2160
|
};
|
|
1878
2161
|
|
|
1879
2162
|
// src/react/VoiceProviderContracts.tsx
|
|
1880
|
-
import { jsxDEV as
|
|
2163
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
1881
2164
|
var VoiceProviderContracts = ({
|
|
1882
2165
|
className,
|
|
1883
2166
|
path = "/api/provider-contracts",
|
|
@@ -1885,74 +2168,74 @@ var VoiceProviderContracts = ({
|
|
|
1885
2168
|
}) => {
|
|
1886
2169
|
const snapshot = useVoiceProviderContracts(path, options);
|
|
1887
2170
|
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
1888
|
-
return /* @__PURE__ */
|
|
2171
|
+
return /* @__PURE__ */ jsxDEV7("section", {
|
|
1889
2172
|
className: [
|
|
1890
2173
|
"absolute-voice-provider-contracts",
|
|
1891
2174
|
`absolute-voice-provider-contracts--${model.status}`,
|
|
1892
2175
|
className
|
|
1893
2176
|
].filter(Boolean).join(" "),
|
|
1894
2177
|
children: [
|
|
1895
|
-
/* @__PURE__ */
|
|
2178
|
+
/* @__PURE__ */ jsxDEV7("header", {
|
|
1896
2179
|
className: "absolute-voice-provider-contracts__header",
|
|
1897
2180
|
children: [
|
|
1898
|
-
/* @__PURE__ */
|
|
2181
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1899
2182
|
className: "absolute-voice-provider-contracts__eyebrow",
|
|
1900
2183
|
children: model.title
|
|
1901
2184
|
}, undefined, false, undefined, this),
|
|
1902
|
-
/* @__PURE__ */
|
|
2185
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1903
2186
|
className: "absolute-voice-provider-contracts__label",
|
|
1904
2187
|
children: model.label
|
|
1905
2188
|
}, undefined, false, undefined, this)
|
|
1906
2189
|
]
|
|
1907
2190
|
}, undefined, true, undefined, this),
|
|
1908
|
-
/* @__PURE__ */
|
|
2191
|
+
/* @__PURE__ */ jsxDEV7("p", {
|
|
1909
2192
|
className: "absolute-voice-provider-contracts__description",
|
|
1910
2193
|
children: model.description
|
|
1911
2194
|
}, undefined, false, undefined, this),
|
|
1912
|
-
model.rows.length ? /* @__PURE__ */
|
|
2195
|
+
model.rows.length ? /* @__PURE__ */ jsxDEV7("div", {
|
|
1913
2196
|
className: "absolute-voice-provider-contracts__rows",
|
|
1914
|
-
children: model.rows.map((row) => /* @__PURE__ */
|
|
2197
|
+
children: model.rows.map((row) => /* @__PURE__ */ jsxDEV7("article", {
|
|
1915
2198
|
className: [
|
|
1916
2199
|
"absolute-voice-provider-contracts__row",
|
|
1917
2200
|
`absolute-voice-provider-contracts__row--${row.status}`
|
|
1918
2201
|
].join(" "),
|
|
1919
2202
|
children: [
|
|
1920
|
-
/* @__PURE__ */
|
|
2203
|
+
/* @__PURE__ */ jsxDEV7("header", {
|
|
1921
2204
|
children: [
|
|
1922
|
-
/* @__PURE__ */
|
|
2205
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1923
2206
|
children: row.label
|
|
1924
2207
|
}, undefined, false, undefined, this),
|
|
1925
|
-
/* @__PURE__ */
|
|
2208
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1926
2209
|
children: row.status
|
|
1927
2210
|
}, undefined, false, undefined, this)
|
|
1928
2211
|
]
|
|
1929
2212
|
}, undefined, true, undefined, this),
|
|
1930
|
-
/* @__PURE__ */
|
|
2213
|
+
/* @__PURE__ */ jsxDEV7("p", {
|
|
1931
2214
|
children: row.detail
|
|
1932
2215
|
}, undefined, false, undefined, this),
|
|
1933
|
-
row.remediations.length ? /* @__PURE__ */
|
|
2216
|
+
row.remediations.length ? /* @__PURE__ */ jsxDEV7("ul", {
|
|
1934
2217
|
className: "absolute-voice-provider-contracts__remediations",
|
|
1935
|
-
children: row.remediations.map((remediation) => /* @__PURE__ */
|
|
2218
|
+
children: row.remediations.map((remediation) => /* @__PURE__ */ jsxDEV7("li", {
|
|
1936
2219
|
children: [
|
|
1937
|
-
remediation.href ? /* @__PURE__ */
|
|
2220
|
+
remediation.href ? /* @__PURE__ */ jsxDEV7("a", {
|
|
1938
2221
|
href: remediation.href,
|
|
1939
2222
|
children: remediation.label
|
|
1940
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2223
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("strong", {
|
|
1941
2224
|
children: remediation.label
|
|
1942
2225
|
}, undefined, false, undefined, this),
|
|
1943
|
-
/* @__PURE__ */
|
|
2226
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1944
2227
|
children: remediation.detail
|
|
1945
2228
|
}, undefined, false, undefined, this)
|
|
1946
2229
|
]
|
|
1947
2230
|
}, `${row.kind}:${row.provider}:${remediation.label}`, true, undefined, this))
|
|
1948
2231
|
}, undefined, false, undefined, this) : null,
|
|
1949
|
-
/* @__PURE__ */
|
|
1950
|
-
children: row.rows.map((item) => /* @__PURE__ */
|
|
2232
|
+
/* @__PURE__ */ jsxDEV7("dl", {
|
|
2233
|
+
children: row.rows.map((item) => /* @__PURE__ */ jsxDEV7("div", {
|
|
1951
2234
|
children: [
|
|
1952
|
-
/* @__PURE__ */
|
|
2235
|
+
/* @__PURE__ */ jsxDEV7("dt", {
|
|
1953
2236
|
children: item.label
|
|
1954
2237
|
}, undefined, false, undefined, this),
|
|
1955
|
-
/* @__PURE__ */
|
|
2238
|
+
/* @__PURE__ */ jsxDEV7("dd", {
|
|
1956
2239
|
children: item.value
|
|
1957
2240
|
}, undefined, false, undefined, this)
|
|
1958
2241
|
]
|
|
@@ -1960,11 +2243,11 @@ var VoiceProviderContracts = ({
|
|
|
1960
2243
|
}, undefined, false, undefined, this)
|
|
1961
2244
|
]
|
|
1962
2245
|
}, `${row.kind}:${row.provider}`, true, undefined, this))
|
|
1963
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2246
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("p", {
|
|
1964
2247
|
className: "absolute-voice-provider-contracts__empty",
|
|
1965
2248
|
children: "Configure provider contracts to see production coverage."
|
|
1966
2249
|
}, undefined, false, undefined, this),
|
|
1967
|
-
model.error ? /* @__PURE__ */
|
|
2250
|
+
model.error ? /* @__PURE__ */ jsxDEV7("p", {
|
|
1968
2251
|
className: "absolute-voice-provider-contracts__error",
|
|
1969
2252
|
children: model.error
|
|
1970
2253
|
}, undefined, false, undefined, this) : null
|
|
@@ -1972,7 +2255,7 @@ var VoiceProviderContracts = ({
|
|
|
1972
2255
|
}, undefined, true, undefined, this);
|
|
1973
2256
|
};
|
|
1974
2257
|
// src/react/useVoiceProviderStatus.tsx
|
|
1975
|
-
import { useEffect as
|
|
2258
|
+
import { useEffect as useEffect8, useRef as useRef8, useSyncExternalStore as useSyncExternalStore8 } from "react";
|
|
1976
2259
|
|
|
1977
2260
|
// src/client/providerStatus.ts
|
|
1978
2261
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
@@ -2056,27 +2339,27 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
2056
2339
|
|
|
2057
2340
|
// src/react/useVoiceProviderStatus.tsx
|
|
2058
2341
|
var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
2059
|
-
const storeRef =
|
|
2342
|
+
const storeRef = useRef8(null);
|
|
2060
2343
|
if (!storeRef.current) {
|
|
2061
2344
|
storeRef.current = createVoiceProviderStatusStore(path, options);
|
|
2062
2345
|
}
|
|
2063
2346
|
const store = storeRef.current;
|
|
2064
|
-
|
|
2347
|
+
useEffect8(() => {
|
|
2065
2348
|
store.refresh().catch(() => {});
|
|
2066
2349
|
return () => store.close();
|
|
2067
2350
|
}, [store]);
|
|
2068
2351
|
return {
|
|
2069
|
-
...
|
|
2352
|
+
...useSyncExternalStore8(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2070
2353
|
refresh: store.refresh
|
|
2071
2354
|
};
|
|
2072
2355
|
};
|
|
2073
2356
|
|
|
2074
2357
|
// src/client/providerStatusWidget.ts
|
|
2075
|
-
var
|
|
2076
|
-
var
|
|
2077
|
-
var
|
|
2358
|
+
var DEFAULT_TITLE7 = "Voice Providers";
|
|
2359
|
+
var DEFAULT_DESCRIPTION7 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
2360
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2078
2361
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
2079
|
-
var
|
|
2362
|
+
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
2080
2363
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
2081
2364
|
var formatSuppression = (value) => typeof value === "number" ? `${Math.ceil(value / 1000)}s` : "None";
|
|
2082
2365
|
var getProviderDetail = (provider) => {
|
|
@@ -2118,37 +2401,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
2118
2401
|
const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
|
|
2119
2402
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
2120
2403
|
return {
|
|
2121
|
-
description: options.description ??
|
|
2404
|
+
description: options.description ?? DEFAULT_DESCRIPTION7,
|
|
2122
2405
|
error: snapshot.error,
|
|
2123
2406
|
isLoading: snapshot.isLoading,
|
|
2124
2407
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
2125
2408
|
providers,
|
|
2126
2409
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2127
|
-
title: options.title ??
|
|
2410
|
+
title: options.title ?? DEFAULT_TITLE7,
|
|
2128
2411
|
updatedAt: snapshot.updatedAt
|
|
2129
2412
|
};
|
|
2130
2413
|
};
|
|
2131
2414
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
2132
2415
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
2133
|
-
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--${
|
|
2416
|
+
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--${escapeHtml8(provider.status)}">
|
|
2134
2417
|
<header>
|
|
2135
|
-
<strong>${
|
|
2136
|
-
<span>${
|
|
2418
|
+
<strong>${escapeHtml8(provider.label)}</strong>
|
|
2419
|
+
<span>${escapeHtml8(formatStatus4(provider.status))}</span>
|
|
2137
2420
|
</header>
|
|
2138
|
-
<p>${
|
|
2421
|
+
<p>${escapeHtml8(provider.detail)}</p>
|
|
2139
2422
|
<dl>${provider.rows.map((row) => `<div>
|
|
2140
|
-
<dt>${
|
|
2141
|
-
<dd>${
|
|
2423
|
+
<dt>${escapeHtml8(row.label)}</dt>
|
|
2424
|
+
<dd>${escapeHtml8(row.value)}</dd>
|
|
2142
2425
|
</div>`).join("")}</dl>
|
|
2143
2426
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
2144
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
2427
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml8(model.status)}">
|
|
2145
2428
|
<header class="absolute-voice-provider-status__header">
|
|
2146
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
2147
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
2429
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml8(model.title)}</span>
|
|
2430
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml8(model.label)}</strong>
|
|
2148
2431
|
</header>
|
|
2149
|
-
<p class="absolute-voice-provider-status__description">${
|
|
2432
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml8(model.description)}</p>
|
|
2150
2433
|
${providers}
|
|
2151
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
2434
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml8(model.error)}</p>` : ""}
|
|
2152
2435
|
</section>`;
|
|
2153
2436
|
};
|
|
2154
2437
|
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}`;
|
|
@@ -2190,7 +2473,7 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
2190
2473
|
};
|
|
2191
2474
|
|
|
2192
2475
|
// src/react/VoiceProviderStatus.tsx
|
|
2193
|
-
import { jsxDEV as
|
|
2476
|
+
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
2194
2477
|
var VoiceProviderStatus = ({
|
|
2195
2478
|
className,
|
|
2196
2479
|
path = "/api/provider-status",
|
|
@@ -2198,58 +2481,58 @@ var VoiceProviderStatus = ({
|
|
|
2198
2481
|
}) => {
|
|
2199
2482
|
const snapshot = useVoiceProviderStatus(path, options);
|
|
2200
2483
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
2201
|
-
return /* @__PURE__ */
|
|
2484
|
+
return /* @__PURE__ */ jsxDEV8("section", {
|
|
2202
2485
|
className: [
|
|
2203
2486
|
"absolute-voice-provider-status",
|
|
2204
2487
|
`absolute-voice-provider-status--${model.status}`,
|
|
2205
2488
|
className
|
|
2206
2489
|
].filter(Boolean).join(" "),
|
|
2207
2490
|
children: [
|
|
2208
|
-
/* @__PURE__ */
|
|
2491
|
+
/* @__PURE__ */ jsxDEV8("header", {
|
|
2209
2492
|
className: "absolute-voice-provider-status__header",
|
|
2210
2493
|
children: [
|
|
2211
|
-
/* @__PURE__ */
|
|
2494
|
+
/* @__PURE__ */ jsxDEV8("span", {
|
|
2212
2495
|
className: "absolute-voice-provider-status__eyebrow",
|
|
2213
2496
|
children: model.title
|
|
2214
2497
|
}, undefined, false, undefined, this),
|
|
2215
|
-
/* @__PURE__ */
|
|
2498
|
+
/* @__PURE__ */ jsxDEV8("strong", {
|
|
2216
2499
|
className: "absolute-voice-provider-status__label",
|
|
2217
2500
|
children: model.label
|
|
2218
2501
|
}, undefined, false, undefined, this)
|
|
2219
2502
|
]
|
|
2220
2503
|
}, undefined, true, undefined, this),
|
|
2221
|
-
/* @__PURE__ */
|
|
2504
|
+
/* @__PURE__ */ jsxDEV8("p", {
|
|
2222
2505
|
className: "absolute-voice-provider-status__description",
|
|
2223
2506
|
children: model.description
|
|
2224
2507
|
}, undefined, false, undefined, this),
|
|
2225
|
-
model.providers.length ? /* @__PURE__ */
|
|
2508
|
+
model.providers.length ? /* @__PURE__ */ jsxDEV8("div", {
|
|
2226
2509
|
className: "absolute-voice-provider-status__providers",
|
|
2227
|
-
children: model.providers.map((provider) => /* @__PURE__ */
|
|
2510
|
+
children: model.providers.map((provider) => /* @__PURE__ */ jsxDEV8("article", {
|
|
2228
2511
|
className: [
|
|
2229
2512
|
"absolute-voice-provider-status__provider",
|
|
2230
2513
|
`absolute-voice-provider-status__provider--${provider.status}`
|
|
2231
2514
|
].join(" "),
|
|
2232
2515
|
children: [
|
|
2233
|
-
/* @__PURE__ */
|
|
2516
|
+
/* @__PURE__ */ jsxDEV8("header", {
|
|
2234
2517
|
children: [
|
|
2235
|
-
/* @__PURE__ */
|
|
2518
|
+
/* @__PURE__ */ jsxDEV8("strong", {
|
|
2236
2519
|
children: provider.label
|
|
2237
2520
|
}, undefined, false, undefined, this),
|
|
2238
|
-
/* @__PURE__ */
|
|
2521
|
+
/* @__PURE__ */ jsxDEV8("span", {
|
|
2239
2522
|
children: provider.status
|
|
2240
2523
|
}, undefined, false, undefined, this)
|
|
2241
2524
|
]
|
|
2242
2525
|
}, undefined, true, undefined, this),
|
|
2243
|
-
/* @__PURE__ */
|
|
2526
|
+
/* @__PURE__ */ jsxDEV8("p", {
|
|
2244
2527
|
children: provider.detail
|
|
2245
2528
|
}, undefined, false, undefined, this),
|
|
2246
|
-
/* @__PURE__ */
|
|
2247
|
-
children: provider.rows.map((row) => /* @__PURE__ */
|
|
2529
|
+
/* @__PURE__ */ jsxDEV8("dl", {
|
|
2530
|
+
children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV8("div", {
|
|
2248
2531
|
children: [
|
|
2249
|
-
/* @__PURE__ */
|
|
2532
|
+
/* @__PURE__ */ jsxDEV8("dt", {
|
|
2250
2533
|
children: row.label
|
|
2251
2534
|
}, undefined, false, undefined, this),
|
|
2252
|
-
/* @__PURE__ */
|
|
2535
|
+
/* @__PURE__ */ jsxDEV8("dd", {
|
|
2253
2536
|
children: row.value
|
|
2254
2537
|
}, undefined, false, undefined, this)
|
|
2255
2538
|
]
|
|
@@ -2257,11 +2540,11 @@ var VoiceProviderStatus = ({
|
|
|
2257
2540
|
}, undefined, false, undefined, this)
|
|
2258
2541
|
]
|
|
2259
2542
|
}, provider.provider, true, undefined, this))
|
|
2260
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2543
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV8("p", {
|
|
2261
2544
|
className: "absolute-voice-provider-status__empty",
|
|
2262
2545
|
children: "Run voice traffic to see provider health."
|
|
2263
2546
|
}, undefined, false, undefined, this),
|
|
2264
|
-
model.error ? /* @__PURE__ */
|
|
2547
|
+
model.error ? /* @__PURE__ */ jsxDEV8("p", {
|
|
2265
2548
|
className: "absolute-voice-provider-status__error",
|
|
2266
2549
|
children: model.error
|
|
2267
2550
|
}, undefined, false, undefined, this) : null
|
|
@@ -2269,7 +2552,7 @@ var VoiceProviderStatus = ({
|
|
|
2269
2552
|
}, undefined, true, undefined, this);
|
|
2270
2553
|
};
|
|
2271
2554
|
// src/react/useVoiceRoutingStatus.tsx
|
|
2272
|
-
import { useEffect as
|
|
2555
|
+
import { useEffect as useEffect9, useRef as useRef9, useSyncExternalStore as useSyncExternalStore9 } from "react";
|
|
2273
2556
|
|
|
2274
2557
|
// src/client/routingStatus.ts
|
|
2275
2558
|
var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
|
|
@@ -2353,25 +2636,25 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
2353
2636
|
|
|
2354
2637
|
// src/react/useVoiceRoutingStatus.tsx
|
|
2355
2638
|
var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
2356
|
-
const storeRef =
|
|
2639
|
+
const storeRef = useRef9(null);
|
|
2357
2640
|
if (!storeRef.current) {
|
|
2358
2641
|
storeRef.current = createVoiceRoutingStatusStore(path, options);
|
|
2359
2642
|
}
|
|
2360
2643
|
const store = storeRef.current;
|
|
2361
|
-
|
|
2644
|
+
useEffect9(() => {
|
|
2362
2645
|
store.refresh().catch(() => {});
|
|
2363
2646
|
return () => store.close();
|
|
2364
2647
|
}, [store]);
|
|
2365
2648
|
return {
|
|
2366
|
-
...
|
|
2649
|
+
...useSyncExternalStore9(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2367
2650
|
refresh: store.refresh
|
|
2368
2651
|
};
|
|
2369
2652
|
};
|
|
2370
2653
|
|
|
2371
2654
|
// src/client/routingStatusWidget.ts
|
|
2372
|
-
var
|
|
2373
|
-
var
|
|
2374
|
-
var
|
|
2655
|
+
var DEFAULT_TITLE8 = "Voice Routing";
|
|
2656
|
+
var DEFAULT_DESCRIPTION8 = "Latest provider routing decision from the self-hosted trace store.";
|
|
2657
|
+
var escapeHtml9 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2375
2658
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
2376
2659
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
2377
2660
|
const decision = snapshot.decision;
|
|
@@ -2395,30 +2678,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
2395
2678
|
] : [];
|
|
2396
2679
|
return {
|
|
2397
2680
|
decision,
|
|
2398
|
-
description: options.description ??
|
|
2681
|
+
description: options.description ?? DEFAULT_DESCRIPTION8,
|
|
2399
2682
|
error: snapshot.error,
|
|
2400
2683
|
isLoading: snapshot.isLoading,
|
|
2401
2684
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
2402
2685
|
rows,
|
|
2403
2686
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2404
|
-
title: options.title ??
|
|
2687
|
+
title: options.title ?? DEFAULT_TITLE8,
|
|
2405
2688
|
updatedAt: snapshot.updatedAt
|
|
2406
2689
|
};
|
|
2407
2690
|
};
|
|
2408
2691
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
2409
2692
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
2410
2693
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
2411
|
-
<span>${
|
|
2412
|
-
<strong>${
|
|
2694
|
+
<span>${escapeHtml9(row.label)}</span>
|
|
2695
|
+
<strong>${escapeHtml9(row.value)}</strong>
|
|
2413
2696
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
2414
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
2697
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml9(model.status)}">
|
|
2415
2698
|
<header class="absolute-voice-routing-status__header">
|
|
2416
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
2417
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
2699
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml9(model.title)}</span>
|
|
2700
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml9(model.label)}</strong>
|
|
2418
2701
|
</header>
|
|
2419
|
-
<p class="absolute-voice-routing-status__description">${
|
|
2702
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml9(model.description)}</p>
|
|
2420
2703
|
${rows}
|
|
2421
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
2704
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml9(model.error)}</p>` : ""}
|
|
2422
2705
|
</section>`;
|
|
2423
2706
|
};
|
|
2424
2707
|
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__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}`;
|
|
@@ -2460,7 +2743,7 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
|
|
|
2460
2743
|
};
|
|
2461
2744
|
|
|
2462
2745
|
// src/react/VoiceRoutingStatus.tsx
|
|
2463
|
-
import { jsxDEV as
|
|
2746
|
+
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
2464
2747
|
var VoiceRoutingStatus = ({
|
|
2465
2748
|
className,
|
|
2466
2749
|
path = "/api/routing/latest",
|
|
@@ -2468,47 +2751,47 @@ var VoiceRoutingStatus = ({
|
|
|
2468
2751
|
}) => {
|
|
2469
2752
|
const snapshot = useVoiceRoutingStatus(path, options);
|
|
2470
2753
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
2471
|
-
return /* @__PURE__ */
|
|
2754
|
+
return /* @__PURE__ */ jsxDEV9("section", {
|
|
2472
2755
|
className: [
|
|
2473
2756
|
"absolute-voice-routing-status",
|
|
2474
2757
|
`absolute-voice-routing-status--${model.status}`,
|
|
2475
2758
|
className
|
|
2476
2759
|
].filter(Boolean).join(" "),
|
|
2477
2760
|
children: [
|
|
2478
|
-
/* @__PURE__ */
|
|
2761
|
+
/* @__PURE__ */ jsxDEV9("header", {
|
|
2479
2762
|
className: "absolute-voice-routing-status__header",
|
|
2480
2763
|
children: [
|
|
2481
|
-
/* @__PURE__ */
|
|
2764
|
+
/* @__PURE__ */ jsxDEV9("span", {
|
|
2482
2765
|
className: "absolute-voice-routing-status__eyebrow",
|
|
2483
2766
|
children: model.title
|
|
2484
2767
|
}, undefined, false, undefined, this),
|
|
2485
|
-
/* @__PURE__ */
|
|
2768
|
+
/* @__PURE__ */ jsxDEV9("strong", {
|
|
2486
2769
|
className: "absolute-voice-routing-status__label",
|
|
2487
2770
|
children: model.label
|
|
2488
2771
|
}, undefined, false, undefined, this)
|
|
2489
2772
|
]
|
|
2490
2773
|
}, undefined, true, undefined, this),
|
|
2491
|
-
/* @__PURE__ */
|
|
2774
|
+
/* @__PURE__ */ jsxDEV9("p", {
|
|
2492
2775
|
className: "absolute-voice-routing-status__description",
|
|
2493
2776
|
children: model.description
|
|
2494
2777
|
}, undefined, false, undefined, this),
|
|
2495
|
-
model.rows.length ? /* @__PURE__ */
|
|
2778
|
+
model.rows.length ? /* @__PURE__ */ jsxDEV9("div", {
|
|
2496
2779
|
className: "absolute-voice-routing-status__grid",
|
|
2497
|
-
children: model.rows.map((row) => /* @__PURE__ */
|
|
2780
|
+
children: model.rows.map((row) => /* @__PURE__ */ jsxDEV9("div", {
|
|
2498
2781
|
children: [
|
|
2499
|
-
/* @__PURE__ */
|
|
2782
|
+
/* @__PURE__ */ jsxDEV9("span", {
|
|
2500
2783
|
children: row.label
|
|
2501
2784
|
}, undefined, false, undefined, this),
|
|
2502
|
-
/* @__PURE__ */
|
|
2785
|
+
/* @__PURE__ */ jsxDEV9("strong", {
|
|
2503
2786
|
children: row.value
|
|
2504
2787
|
}, undefined, false, undefined, this)
|
|
2505
2788
|
]
|
|
2506
2789
|
}, row.label, true, undefined, this))
|
|
2507
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2790
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9("p", {
|
|
2508
2791
|
className: "absolute-voice-routing-status__empty",
|
|
2509
2792
|
children: "Start a voice session to see the selected provider."
|
|
2510
2793
|
}, undefined, false, undefined, this),
|
|
2511
|
-
model.error ? /* @__PURE__ */
|
|
2794
|
+
model.error ? /* @__PURE__ */ jsxDEV9("p", {
|
|
2512
2795
|
className: "absolute-voice-routing-status__error",
|
|
2513
2796
|
children: model.error
|
|
2514
2797
|
}, undefined, false, undefined, this) : null
|
|
@@ -2596,9 +2879,9 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
|
|
|
2596
2879
|
};
|
|
2597
2880
|
|
|
2598
2881
|
// src/client/traceTimelineWidget.ts
|
|
2599
|
-
var
|
|
2600
|
-
var
|
|
2601
|
-
var
|
|
2882
|
+
var DEFAULT_TITLE9 = "Voice Traces";
|
|
2883
|
+
var DEFAULT_DESCRIPTION9 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
2884
|
+
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2602
2885
|
var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
2603
2886
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
2604
2887
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -2614,13 +2897,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
|
2614
2897
|
const failed = sessions.filter((session) => session.status === "failed").length;
|
|
2615
2898
|
const warnings = sessions.filter((session) => session.status === "warning").length;
|
|
2616
2899
|
return {
|
|
2617
|
-
description: options.description ??
|
|
2900
|
+
description: options.description ?? DEFAULT_DESCRIPTION9,
|
|
2618
2901
|
error: snapshot.error,
|
|
2619
2902
|
isLoading: snapshot.isLoading,
|
|
2620
2903
|
label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
|
|
2621
2904
|
sessions,
|
|
2622
2905
|
status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2623
|
-
title: options.title ??
|
|
2906
|
+
title: options.title ?? DEFAULT_TITLE9,
|
|
2624
2907
|
updatedAt: snapshot.updatedAt
|
|
2625
2908
|
};
|
|
2626
2909
|
};
|
|
@@ -2628,27 +2911,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
2628
2911
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
2629
2912
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
2630
2913
|
const supportLinks = [
|
|
2631
|
-
`<a href="${
|
|
2632
|
-
session.operationsRecordHref ? `<a href="${
|
|
2633
|
-
session.incidentBundleHref ? `<a href="${
|
|
2914
|
+
`<a href="${escapeHtml10(session.detailHref)}">Open timeline</a>`,
|
|
2915
|
+
session.operationsRecordHref ? `<a href="${escapeHtml10(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
2916
|
+
session.incidentBundleHref ? `<a href="${escapeHtml10(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
2634
2917
|
].filter(Boolean).join("");
|
|
2635
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
2918
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml10(session.status)}">
|
|
2636
2919
|
<header>
|
|
2637
|
-
<strong>${
|
|
2638
|
-
<span>${
|
|
2920
|
+
<strong>${escapeHtml10(session.sessionId)}</strong>
|
|
2921
|
+
<span>${escapeHtml10(session.status)}</span>
|
|
2639
2922
|
</header>
|
|
2640
|
-
<p>${
|
|
2923
|
+
<p>${escapeHtml10(session.label)} \xB7 ${escapeHtml10(session.durationLabel)} \xB7 ${escapeHtml10(session.providerLabel)}</p>
|
|
2641
2924
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
2642
2925
|
</article>`;
|
|
2643
2926
|
}).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
2644
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
2927
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml10(model.status)}">
|
|
2645
2928
|
<header class="absolute-voice-trace-timeline__header">
|
|
2646
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
2647
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
2929
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml10(model.title)}</span>
|
|
2930
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml10(model.label)}</strong>
|
|
2648
2931
|
</header>
|
|
2649
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
2932
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml10(model.description)}</p>
|
|
2650
2933
|
${sessions}
|
|
2651
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
2934
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml10(model.error)}</p>` : ""}
|
|
2652
2935
|
</section>`;
|
|
2653
2936
|
};
|
|
2654
2937
|
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}`;
|
|
@@ -2695,25 +2978,25 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
|
|
|
2695
2978
|
};
|
|
2696
2979
|
|
|
2697
2980
|
// src/react/useVoiceTraceTimeline.tsx
|
|
2698
|
-
import { useEffect as
|
|
2981
|
+
import { useEffect as useEffect10, useRef as useRef10, useSyncExternalStore as useSyncExternalStore10 } from "react";
|
|
2699
2982
|
var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
|
|
2700
|
-
const storeRef =
|
|
2983
|
+
const storeRef = useRef10(null);
|
|
2701
2984
|
if (!storeRef.current) {
|
|
2702
2985
|
storeRef.current = createVoiceTraceTimelineStore(path, options);
|
|
2703
2986
|
}
|
|
2704
2987
|
const store = storeRef.current;
|
|
2705
|
-
|
|
2988
|
+
useEffect10(() => {
|
|
2706
2989
|
store.refresh().catch(() => {});
|
|
2707
2990
|
return () => store.close();
|
|
2708
2991
|
}, [store]);
|
|
2709
2992
|
return {
|
|
2710
|
-
...
|
|
2993
|
+
...useSyncExternalStore10(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2711
2994
|
refresh: store.refresh
|
|
2712
2995
|
};
|
|
2713
2996
|
};
|
|
2714
2997
|
|
|
2715
2998
|
// src/react/VoiceTraceTimeline.tsx
|
|
2716
|
-
import { jsxDEV as
|
|
2999
|
+
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
2717
3000
|
var VoiceTraceTimeline = ({
|
|
2718
3001
|
className,
|
|
2719
3002
|
path = "/api/voice-traces",
|
|
@@ -2721,49 +3004,49 @@ var VoiceTraceTimeline = ({
|
|
|
2721
3004
|
}) => {
|
|
2722
3005
|
const snapshot = useVoiceTraceTimeline(path, options);
|
|
2723
3006
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
2724
|
-
return /* @__PURE__ */
|
|
3007
|
+
return /* @__PURE__ */ jsxDEV10("section", {
|
|
2725
3008
|
className: [
|
|
2726
3009
|
"absolute-voice-trace-timeline",
|
|
2727
3010
|
`absolute-voice-trace-timeline--${model.status}`,
|
|
2728
3011
|
className
|
|
2729
3012
|
].filter(Boolean).join(" "),
|
|
2730
3013
|
children: [
|
|
2731
|
-
/* @__PURE__ */
|
|
3014
|
+
/* @__PURE__ */ jsxDEV10("header", {
|
|
2732
3015
|
className: "absolute-voice-trace-timeline__header",
|
|
2733
3016
|
children: [
|
|
2734
|
-
/* @__PURE__ */
|
|
3017
|
+
/* @__PURE__ */ jsxDEV10("span", {
|
|
2735
3018
|
className: "absolute-voice-trace-timeline__eyebrow",
|
|
2736
3019
|
children: model.title
|
|
2737
3020
|
}, undefined, false, undefined, this),
|
|
2738
|
-
/* @__PURE__ */
|
|
3021
|
+
/* @__PURE__ */ jsxDEV10("strong", {
|
|
2739
3022
|
className: "absolute-voice-trace-timeline__label",
|
|
2740
3023
|
children: model.label
|
|
2741
3024
|
}, undefined, false, undefined, this)
|
|
2742
3025
|
]
|
|
2743
3026
|
}, undefined, true, undefined, this),
|
|
2744
|
-
/* @__PURE__ */
|
|
3027
|
+
/* @__PURE__ */ jsxDEV10("p", {
|
|
2745
3028
|
className: "absolute-voice-trace-timeline__description",
|
|
2746
3029
|
children: model.description
|
|
2747
3030
|
}, undefined, false, undefined, this),
|
|
2748
|
-
model.sessions.length ? /* @__PURE__ */
|
|
3031
|
+
model.sessions.length ? /* @__PURE__ */ jsxDEV10("div", {
|
|
2749
3032
|
className: "absolute-voice-trace-timeline__sessions",
|
|
2750
|
-
children: model.sessions.map((session) => /* @__PURE__ */
|
|
3033
|
+
children: model.sessions.map((session) => /* @__PURE__ */ jsxDEV10("article", {
|
|
2751
3034
|
className: [
|
|
2752
3035
|
"absolute-voice-trace-timeline__session",
|
|
2753
3036
|
`absolute-voice-trace-timeline__session--${session.status}`
|
|
2754
3037
|
].join(" "),
|
|
2755
3038
|
children: [
|
|
2756
|
-
/* @__PURE__ */
|
|
3039
|
+
/* @__PURE__ */ jsxDEV10("header", {
|
|
2757
3040
|
children: [
|
|
2758
|
-
/* @__PURE__ */
|
|
3041
|
+
/* @__PURE__ */ jsxDEV10("strong", {
|
|
2759
3042
|
children: session.sessionId
|
|
2760
3043
|
}, undefined, false, undefined, this),
|
|
2761
|
-
/* @__PURE__ */
|
|
3044
|
+
/* @__PURE__ */ jsxDEV10("span", {
|
|
2762
3045
|
children: session.status
|
|
2763
3046
|
}, undefined, false, undefined, this)
|
|
2764
3047
|
]
|
|
2765
3048
|
}, undefined, true, undefined, this),
|
|
2766
|
-
/* @__PURE__ */
|
|
3049
|
+
/* @__PURE__ */ jsxDEV10("p", {
|
|
2767
3050
|
children: [
|
|
2768
3051
|
session.label,
|
|
2769
3052
|
" \xB7 ",
|
|
@@ -2773,18 +3056,18 @@ var VoiceTraceTimeline = ({
|
|
|
2773
3056
|
session.providerLabel
|
|
2774
3057
|
]
|
|
2775
3058
|
}, undefined, true, undefined, this),
|
|
2776
|
-
/* @__PURE__ */
|
|
3059
|
+
/* @__PURE__ */ jsxDEV10("p", {
|
|
2777
3060
|
className: "absolute-voice-trace-timeline__actions",
|
|
2778
3061
|
children: [
|
|
2779
|
-
/* @__PURE__ */
|
|
3062
|
+
/* @__PURE__ */ jsxDEV10("a", {
|
|
2780
3063
|
href: session.detailHref,
|
|
2781
3064
|
children: "Open timeline"
|
|
2782
3065
|
}, undefined, false, undefined, this),
|
|
2783
|
-
session.operationsRecordHref ? /* @__PURE__ */
|
|
3066
|
+
session.operationsRecordHref ? /* @__PURE__ */ jsxDEV10("a", {
|
|
2784
3067
|
href: session.operationsRecordHref,
|
|
2785
3068
|
children: "Open operations record"
|
|
2786
3069
|
}, undefined, false, undefined, this) : null,
|
|
2787
|
-
session.incidentBundleHref ? /* @__PURE__ */
|
|
3070
|
+
session.incidentBundleHref ? /* @__PURE__ */ jsxDEV10("a", {
|
|
2788
3071
|
href: session.incidentBundleHref,
|
|
2789
3072
|
children: "Export incident bundle"
|
|
2790
3073
|
}, undefined, false, undefined, this) : null
|
|
@@ -2792,11 +3075,11 @@ var VoiceTraceTimeline = ({
|
|
|
2792
3075
|
}, undefined, true, undefined, this)
|
|
2793
3076
|
]
|
|
2794
3077
|
}, session.sessionId, true, undefined, this))
|
|
2795
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
3078
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV10("p", {
|
|
2796
3079
|
className: "absolute-voice-trace-timeline__empty",
|
|
2797
3080
|
children: "Run a voice session to see call timelines."
|
|
2798
3081
|
}, undefined, false, undefined, this),
|
|
2799
|
-
model.error ? /* @__PURE__ */
|
|
3082
|
+
model.error ? /* @__PURE__ */ jsxDEV10("p", {
|
|
2800
3083
|
className: "absolute-voice-trace-timeline__error",
|
|
2801
3084
|
children: model.error
|
|
2802
3085
|
}, undefined, false, undefined, this) : null
|
|
@@ -2804,7 +3087,7 @@ var VoiceTraceTimeline = ({
|
|
|
2804
3087
|
}, undefined, true, undefined, this);
|
|
2805
3088
|
};
|
|
2806
3089
|
// src/react/useVoiceAgentSquadStatus.tsx
|
|
2807
|
-
import { useEffect as
|
|
3090
|
+
import { useEffect as useEffect11, useRef as useRef11, useSyncExternalStore as useSyncExternalStore11 } from "react";
|
|
2808
3091
|
|
|
2809
3092
|
// src/client/agentSquadStatus.ts
|
|
2810
3093
|
var getString = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
@@ -2882,25 +3165,25 @@ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}
|
|
|
2882
3165
|
|
|
2883
3166
|
// src/react/useVoiceAgentSquadStatus.tsx
|
|
2884
3167
|
var useVoiceAgentSquadStatus = (path = "/api/voice-traces", options = {}) => {
|
|
2885
|
-
const storeRef =
|
|
3168
|
+
const storeRef = useRef11(null);
|
|
2886
3169
|
if (!storeRef.current) {
|
|
2887
3170
|
storeRef.current = createVoiceAgentSquadStatusStore(path, options);
|
|
2888
3171
|
}
|
|
2889
3172
|
const store = storeRef.current;
|
|
2890
|
-
|
|
3173
|
+
useEffect11(() => {
|
|
2891
3174
|
store.refresh().catch(() => {});
|
|
2892
3175
|
return () => store.close();
|
|
2893
3176
|
}, [store]);
|
|
2894
3177
|
return {
|
|
2895
|
-
...
|
|
3178
|
+
...useSyncExternalStore11(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2896
3179
|
refresh: store.refresh
|
|
2897
3180
|
};
|
|
2898
3181
|
};
|
|
2899
3182
|
|
|
2900
3183
|
// src/client/agentSquadStatusWidget.ts
|
|
2901
|
-
var
|
|
2902
|
-
var
|
|
2903
|
-
var
|
|
3184
|
+
var DEFAULT_TITLE10 = "Voice Agent Squad";
|
|
3185
|
+
var DEFAULT_DESCRIPTION10 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
3186
|
+
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2904
3187
|
var labelFor = (current) => {
|
|
2905
3188
|
if (!current)
|
|
2906
3189
|
return "Waiting for specialist activity";
|
|
@@ -2914,37 +3197,37 @@ var labelFor = (current) => {
|
|
|
2914
3197
|
};
|
|
2915
3198
|
var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
|
|
2916
3199
|
current: snapshot.report.current,
|
|
2917
|
-
description: options.description ??
|
|
3200
|
+
description: options.description ?? DEFAULT_DESCRIPTION10,
|
|
2918
3201
|
error: snapshot.error,
|
|
2919
3202
|
isLoading: snapshot.isLoading,
|
|
2920
3203
|
label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
|
|
2921
3204
|
sessionCount: snapshot.report.sessionCount,
|
|
2922
3205
|
sessions: snapshot.report.sessions,
|
|
2923
|
-
title: options.title ??
|
|
3206
|
+
title: options.title ?? DEFAULT_TITLE10,
|
|
2924
3207
|
updatedAt: snapshot.updatedAt
|
|
2925
3208
|
});
|
|
2926
3209
|
var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
2927
3210
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
2928
3211
|
const current = model.current;
|
|
2929
3212
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
2930
|
-
<span>${
|
|
2931
|
-
<strong>${
|
|
2932
|
-
<em>${
|
|
2933
|
-
${session.summary || session.reason ? `<p>${
|
|
3213
|
+
<span>${escapeHtml11(session.sessionId)}</span>
|
|
3214
|
+
<strong>${escapeHtml11(session.targetAgentId ?? "none")}</strong>
|
|
3215
|
+
<em>${escapeHtml11(session.status)}</em>
|
|
3216
|
+
${session.summary || session.reason ? `<p>${escapeHtml11(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
2934
3217
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
2935
3218
|
return `<section class="absolute-voice-agent-squad-status">
|
|
2936
3219
|
<header>
|
|
2937
|
-
<span>${
|
|
2938
|
-
<strong>${
|
|
3220
|
+
<span>${escapeHtml11(model.title)}</span>
|
|
3221
|
+
<strong>${escapeHtml11(model.label)}</strong>
|
|
2939
3222
|
</header>
|
|
2940
|
-
<p>${
|
|
3223
|
+
<p>${escapeHtml11(model.description)}</p>
|
|
2941
3224
|
<div>
|
|
2942
|
-
<span>Session</span><strong>${
|
|
2943
|
-
<span>From</span><strong>${
|
|
2944
|
-
<span>Status</span><strong>${
|
|
3225
|
+
<span>Session</span><strong>${escapeHtml11(current?.sessionId ?? "n/a")}</strong>
|
|
3226
|
+
<span>From</span><strong>${escapeHtml11(current?.fromAgentId ?? "n/a")}</strong>
|
|
3227
|
+
<span>Status</span><strong>${escapeHtml11(current?.status ?? "idle")}</strong>
|
|
2945
3228
|
</div>
|
|
2946
3229
|
<ul>${rows}</ul>
|
|
2947
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
3230
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml11(model.error)}</p>` : ""}
|
|
2948
3231
|
</section>`;
|
|
2949
3232
|
};
|
|
2950
3233
|
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}`;
|
|
@@ -2989,7 +3272,7 @@ var defineVoiceAgentSquadStatusElement = (tagName = "absolute-voice-agent-squad-
|
|
|
2989
3272
|
};
|
|
2990
3273
|
|
|
2991
3274
|
// src/react/VoiceAgentSquadStatus.tsx
|
|
2992
|
-
import { jsxDEV as
|
|
3275
|
+
import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
|
|
2993
3276
|
function VoiceAgentSquadStatus({
|
|
2994
3277
|
path = "/api/voice-traces",
|
|
2995
3278
|
...options
|
|
@@ -2997,64 +3280,64 @@ function VoiceAgentSquadStatus({
|
|
|
2997
3280
|
const snapshot = useVoiceAgentSquadStatus(path, options);
|
|
2998
3281
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
2999
3282
|
const current = model.current;
|
|
3000
|
-
return /* @__PURE__ */
|
|
3283
|
+
return /* @__PURE__ */ jsxDEV11("section", {
|
|
3001
3284
|
className: "absolute-voice-agent-squad-status",
|
|
3002
3285
|
children: [
|
|
3003
|
-
/* @__PURE__ */
|
|
3286
|
+
/* @__PURE__ */ jsxDEV11("header", {
|
|
3004
3287
|
children: [
|
|
3005
|
-
/* @__PURE__ */
|
|
3288
|
+
/* @__PURE__ */ jsxDEV11("span", {
|
|
3006
3289
|
children: model.title
|
|
3007
3290
|
}, undefined, false, undefined, this),
|
|
3008
|
-
/* @__PURE__ */
|
|
3291
|
+
/* @__PURE__ */ jsxDEV11("strong", {
|
|
3009
3292
|
children: model.label
|
|
3010
3293
|
}, undefined, false, undefined, this)
|
|
3011
3294
|
]
|
|
3012
3295
|
}, undefined, true, undefined, this),
|
|
3013
|
-
/* @__PURE__ */
|
|
3296
|
+
/* @__PURE__ */ jsxDEV11("p", {
|
|
3014
3297
|
children: model.description
|
|
3015
3298
|
}, undefined, false, undefined, this),
|
|
3016
|
-
/* @__PURE__ */
|
|
3299
|
+
/* @__PURE__ */ jsxDEV11("dl", {
|
|
3017
3300
|
children: [
|
|
3018
|
-
/* @__PURE__ */
|
|
3301
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
3019
3302
|
children: [
|
|
3020
|
-
/* @__PURE__ */
|
|
3303
|
+
/* @__PURE__ */ jsxDEV11("dt", {
|
|
3021
3304
|
children: "Session"
|
|
3022
3305
|
}, undefined, false, undefined, this),
|
|
3023
|
-
/* @__PURE__ */
|
|
3306
|
+
/* @__PURE__ */ jsxDEV11("dd", {
|
|
3024
3307
|
children: current?.sessionId ?? "n/a"
|
|
3025
3308
|
}, undefined, false, undefined, this)
|
|
3026
3309
|
]
|
|
3027
3310
|
}, undefined, true, undefined, this),
|
|
3028
|
-
/* @__PURE__ */
|
|
3311
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
3029
3312
|
children: [
|
|
3030
|
-
/* @__PURE__ */
|
|
3313
|
+
/* @__PURE__ */ jsxDEV11("dt", {
|
|
3031
3314
|
children: "Current specialist"
|
|
3032
3315
|
}, undefined, false, undefined, this),
|
|
3033
|
-
/* @__PURE__ */
|
|
3316
|
+
/* @__PURE__ */ jsxDEV11("dd", {
|
|
3034
3317
|
children: current?.targetAgentId ?? "none"
|
|
3035
3318
|
}, undefined, false, undefined, this)
|
|
3036
3319
|
]
|
|
3037
3320
|
}, undefined, true, undefined, this),
|
|
3038
|
-
/* @__PURE__ */
|
|
3321
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
3039
3322
|
children: [
|
|
3040
|
-
/* @__PURE__ */
|
|
3323
|
+
/* @__PURE__ */ jsxDEV11("dt", {
|
|
3041
3324
|
children: "Status"
|
|
3042
3325
|
}, undefined, false, undefined, this),
|
|
3043
|
-
/* @__PURE__ */
|
|
3326
|
+
/* @__PURE__ */ jsxDEV11("dd", {
|
|
3044
3327
|
children: current?.status ?? "idle"
|
|
3045
3328
|
}, undefined, false, undefined, this)
|
|
3046
3329
|
]
|
|
3047
3330
|
}, undefined, true, undefined, this)
|
|
3048
3331
|
]
|
|
3049
3332
|
}, undefined, true, undefined, this),
|
|
3050
|
-
model.error ? /* @__PURE__ */
|
|
3333
|
+
model.error ? /* @__PURE__ */ jsxDEV11("p", {
|
|
3051
3334
|
children: model.error
|
|
3052
3335
|
}, undefined, false, undefined, this) : null
|
|
3053
3336
|
]
|
|
3054
3337
|
}, undefined, true, undefined, this);
|
|
3055
3338
|
}
|
|
3056
3339
|
// src/react/useVoiceTurnLatency.tsx
|
|
3057
|
-
import { useEffect as
|
|
3340
|
+
import { useEffect as useEffect12, useRef as useRef12, useSyncExternalStore as useSyncExternalStore12 } from "react";
|
|
3058
3341
|
|
|
3059
3342
|
// src/client/turnLatency.ts
|
|
3060
3343
|
var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
|
|
@@ -3161,27 +3444,27 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
|
|
|
3161
3444
|
|
|
3162
3445
|
// src/react/useVoiceTurnLatency.tsx
|
|
3163
3446
|
var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
|
|
3164
|
-
const storeRef =
|
|
3447
|
+
const storeRef = useRef12(null);
|
|
3165
3448
|
if (!storeRef.current) {
|
|
3166
3449
|
storeRef.current = createVoiceTurnLatencyStore(path, options);
|
|
3167
3450
|
}
|
|
3168
3451
|
const store = storeRef.current;
|
|
3169
|
-
|
|
3452
|
+
useEffect12(() => {
|
|
3170
3453
|
store.refresh().catch(() => {});
|
|
3171
3454
|
return () => store.close();
|
|
3172
3455
|
}, [store]);
|
|
3173
3456
|
return {
|
|
3174
|
-
...
|
|
3457
|
+
...useSyncExternalStore12(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
3175
3458
|
refresh: store.refresh,
|
|
3176
3459
|
runProof: store.runProof
|
|
3177
3460
|
};
|
|
3178
3461
|
};
|
|
3179
3462
|
|
|
3180
3463
|
// src/client/turnLatencyWidget.ts
|
|
3181
|
-
var
|
|
3182
|
-
var
|
|
3464
|
+
var DEFAULT_TITLE11 = "Turn Latency";
|
|
3465
|
+
var DEFAULT_DESCRIPTION11 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
3183
3466
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
3184
|
-
var
|
|
3467
|
+
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3185
3468
|
var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
3186
3469
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
3187
3470
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -3195,39 +3478,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
3195
3478
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
3196
3479
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
3197
3480
|
return {
|
|
3198
|
-
description: options.description ??
|
|
3481
|
+
description: options.description ?? DEFAULT_DESCRIPTION11,
|
|
3199
3482
|
error: snapshot.error,
|
|
3200
3483
|
isLoading: snapshot.isLoading,
|
|
3201
3484
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
3202
3485
|
proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
|
|
3203
3486
|
showProofAction: Boolean(options.proofPath),
|
|
3204
3487
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
3205
|
-
title: options.title ??
|
|
3488
|
+
title: options.title ?? DEFAULT_TITLE11,
|
|
3206
3489
|
turns,
|
|
3207
3490
|
updatedAt: snapshot.updatedAt
|
|
3208
3491
|
};
|
|
3209
3492
|
};
|
|
3210
3493
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
3211
3494
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
3212
|
-
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--${
|
|
3495
|
+
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--${escapeHtml12(turn.status)}">
|
|
3213
3496
|
<header>
|
|
3214
|
-
<strong>${
|
|
3215
|
-
<span>${
|
|
3497
|
+
<strong>${escapeHtml12(turn.label)}</strong>
|
|
3498
|
+
<span>${escapeHtml12(turn.status)}</span>
|
|
3216
3499
|
</header>
|
|
3217
3500
|
<dl>${turn.rows.map((row) => `<div>
|
|
3218
|
-
<dt>${
|
|
3219
|
-
<dd>${
|
|
3501
|
+
<dt>${escapeHtml12(row.label)}</dt>
|
|
3502
|
+
<dd>${escapeHtml12(row.value)}</dd>
|
|
3220
3503
|
</div>`).join("")}</dl>
|
|
3221
3504
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
3222
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
3505
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml12(model.status)}">
|
|
3223
3506
|
<header class="absolute-voice-turn-latency__header">
|
|
3224
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
3225
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
3507
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml12(model.title)}</span>
|
|
3508
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml12(model.label)}</strong>
|
|
3226
3509
|
</header>
|
|
3227
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
3228
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
3510
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml12(model.description)}</p>
|
|
3511
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml12(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
3229
3512
|
${turns}
|
|
3230
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
3513
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml12(model.error)}</p>` : ""}
|
|
3231
3514
|
</section>`;
|
|
3232
3515
|
};
|
|
3233
3516
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -3278,7 +3561,7 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
3278
3561
|
};
|
|
3279
3562
|
|
|
3280
3563
|
// src/react/VoiceTurnLatency.tsx
|
|
3281
|
-
import { jsxDEV as
|
|
3564
|
+
import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
|
|
3282
3565
|
var VoiceTurnLatency = ({
|
|
3283
3566
|
className,
|
|
3284
3567
|
path = "/api/turn-latency",
|
|
@@ -3286,31 +3569,31 @@ var VoiceTurnLatency = ({
|
|
|
3286
3569
|
}) => {
|
|
3287
3570
|
const latency = useVoiceTurnLatency(path, options);
|
|
3288
3571
|
const model = createVoiceTurnLatencyViewModel(latency, options);
|
|
3289
|
-
return /* @__PURE__ */
|
|
3572
|
+
return /* @__PURE__ */ jsxDEV12("section", {
|
|
3290
3573
|
className: [
|
|
3291
3574
|
"absolute-voice-turn-latency",
|
|
3292
3575
|
`absolute-voice-turn-latency--${model.status}`,
|
|
3293
3576
|
className
|
|
3294
3577
|
].filter(Boolean).join(" "),
|
|
3295
3578
|
children: [
|
|
3296
|
-
/* @__PURE__ */
|
|
3579
|
+
/* @__PURE__ */ jsxDEV12("header", {
|
|
3297
3580
|
className: "absolute-voice-turn-latency__header",
|
|
3298
3581
|
children: [
|
|
3299
|
-
/* @__PURE__ */
|
|
3582
|
+
/* @__PURE__ */ jsxDEV12("span", {
|
|
3300
3583
|
className: "absolute-voice-turn-latency__eyebrow",
|
|
3301
3584
|
children: model.title
|
|
3302
3585
|
}, undefined, false, undefined, this),
|
|
3303
|
-
/* @__PURE__ */
|
|
3586
|
+
/* @__PURE__ */ jsxDEV12("strong", {
|
|
3304
3587
|
className: "absolute-voice-turn-latency__label",
|
|
3305
3588
|
children: model.label
|
|
3306
3589
|
}, undefined, false, undefined, this)
|
|
3307
3590
|
]
|
|
3308
3591
|
}, undefined, true, undefined, this),
|
|
3309
|
-
/* @__PURE__ */
|
|
3592
|
+
/* @__PURE__ */ jsxDEV12("p", {
|
|
3310
3593
|
className: "absolute-voice-turn-latency__description",
|
|
3311
3594
|
children: model.description
|
|
3312
3595
|
}, undefined, false, undefined, this),
|
|
3313
|
-
model.showProofAction ? /* @__PURE__ */
|
|
3596
|
+
model.showProofAction ? /* @__PURE__ */ jsxDEV12("button", {
|
|
3314
3597
|
className: "absolute-voice-turn-latency__proof",
|
|
3315
3598
|
onClick: () => {
|
|
3316
3599
|
latency.runProof().catch(() => {});
|
|
@@ -3318,31 +3601,31 @@ var VoiceTurnLatency = ({
|
|
|
3318
3601
|
type: "button",
|
|
3319
3602
|
children: model.proofLabel
|
|
3320
3603
|
}, undefined, false, undefined, this) : null,
|
|
3321
|
-
model.turns.length ? /* @__PURE__ */
|
|
3604
|
+
model.turns.length ? /* @__PURE__ */ jsxDEV12("div", {
|
|
3322
3605
|
className: "absolute-voice-turn-latency__turns",
|
|
3323
|
-
children: model.turns.map((turn) => /* @__PURE__ */
|
|
3606
|
+
children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV12("article", {
|
|
3324
3607
|
className: [
|
|
3325
3608
|
"absolute-voice-turn-latency__turn",
|
|
3326
3609
|
`absolute-voice-turn-latency__turn--${turn.status}`
|
|
3327
3610
|
].join(" "),
|
|
3328
3611
|
children: [
|
|
3329
|
-
/* @__PURE__ */
|
|
3612
|
+
/* @__PURE__ */ jsxDEV12("header", {
|
|
3330
3613
|
children: [
|
|
3331
|
-
/* @__PURE__ */
|
|
3614
|
+
/* @__PURE__ */ jsxDEV12("strong", {
|
|
3332
3615
|
children: turn.label
|
|
3333
3616
|
}, undefined, false, undefined, this),
|
|
3334
|
-
/* @__PURE__ */
|
|
3617
|
+
/* @__PURE__ */ jsxDEV12("span", {
|
|
3335
3618
|
children: turn.status
|
|
3336
3619
|
}, undefined, false, undefined, this)
|
|
3337
3620
|
]
|
|
3338
3621
|
}, undefined, true, undefined, this),
|
|
3339
|
-
/* @__PURE__ */
|
|
3340
|
-
children: turn.rows.map((row) => /* @__PURE__ */
|
|
3622
|
+
/* @__PURE__ */ jsxDEV12("dl", {
|
|
3623
|
+
children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV12("div", {
|
|
3341
3624
|
children: [
|
|
3342
|
-
/* @__PURE__ */
|
|
3625
|
+
/* @__PURE__ */ jsxDEV12("dt", {
|
|
3343
3626
|
children: row.label
|
|
3344
3627
|
}, undefined, false, undefined, this),
|
|
3345
|
-
/* @__PURE__ */
|
|
3628
|
+
/* @__PURE__ */ jsxDEV12("dd", {
|
|
3346
3629
|
children: row.value
|
|
3347
3630
|
}, undefined, false, undefined, this)
|
|
3348
3631
|
]
|
|
@@ -3350,11 +3633,11 @@ var VoiceTurnLatency = ({
|
|
|
3350
3633
|
}, undefined, false, undefined, this)
|
|
3351
3634
|
]
|
|
3352
3635
|
}, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
|
|
3353
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
3636
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV12("p", {
|
|
3354
3637
|
className: "absolute-voice-turn-latency__empty",
|
|
3355
3638
|
children: "Complete a voice turn to see latency diagnostics."
|
|
3356
3639
|
}, undefined, false, undefined, this),
|
|
3357
|
-
model.error ? /* @__PURE__ */
|
|
3640
|
+
model.error ? /* @__PURE__ */ jsxDEV12("p", {
|
|
3358
3641
|
className: "absolute-voice-turn-latency__error",
|
|
3359
3642
|
children: model.error
|
|
3360
3643
|
}, undefined, false, undefined, this) : null
|
|
@@ -3362,7 +3645,7 @@ var VoiceTurnLatency = ({
|
|
|
3362
3645
|
}, undefined, true, undefined, this);
|
|
3363
3646
|
};
|
|
3364
3647
|
// src/react/useVoiceTurnQuality.tsx
|
|
3365
|
-
import { useEffect as
|
|
3648
|
+
import { useEffect as useEffect13, useRef as useRef13, useSyncExternalStore as useSyncExternalStore13 } from "react";
|
|
3366
3649
|
|
|
3367
3650
|
// src/client/turnQuality.ts
|
|
3368
3651
|
var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
|
|
@@ -3445,25 +3728,25 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
3445
3728
|
|
|
3446
3729
|
// src/react/useVoiceTurnQuality.tsx
|
|
3447
3730
|
var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
3448
|
-
const storeRef =
|
|
3731
|
+
const storeRef = useRef13(null);
|
|
3449
3732
|
if (!storeRef.current) {
|
|
3450
3733
|
storeRef.current = createVoiceTurnQualityStore(path, options);
|
|
3451
3734
|
}
|
|
3452
3735
|
const store = storeRef.current;
|
|
3453
|
-
|
|
3736
|
+
useEffect13(() => {
|
|
3454
3737
|
store.refresh().catch(() => {});
|
|
3455
3738
|
return () => store.close();
|
|
3456
3739
|
}, [store]);
|
|
3457
3740
|
return {
|
|
3458
|
-
...
|
|
3741
|
+
...useSyncExternalStore13(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
3459
3742
|
refresh: store.refresh
|
|
3460
3743
|
};
|
|
3461
3744
|
};
|
|
3462
3745
|
|
|
3463
3746
|
// src/client/turnQualityWidget.ts
|
|
3464
|
-
var
|
|
3465
|
-
var
|
|
3466
|
-
var
|
|
3747
|
+
var DEFAULT_TITLE12 = "Turn Quality";
|
|
3748
|
+
var DEFAULT_DESCRIPTION12 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
3749
|
+
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3467
3750
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
3468
3751
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
3469
3752
|
var getTurnDetail = (turn) => {
|
|
@@ -3501,37 +3784,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
3501
3784
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
3502
3785
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
3503
3786
|
return {
|
|
3504
|
-
description: options.description ??
|
|
3787
|
+
description: options.description ?? DEFAULT_DESCRIPTION12,
|
|
3505
3788
|
error: snapshot.error,
|
|
3506
3789
|
isLoading: snapshot.isLoading,
|
|
3507
3790
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
3508
3791
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
3509
|
-
title: options.title ??
|
|
3792
|
+
title: options.title ?? DEFAULT_TITLE12,
|
|
3510
3793
|
turns,
|
|
3511
3794
|
updatedAt: snapshot.updatedAt
|
|
3512
3795
|
};
|
|
3513
3796
|
};
|
|
3514
3797
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
3515
3798
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
3516
|
-
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--${
|
|
3799
|
+
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--${escapeHtml13(turn.status)}">
|
|
3517
3800
|
<header>
|
|
3518
|
-
<strong>${
|
|
3519
|
-
<span>${
|
|
3801
|
+
<strong>${escapeHtml13(turn.label)}</strong>
|
|
3802
|
+
<span>${escapeHtml13(turn.status)}</span>
|
|
3520
3803
|
</header>
|
|
3521
|
-
<p>${
|
|
3804
|
+
<p>${escapeHtml13(turn.detail)}</p>
|
|
3522
3805
|
<dl>${turn.rows.map((row) => `<div>
|
|
3523
|
-
<dt>${
|
|
3524
|
-
<dd>${
|
|
3806
|
+
<dt>${escapeHtml13(row.label)}</dt>
|
|
3807
|
+
<dd>${escapeHtml13(row.value)}</dd>
|
|
3525
3808
|
</div>`).join("")}</dl>
|
|
3526
3809
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
3527
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
3810
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml13(model.status)}">
|
|
3528
3811
|
<header class="absolute-voice-turn-quality__header">
|
|
3529
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
3530
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
3812
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml13(model.title)}</span>
|
|
3813
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml13(model.label)}</strong>
|
|
3531
3814
|
</header>
|
|
3532
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
3815
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml13(model.description)}</p>
|
|
3533
3816
|
${turns}
|
|
3534
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
3817
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml13(model.error)}</p>` : ""}
|
|
3535
3818
|
</section>`;
|
|
3536
3819
|
};
|
|
3537
3820
|
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}`;
|
|
@@ -3573,7 +3856,7 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
3573
3856
|
};
|
|
3574
3857
|
|
|
3575
3858
|
// src/react/VoiceTurnQuality.tsx
|
|
3576
|
-
import { jsxDEV as
|
|
3859
|
+
import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
|
|
3577
3860
|
var VoiceTurnQuality = ({
|
|
3578
3861
|
className,
|
|
3579
3862
|
path = "/api/turn-quality",
|
|
@@ -3581,58 +3864,58 @@ var VoiceTurnQuality = ({
|
|
|
3581
3864
|
}) => {
|
|
3582
3865
|
const snapshot = useVoiceTurnQuality(path, options);
|
|
3583
3866
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
3584
|
-
return /* @__PURE__ */
|
|
3867
|
+
return /* @__PURE__ */ jsxDEV13("section", {
|
|
3585
3868
|
className: [
|
|
3586
3869
|
"absolute-voice-turn-quality",
|
|
3587
3870
|
`absolute-voice-turn-quality--${model.status}`,
|
|
3588
3871
|
className
|
|
3589
3872
|
].filter(Boolean).join(" "),
|
|
3590
3873
|
children: [
|
|
3591
|
-
/* @__PURE__ */
|
|
3874
|
+
/* @__PURE__ */ jsxDEV13("header", {
|
|
3592
3875
|
className: "absolute-voice-turn-quality__header",
|
|
3593
3876
|
children: [
|
|
3594
|
-
/* @__PURE__ */
|
|
3877
|
+
/* @__PURE__ */ jsxDEV13("span", {
|
|
3595
3878
|
className: "absolute-voice-turn-quality__eyebrow",
|
|
3596
3879
|
children: model.title
|
|
3597
3880
|
}, undefined, false, undefined, this),
|
|
3598
|
-
/* @__PURE__ */
|
|
3881
|
+
/* @__PURE__ */ jsxDEV13("strong", {
|
|
3599
3882
|
className: "absolute-voice-turn-quality__label",
|
|
3600
3883
|
children: model.label
|
|
3601
3884
|
}, undefined, false, undefined, this)
|
|
3602
3885
|
]
|
|
3603
3886
|
}, undefined, true, undefined, this),
|
|
3604
|
-
/* @__PURE__ */
|
|
3887
|
+
/* @__PURE__ */ jsxDEV13("p", {
|
|
3605
3888
|
className: "absolute-voice-turn-quality__description",
|
|
3606
3889
|
children: model.description
|
|
3607
3890
|
}, undefined, false, undefined, this),
|
|
3608
|
-
model.turns.length ? /* @__PURE__ */
|
|
3891
|
+
model.turns.length ? /* @__PURE__ */ jsxDEV13("div", {
|
|
3609
3892
|
className: "absolute-voice-turn-quality__turns",
|
|
3610
|
-
children: model.turns.map((turn) => /* @__PURE__ */
|
|
3893
|
+
children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV13("article", {
|
|
3611
3894
|
className: [
|
|
3612
3895
|
"absolute-voice-turn-quality__turn",
|
|
3613
3896
|
`absolute-voice-turn-quality__turn--${turn.status}`
|
|
3614
3897
|
].join(" "),
|
|
3615
3898
|
children: [
|
|
3616
|
-
/* @__PURE__ */
|
|
3899
|
+
/* @__PURE__ */ jsxDEV13("header", {
|
|
3617
3900
|
children: [
|
|
3618
|
-
/* @__PURE__ */
|
|
3901
|
+
/* @__PURE__ */ jsxDEV13("strong", {
|
|
3619
3902
|
children: turn.label
|
|
3620
3903
|
}, undefined, false, undefined, this),
|
|
3621
|
-
/* @__PURE__ */
|
|
3904
|
+
/* @__PURE__ */ jsxDEV13("span", {
|
|
3622
3905
|
children: turn.status
|
|
3623
3906
|
}, undefined, false, undefined, this)
|
|
3624
3907
|
]
|
|
3625
3908
|
}, undefined, true, undefined, this),
|
|
3626
|
-
/* @__PURE__ */
|
|
3909
|
+
/* @__PURE__ */ jsxDEV13("p", {
|
|
3627
3910
|
children: turn.detail
|
|
3628
3911
|
}, undefined, false, undefined, this),
|
|
3629
|
-
/* @__PURE__ */
|
|
3630
|
-
children: turn.rows.map((row) => /* @__PURE__ */
|
|
3912
|
+
/* @__PURE__ */ jsxDEV13("dl", {
|
|
3913
|
+
children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV13("div", {
|
|
3631
3914
|
children: [
|
|
3632
|
-
/* @__PURE__ */
|
|
3915
|
+
/* @__PURE__ */ jsxDEV13("dt", {
|
|
3633
3916
|
children: row.label
|
|
3634
3917
|
}, undefined, false, undefined, this),
|
|
3635
|
-
/* @__PURE__ */
|
|
3918
|
+
/* @__PURE__ */ jsxDEV13("dd", {
|
|
3636
3919
|
children: row.value
|
|
3637
3920
|
}, undefined, false, undefined, this)
|
|
3638
3921
|
]
|
|
@@ -3640,115 +3923,17 @@ var VoiceTurnQuality = ({
|
|
|
3640
3923
|
}, undefined, false, undefined, this)
|
|
3641
3924
|
]
|
|
3642
3925
|
}, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
|
|
3643
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
3926
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV13("p", {
|
|
3644
3927
|
className: "absolute-voice-turn-quality__empty",
|
|
3645
3928
|
children: "Complete a voice turn to see STT quality diagnostics."
|
|
3646
3929
|
}, undefined, false, undefined, this),
|
|
3647
|
-
model.error ? /* @__PURE__ */
|
|
3930
|
+
model.error ? /* @__PURE__ */ jsxDEV13("p", {
|
|
3648
3931
|
className: "absolute-voice-turn-quality__error",
|
|
3649
3932
|
children: model.error
|
|
3650
3933
|
}, undefined, false, undefined, this) : null
|
|
3651
3934
|
]
|
|
3652
3935
|
}, undefined, true, undefined, this);
|
|
3653
3936
|
};
|
|
3654
|
-
// src/react/useVoicePlatformCoverage.tsx
|
|
3655
|
-
import { useEffect as useEffect13, useRef as useRef13, useSyncExternalStore as useSyncExternalStore13 } from "react";
|
|
3656
|
-
|
|
3657
|
-
// src/client/platformCoverage.ts
|
|
3658
|
-
var fetchVoicePlatformCoverage = async (path = "/api/voice/platform-coverage", options = {}) => {
|
|
3659
|
-
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
3660
|
-
const response = await fetchImpl(path);
|
|
3661
|
-
if (!response.ok) {
|
|
3662
|
-
throw new Error(`Voice platform coverage failed: HTTP ${response.status}`);
|
|
3663
|
-
}
|
|
3664
|
-
return await response.json();
|
|
3665
|
-
};
|
|
3666
|
-
var createVoicePlatformCoverageStore = (path = "/api/voice/platform-coverage", options = {}) => {
|
|
3667
|
-
const listeners = new Set;
|
|
3668
|
-
let closed = false;
|
|
3669
|
-
let timer;
|
|
3670
|
-
let snapshot = {
|
|
3671
|
-
error: null,
|
|
3672
|
-
isLoading: false
|
|
3673
|
-
};
|
|
3674
|
-
const emit = () => {
|
|
3675
|
-
for (const listener of listeners) {
|
|
3676
|
-
listener();
|
|
3677
|
-
}
|
|
3678
|
-
};
|
|
3679
|
-
const refresh = async () => {
|
|
3680
|
-
if (closed) {
|
|
3681
|
-
return snapshot.report;
|
|
3682
|
-
}
|
|
3683
|
-
snapshot = {
|
|
3684
|
-
...snapshot,
|
|
3685
|
-
error: null,
|
|
3686
|
-
isLoading: true
|
|
3687
|
-
};
|
|
3688
|
-
emit();
|
|
3689
|
-
try {
|
|
3690
|
-
const report = await fetchVoicePlatformCoverage(path, options);
|
|
3691
|
-
snapshot = {
|
|
3692
|
-
error: null,
|
|
3693
|
-
isLoading: false,
|
|
3694
|
-
report,
|
|
3695
|
-
updatedAt: Date.now()
|
|
3696
|
-
};
|
|
3697
|
-
emit();
|
|
3698
|
-
return report;
|
|
3699
|
-
} catch (error) {
|
|
3700
|
-
snapshot = {
|
|
3701
|
-
...snapshot,
|
|
3702
|
-
error: error instanceof Error ? error.message : String(error),
|
|
3703
|
-
isLoading: false
|
|
3704
|
-
};
|
|
3705
|
-
emit();
|
|
3706
|
-
throw error;
|
|
3707
|
-
}
|
|
3708
|
-
};
|
|
3709
|
-
const close = () => {
|
|
3710
|
-
closed = true;
|
|
3711
|
-
if (timer) {
|
|
3712
|
-
clearInterval(timer);
|
|
3713
|
-
timer = undefined;
|
|
3714
|
-
}
|
|
3715
|
-
listeners.clear();
|
|
3716
|
-
};
|
|
3717
|
-
if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
|
|
3718
|
-
timer = setInterval(() => {
|
|
3719
|
-
refresh().catch(() => {});
|
|
3720
|
-
}, options.intervalMs);
|
|
3721
|
-
}
|
|
3722
|
-
return {
|
|
3723
|
-
close,
|
|
3724
|
-
getServerSnapshot: () => snapshot,
|
|
3725
|
-
getSnapshot: () => snapshot,
|
|
3726
|
-
refresh,
|
|
3727
|
-
subscribe: (listener) => {
|
|
3728
|
-
listeners.add(listener);
|
|
3729
|
-
return () => {
|
|
3730
|
-
listeners.delete(listener);
|
|
3731
|
-
};
|
|
3732
|
-
}
|
|
3733
|
-
};
|
|
3734
|
-
};
|
|
3735
|
-
|
|
3736
|
-
// src/react/useVoicePlatformCoverage.tsx
|
|
3737
|
-
var useVoicePlatformCoverage = (path = "/api/voice/platform-coverage", options = {}) => {
|
|
3738
|
-
const storeRef = useRef13(null);
|
|
3739
|
-
if (!storeRef.current) {
|
|
3740
|
-
storeRef.current = createVoicePlatformCoverageStore(path, options);
|
|
3741
|
-
}
|
|
3742
|
-
const store = storeRef.current;
|
|
3743
|
-
useEffect13(() => {
|
|
3744
|
-
store.refresh().catch(() => {});
|
|
3745
|
-
return () => store.close();
|
|
3746
|
-
}, [store]);
|
|
3747
|
-
return {
|
|
3748
|
-
...useSyncExternalStore13(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
3749
|
-
refresh: store.refresh
|
|
3750
|
-
};
|
|
3751
|
-
};
|
|
3752
3937
|
// src/react/useVoiceLiveOps.tsx
|
|
3753
3938
|
import { useEffect as useEffect14, useRef as useRef14, useSyncExternalStore as useSyncExternalStore14 } from "react";
|
|
3754
3939
|
|
|
@@ -5473,6 +5658,7 @@ export {
|
|
|
5473
5658
|
VoiceProviderSimulationControls,
|
|
5474
5659
|
VoiceProviderContracts,
|
|
5475
5660
|
VoiceProviderCapabilities,
|
|
5661
|
+
VoicePlatformCoverage,
|
|
5476
5662
|
VoiceOpsStatus,
|
|
5477
5663
|
VoiceOpsActionCenter,
|
|
5478
5664
|
VoiceDeliveryRuntime,
|