@absolutejs/voice 0.0.22-beta.459 → 0.0.22-beta.460

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/vue/index.js CHANGED
@@ -7125,8 +7125,226 @@ var VoiceSessionSnapshot = defineComponent8({
7125
7125
  ]);
7126
7126
  }
7127
7127
  });
7128
+ // src/vue/VoiceSessionObservability.ts
7129
+ import { defineComponent as defineComponent9, h as h9, onBeforeUnmount, ref as ref7 } from "vue";
7130
+
7131
+ // src/client/sessionObservability.ts
7132
+ var fetchVoiceSessionObservability = async (path, options = {}) => {
7133
+ const fetchImpl = options.fetch ?? globalThis.fetch;
7134
+ const response = await fetchImpl(path);
7135
+ if (!response.ok) {
7136
+ throw new Error(`Voice session observability failed: HTTP ${response.status}`);
7137
+ }
7138
+ return await response.json();
7139
+ };
7140
+ var createVoiceSessionObservabilityStore = (path, options = {}) => {
7141
+ const listeners = new Set;
7142
+ let closed = false;
7143
+ let timer;
7144
+ let snapshot = {
7145
+ error: null,
7146
+ isLoading: false,
7147
+ report: null
7148
+ };
7149
+ const emit = () => {
7150
+ for (const listener of listeners) {
7151
+ listener();
7152
+ }
7153
+ };
7154
+ const refresh = async () => {
7155
+ if (closed) {
7156
+ return snapshot.report;
7157
+ }
7158
+ snapshot = {
7159
+ ...snapshot,
7160
+ error: null,
7161
+ isLoading: true
7162
+ };
7163
+ emit();
7164
+ try {
7165
+ const report = await fetchVoiceSessionObservability(path, options);
7166
+ snapshot = {
7167
+ error: null,
7168
+ isLoading: false,
7169
+ report,
7170
+ updatedAt: Date.now()
7171
+ };
7172
+ emit();
7173
+ return report;
7174
+ } catch (error) {
7175
+ snapshot = {
7176
+ ...snapshot,
7177
+ error: error instanceof Error ? error.message : String(error),
7178
+ isLoading: false
7179
+ };
7180
+ emit();
7181
+ throw error;
7182
+ }
7183
+ };
7184
+ const close = () => {
7185
+ closed = true;
7186
+ if (timer) {
7187
+ clearInterval(timer);
7188
+ timer = undefined;
7189
+ }
7190
+ listeners.clear();
7191
+ };
7192
+ if (options.intervalMs && options.intervalMs > 0) {
7193
+ timer = setInterval(() => {
7194
+ refresh().catch(() => {});
7195
+ }, options.intervalMs);
7196
+ }
7197
+ return {
7198
+ close,
7199
+ getServerSnapshot: () => snapshot,
7200
+ getSnapshot: () => snapshot,
7201
+ refresh,
7202
+ subscribe: (listener) => {
7203
+ listeners.add(listener);
7204
+ return () => {
7205
+ listeners.delete(listener);
7206
+ };
7207
+ }
7208
+ };
7209
+ };
7210
+
7211
+ // src/client/sessionObservabilityWidget.ts
7212
+ var DEFAULT_TITLE9 = "Session Observability";
7213
+ var DEFAULT_DESCRIPTION9 = "One support/debug report for a voice call across traces, provider recovery, tools, handoffs, guardrails, turn waterfalls, and incident handoff.";
7214
+ var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7215
+ var formatMs3 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
7216
+ var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
7217
+ const report = snapshot.report;
7218
+ const turns = (report?.turns ?? []).slice(0, options.maxTurns ?? 3).map((turn) => ({
7219
+ ...turn,
7220
+ durationLabel: formatMs3(turn.durationMs),
7221
+ label: `${turn.transcripts} transcripts / ${turn.toolCalls} tools / ${turn.providerDecisions} provider decisions`
7222
+ }));
7223
+ return {
7224
+ description: options.description ?? DEFAULT_DESCRIPTION9,
7225
+ error: snapshot.error,
7226
+ isLoading: snapshot.isLoading,
7227
+ label: snapshot.error ? "Unavailable" : report ? `${report.summary.turns} turns / ${report.summary.fallbacks} fallbacks / ${report.summary.errors} errors` : snapshot.isLoading ? "Checking" : "No session loaded",
7228
+ links: report?.links ?? [],
7229
+ sessionId: report?.sessionId,
7230
+ status: snapshot.error ? "error" : report?.status === "failed" ? "failed" : report?.status === "warning" ? "warning" : report ? "ready" : snapshot.isLoading ? "loading" : "empty",
7231
+ title: options.title ?? DEFAULT_TITLE9,
7232
+ turns,
7233
+ updatedAt: snapshot.updatedAt
7234
+ };
7235
+ };
7236
+ var renderLinks = (links) => links.length ? `<p class="absolute-voice-session-observability__actions">${links.map((link) => `<a href="${escapeHtml14(link.href)}">${escapeHtml14(link.label)}</a>`).join("")}</p>` : "";
7237
+ var renderVoiceSessionObservabilityHTML = (snapshot, options = {}) => {
7238
+ const model = createVoiceSessionObservabilityViewModel(snapshot, options);
7239
+ const turns = model.turns.length ? `<div class="absolute-voice-session-observability__turns">${model.turns.map((turn) => `<article class="absolute-voice-session-observability__turn"><header><strong>${escapeHtml14(turn.turnId)}</strong><span>${escapeHtml14(turn.durationLabel)}</span></header><p>${escapeHtml14(turn.label)}</p></article>`).join("")}</div>` : '<p class="absolute-voice-session-observability__empty">Open a voice session to see turn waterfalls.</p>';
7240
+ return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${escapeHtml14(model.status)}">
7241
+ <header class="absolute-voice-session-observability__header">
7242
+ <span class="absolute-voice-session-observability__eyebrow">${escapeHtml14(model.title)}</span>
7243
+ <strong class="absolute-voice-session-observability__label">${escapeHtml14(model.label)}</strong>
7244
+ </header>
7245
+ <p class="absolute-voice-session-observability__description">${escapeHtml14(model.description)}</p>
7246
+ ${model.sessionId ? `<p class="absolute-voice-session-observability__session">${escapeHtml14(model.sessionId)}</p>` : ""}
7247
+ ${renderLinks(model.links)}
7248
+ ${turns}
7249
+ ${model.error ? `<p class="absolute-voice-session-observability__error">${escapeHtml14(model.error)}</p>` : ""}
7250
+ </section>`;
7251
+ };
7252
+ var getVoiceSessionObservabilityCSS = () => `.absolute-voice-session-observability{border:1px solid #c8d9bf;border-radius:20px;background:#fbfff3;color:#18220d;padding:18px;box-shadow:0 18px 40px rgba(24,34,13,.12);font-family:inherit}.absolute-voice-session-observability--error,.absolute-voice-session-observability--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-session-observability--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-session-observability__header,.absolute-voice-session-observability__turn header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-session-observability__eyebrow{color:#4d7c0f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-session-observability__label{font-size:24px;line-height:1}.absolute-voice-session-observability__description,.absolute-voice-session-observability__turn p,.absolute-voice-session-observability__empty,.absolute-voice-session-observability__session{color:#4b5f3e}.absolute-voice-session-observability__actions{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0}.absolute-voice-session-observability__actions a{color:#3f6212;font-weight:800}.absolute-voice-session-observability__turns{display:grid;gap:12px;margin-top:14px}.absolute-voice-session-observability__turn{background:#fff;border:1px solid #dcebcf;border-radius:16px;padding:14px}.absolute-voice-session-observability__turn p{margin:10px 0 0}.absolute-voice-session-observability__empty{margin:14px 0 0}.absolute-voice-session-observability__error{color:#9f1239;font-weight:700}`;
7253
+ var mountVoiceSessionObservability = (element, path, options = {}) => {
7254
+ const store = createVoiceSessionObservabilityStore(path, options);
7255
+ const render = () => {
7256
+ element.innerHTML = renderVoiceSessionObservabilityHTML(store.getSnapshot(), options);
7257
+ };
7258
+ const unsubscribe = store.subscribe(render);
7259
+ render();
7260
+ store.refresh().catch(() => {});
7261
+ return {
7262
+ close: () => {
7263
+ unsubscribe();
7264
+ store.close();
7265
+ },
7266
+ refresh: store.refresh
7267
+ };
7268
+ };
7269
+ var defineVoiceSessionObservabilityElement = (tagName = "absolute-voice-session-observability") => {
7270
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
7271
+ return;
7272
+ }
7273
+ customElements.define(tagName, class AbsoluteVoiceSessionObservabilityElement extends HTMLElement {
7274
+ mounted;
7275
+ connectedCallback() {
7276
+ const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
7277
+ const maxTurns = Number(this.getAttribute("max-turns") ?? 3);
7278
+ this.mounted = mountVoiceSessionObservability(this, this.getAttribute("path") ?? "/api/voice/session-observability/latest", {
7279
+ description: this.getAttribute("description") ?? undefined,
7280
+ intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
7281
+ maxTurns: Number.isFinite(maxTurns) ? maxTurns : 3,
7282
+ title: this.getAttribute("title") ?? undefined
7283
+ });
7284
+ }
7285
+ disconnectedCallback() {
7286
+ this.mounted?.close();
7287
+ this.mounted = undefined;
7288
+ }
7289
+ });
7290
+ };
7291
+
7292
+ // src/vue/VoiceSessionObservability.ts
7293
+ var VoiceSessionObservability = defineComponent9({
7294
+ name: "VoiceSessionObservability",
7295
+ props: {
7296
+ description: String,
7297
+ intervalMs: Number,
7298
+ maxTurns: Number,
7299
+ path: {
7300
+ default: "/api/voice/session-observability/latest",
7301
+ type: String
7302
+ },
7303
+ title: String
7304
+ },
7305
+ setup(props) {
7306
+ const options = {
7307
+ description: props.description,
7308
+ intervalMs: props.intervalMs,
7309
+ maxTurns: props.maxTurns,
7310
+ title: props.title
7311
+ };
7312
+ const store = createVoiceSessionObservabilityStore(props.path, options);
7313
+ const model = ref7(createVoiceSessionObservabilityViewModel(store.getSnapshot(), options));
7314
+ const sync = () => {
7315
+ model.value = createVoiceSessionObservabilityViewModel(store.getSnapshot(), options);
7316
+ };
7317
+ const unsubscribe = store.subscribe(sync);
7318
+ store.refresh().catch(() => {});
7319
+ onBeforeUnmount(() => {
7320
+ unsubscribe();
7321
+ store.close();
7322
+ });
7323
+ return () => h9("section", {
7324
+ class: [
7325
+ "absolute-voice-session-observability",
7326
+ `absolute-voice-session-observability--${model.value.status}`
7327
+ ]
7328
+ }, [
7329
+ h9("header", { class: "absolute-voice-session-observability__header" }, [
7330
+ h9("span", { class: "absolute-voice-session-observability__eyebrow" }, model.value.title),
7331
+ h9("strong", { class: "absolute-voice-session-observability__label" }, model.value.label)
7332
+ ]),
7333
+ h9("p", { class: "absolute-voice-session-observability__description" }, model.value.description),
7334
+ model.value.links.length ? h9("p", { class: "absolute-voice-session-observability__actions" }, model.value.links.map((link) => h9("a", { href: link.href }, link.label))) : null,
7335
+ model.value.turns.length ? h9("div", { class: "absolute-voice-session-observability__turns" }, model.value.turns.map((turn) => h9("article", { class: "absolute-voice-session-observability__turn" }, [
7336
+ h9("header", [
7337
+ h9("strong", turn.turnId),
7338
+ h9("span", turn.durationLabel)
7339
+ ]),
7340
+ h9("p", turn.label)
7341
+ ]))) : h9("p", { class: "absolute-voice-session-observability__empty" }, "Open a voice session to see turn waterfalls."),
7342
+ model.value.error ? h9("p", { class: "absolute-voice-session-observability__error" }, model.value.error) : null
7343
+ ]);
7344
+ }
7345
+ });
7128
7346
  // src/vue/VoiceReadinessFailures.ts
7129
- import { defineComponent as defineComponent9, h as h9 } from "vue";
7347
+ import { defineComponent as defineComponent10, h as h10 } from "vue";
7130
7348
 
7131
7349
  // src/client/readinessFailures.ts
7132
7350
  var fetchVoiceReadinessFailures = async (path = "/api/production-readiness", options = {}) => {
@@ -7204,13 +7422,13 @@ var createVoiceReadinessFailuresStore = (path = "/api/production-readiness", opt
7204
7422
  };
7205
7423
 
7206
7424
  // src/client/readinessFailuresWidget.ts
7207
- var DEFAULT_TITLE9 = "Readiness Gate Explanations";
7208
- var DEFAULT_DESCRIPTION9 = "Structured reasons for calibrated production-readiness warnings and failures.";
7425
+ var DEFAULT_TITLE10 = "Readiness Gate Explanations";
7426
+ var DEFAULT_DESCRIPTION10 = "Structured reasons for calibrated production-readiness warnings and failures.";
7209
7427
  var DEFAULT_LINKS4 = [
7210
7428
  { href: "/production-readiness", label: "Readiness page" },
7211
7429
  { href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
7212
7430
  ];
7213
- var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7431
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7214
7432
  var formatExplanationValue = (value, unit) => {
7215
7433
  if (value === undefined || value === null) {
7216
7434
  return "n/a";
@@ -7238,36 +7456,36 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
7238
7456
  const failures = snapshot.report?.checks.map(toFailureView).filter((value) => !!value) ?? [];
7239
7457
  const hasOpenIssues = failures.length > 0;
7240
7458
  return {
7241
- description: options.description ?? DEFAULT_DESCRIPTION9,
7459
+ description: options.description ?? DEFAULT_DESCRIPTION10,
7242
7460
  error: snapshot.error,
7243
7461
  failures,
7244
7462
  isLoading: snapshot.isLoading,
7245
7463
  label: snapshot.error ? "Unavailable" : snapshot.report ? hasOpenIssues ? `${failures.length} calibrated gate issue(s)` : "No calibrated gate issues" : snapshot.isLoading ? "Checking" : "No readiness report",
7246
7464
  links: options.links ?? DEFAULT_LINKS4,
7247
7465
  status: snapshot.error ? "error" : snapshot.report ? hasOpenIssues ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
7248
- title: options.title ?? DEFAULT_TITLE9,
7466
+ title: options.title ?? DEFAULT_TITLE10,
7249
7467
  updatedAt: snapshot.updatedAt
7250
7468
  };
7251
7469
  };
7252
7470
  var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
7253
7471
  const model = createVoiceReadinessFailuresViewModel(snapshot, options);
7254
- const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml14(failure.status)}">
7255
- <span>${escapeHtml14(failure.status.toUpperCase())}</span>
7256
- <strong>${escapeHtml14(failure.label)}</strong>
7257
- <p>Observed ${escapeHtml14(failure.observed)} against ${escapeHtml14(failure.thresholdLabel)} ${escapeHtml14(failure.threshold)}.</p>
7258
- <p>${escapeHtml14(failure.remediation)}</p>
7259
- <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml14(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml14(failure.sourceHref)}">Threshold source</a>` : ""}</p>
7260
- </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml14(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
7261
- const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml14(link.href)}">${escapeHtml14(link.label)}</a>`).join("")}</p>` : "";
7262
- return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml14(model.status)}">
7472
+ const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml15(failure.status)}">
7473
+ <span>${escapeHtml15(failure.status.toUpperCase())}</span>
7474
+ <strong>${escapeHtml15(failure.label)}</strong>
7475
+ <p>Observed ${escapeHtml15(failure.observed)} against ${escapeHtml15(failure.thresholdLabel)} ${escapeHtml15(failure.threshold)}.</p>
7476
+ <p>${escapeHtml15(failure.remediation)}</p>
7477
+ <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml15(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml15(failure.sourceHref)}">Threshold source</a>` : ""}</p>
7478
+ </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml15(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
7479
+ const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml15(link.href)}">${escapeHtml15(link.label)}</a>`).join("")}</p>` : "";
7480
+ return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml15(model.status)}">
7263
7481
  <header class="absolute-voice-readiness-failures__header">
7264
- <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml14(model.title)}</span>
7265
- <strong class="absolute-voice-readiness-failures__label">${escapeHtml14(model.label)}</strong>
7482
+ <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml15(model.title)}</span>
7483
+ <strong class="absolute-voice-readiness-failures__label">${escapeHtml15(model.label)}</strong>
7266
7484
  </header>
7267
- <p class="absolute-voice-readiness-failures__description">${escapeHtml14(model.description)}</p>
7485
+ <p class="absolute-voice-readiness-failures__description">${escapeHtml15(model.description)}</p>
7268
7486
  ${failures}
7269
7487
  ${links}
7270
- ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml14(model.error)}</p>` : ""}
7488
+ ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml15(model.error)}</p>` : ""}
7271
7489
  </section>`;
7272
7490
  };
7273
7491
  var getVoiceReadinessFailuresCSS = () => `.absolute-voice-readiness-failures{border:1px solid #fed7aa;border-radius:20px;background:#fff7ed;color:#1c1917;padding:18px;box-shadow:0 18px 40px rgba(234,88,12,.12);font-family:inherit}.absolute-voice-readiness-failures--ready{border-color:#86efac;background:#f0fdf4}.absolute-voice-readiness-failures--error{border-color:#fda4af;background:#fff1f2}.absolute-voice-readiness-failures__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-readiness-failures__eyebrow{color:#9a3412;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-readiness-failures__label{font-size:24px;line-height:1}.absolute-voice-readiness-failures__description,.absolute-voice-readiness-failures__empty{color:#57534e}.absolute-voice-readiness-failures__items{display:grid;gap:10px;margin-top:14px}.absolute-voice-readiness-failures__item{background:white;border:1px solid #fed7aa;border-radius:16px;padding:12px}.absolute-voice-readiness-failures__item--fail{border-color:#fb7185}.absolute-voice-readiness-failures__item span{color:#9a3412;display:block;font-size:12px;font-weight:900;text-transform:uppercase}.absolute-voice-readiness-failures__item strong{display:block;font-size:18px;margin-top:4px}.absolute-voice-readiness-failures__item p{margin:.45rem 0 0}.absolute-voice-readiness-failures__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-readiness-failures__links a{border:1px solid #fdba74;border-radius:999px;color:#9a3412;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-readiness-failures__error{color:#9f1239;font-weight:700}`;
@@ -7308,13 +7526,13 @@ var defineVoiceReadinessFailuresElement = (tagName = "absolute-voice-readiness-f
7308
7526
  };
7309
7527
 
7310
7528
  // src/vue/useVoiceReadinessFailures.ts
7311
- import { onBeforeUnmount, readonly, ref as ref7 } from "vue";
7529
+ import { onBeforeUnmount as onBeforeUnmount2, readonly, ref as ref8 } from "vue";
7312
7530
  var useVoiceReadinessFailures = (path = "/api/production-readiness", options = {}) => {
7313
7531
  const store = createVoiceReadinessFailuresStore(path, options);
7314
- const error = ref7(null);
7315
- const isLoading = ref7(false);
7316
- const report = ref7(undefined);
7317
- const updatedAt = ref7(undefined);
7532
+ const error = ref8(null);
7533
+ const isLoading = ref8(false);
7534
+ const report = ref8(undefined);
7535
+ const updatedAt = ref8(undefined);
7318
7536
  const sync = () => {
7319
7537
  const snapshot = store.getSnapshot();
7320
7538
  error.value = snapshot.error;
@@ -7327,7 +7545,7 @@ var useVoiceReadinessFailures = (path = "/api/production-readiness", options = {
7327
7545
  if (typeof window !== "undefined") {
7328
7546
  store.refresh().catch(() => {});
7329
7547
  }
7330
- onBeforeUnmount(() => {
7548
+ onBeforeUnmount2(() => {
7331
7549
  unsubscribe();
7332
7550
  store.close();
7333
7551
  });
@@ -7341,7 +7559,7 @@ var useVoiceReadinessFailures = (path = "/api/production-readiness", options = {
7341
7559
  };
7342
7560
 
7343
7561
  // src/vue/VoiceReadinessFailures.ts
7344
- var VoiceReadinessFailures = defineComponent9({
7562
+ var VoiceReadinessFailures = defineComponent10({
7345
7563
  name: "VoiceReadinessFailures",
7346
7564
  props: {
7347
7565
  description: String,
@@ -7369,40 +7587,40 @@ var VoiceReadinessFailures = defineComponent9({
7369
7587
  intervalMs: props.intervalMs,
7370
7588
  title: props.title
7371
7589
  });
7372
- return h9("section", {
7590
+ return h10("section", {
7373
7591
  class: [
7374
7592
  "absolute-voice-readiness-failures",
7375
7593
  `absolute-voice-readiness-failures--${model.status}`
7376
7594
  ]
7377
7595
  }, [
7378
- h9("header", { class: "absolute-voice-readiness-failures__header" }, [
7379
- h9("span", { class: "absolute-voice-readiness-failures__eyebrow" }, model.title),
7380
- h9("strong", { class: "absolute-voice-readiness-failures__label" }, model.label)
7596
+ h10("header", { class: "absolute-voice-readiness-failures__header" }, [
7597
+ h10("span", { class: "absolute-voice-readiness-failures__eyebrow" }, model.title),
7598
+ h10("strong", { class: "absolute-voice-readiness-failures__label" }, model.label)
7381
7599
  ]),
7382
- h9("p", { class: "absolute-voice-readiness-failures__description" }, model.description),
7383
- model.failures.length ? h9("div", { class: "absolute-voice-readiness-failures__items" }, model.failures.map((failure) => h9("article", {
7600
+ h10("p", { class: "absolute-voice-readiness-failures__description" }, model.description),
7601
+ model.failures.length ? h10("div", { class: "absolute-voice-readiness-failures__items" }, model.failures.map((failure) => h10("article", {
7384
7602
  class: [
7385
7603
  "absolute-voice-readiness-failures__item",
7386
7604
  `absolute-voice-readiness-failures__item--${failure.status}`
7387
7605
  ],
7388
7606
  key: failure.label
7389
7607
  }, [
7390
- h9("span", failure.status.toUpperCase()),
7391
- h9("strong", failure.label),
7392
- h9("p", `Observed ${failure.observed} against ${failure.thresholdLabel} ${failure.threshold}.`),
7393
- h9("p", failure.remediation),
7394
- h9("p", { class: "absolute-voice-readiness-failures__links" }, [
7395
- failure.evidenceHref ? h9("a", { href: failure.evidenceHref }, "Evidence") : null,
7396
- failure.sourceHref ? h9("a", { href: failure.sourceHref }, "Threshold source") : null
7608
+ h10("span", failure.status.toUpperCase()),
7609
+ h10("strong", failure.label),
7610
+ h10("p", `Observed ${failure.observed} against ${failure.thresholdLabel} ${failure.threshold}.`),
7611
+ h10("p", failure.remediation),
7612
+ h10("p", { class: "absolute-voice-readiness-failures__links" }, [
7613
+ failure.evidenceHref ? h10("a", { href: failure.evidenceHref }, "Evidence") : null,
7614
+ failure.sourceHref ? h10("a", { href: failure.sourceHref }, "Threshold source") : null
7397
7615
  ])
7398
- ]))) : h9("p", { class: "absolute-voice-readiness-failures__empty" }, model.error ?? "No calibrated readiness gate explanations are open."),
7399
- model.links.length ? h9("p", { class: "absolute-voice-readiness-failures__links" }, model.links.map((link) => h9("a", { href: link.href, key: link.href }, link.label))) : null
7616
+ ]))) : h10("p", { class: "absolute-voice-readiness-failures__empty" }, model.error ?? "No calibrated readiness gate explanations are open."),
7617
+ model.links.length ? h10("p", { class: "absolute-voice-readiness-failures__links" }, model.links.map((link) => h10("a", { href: link.href, key: link.href }, link.label))) : null
7400
7618
  ]);
7401
7619
  };
7402
7620
  }
7403
7621
  });
7404
7622
  // src/vue/VoiceProviderSimulationControls.ts
7405
- import { computed as computed4, defineComponent as defineComponent10, h as h10 } from "vue";
7623
+ import { computed as computed4, defineComponent as defineComponent11, h as h11 } from "vue";
7406
7624
 
7407
7625
  // src/client/providerSimulationControls.ts
7408
7626
  var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
@@ -7484,7 +7702,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
7484
7702
  };
7485
7703
 
7486
7704
  // src/client/providerSimulationControlsWidget.ts
7487
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7705
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7488
7706
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
7489
7707
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
7490
7708
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -7504,18 +7722,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
7504
7722
  };
7505
7723
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
7506
7724
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
7507
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml15(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml15(provider.provider)} ${escapeHtml15(formatKind(options.kind))} failure</button>`).join("");
7508
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml15(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml15(provider.provider)} recovered</button>`).join("");
7725
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml16(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml16(provider.provider)} ${escapeHtml16(formatKind(options.kind))} failure</button>`).join("");
7726
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml16(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml16(provider.provider)} recovered</button>`).join("");
7509
7727
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
7510
7728
  <header class="absolute-voice-provider-simulation__header">
7511
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml15(model.title)}</span>
7512
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml15(model.label)}</strong>
7729
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml16(model.title)}</span>
7730
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml16(model.label)}</strong>
7513
7731
  </header>
7514
- <p class="absolute-voice-provider-simulation__description">${escapeHtml15(model.description)}</p>
7515
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml15(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
7732
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml16(model.description)}</p>
7733
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml16(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
7516
7734
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
7517
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml15(snapshot.error)}</p>` : ""}
7518
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml15(model.resultText)}</pre>` : ""}
7735
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml16(snapshot.error)}</p>` : ""}
7736
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml16(model.resultText)}</pre>` : ""}
7519
7737
  </section>`;
7520
7738
  };
7521
7739
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -7581,15 +7799,15 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
7581
7799
  };
7582
7800
 
7583
7801
  // src/vue/useVoiceProviderSimulationControls.ts
7584
- import { onUnmounted as onUnmounted9, ref as ref8 } from "vue";
7802
+ import { onUnmounted as onUnmounted9, ref as ref9 } from "vue";
7585
7803
  function useVoiceProviderSimulationControls(options) {
7586
7804
  const store = createVoiceProviderSimulationControlsStore(options);
7587
- const error = ref8(null);
7588
- const isRunning = ref8(false);
7589
- const lastResult = ref8(null);
7590
- const mode = ref8(null);
7591
- const provider = ref8(null);
7592
- const updatedAt = ref8(undefined);
7805
+ const error = ref9(null);
7806
+ const isRunning = ref9(false);
7807
+ const lastResult = ref9(null);
7808
+ const mode = ref9(null);
7809
+ const provider = ref9(null);
7810
+ const updatedAt = ref9(undefined);
7593
7811
  const sync = () => {
7594
7812
  const snapshot = store.getSnapshot();
7595
7813
  error.value = snapshot.error;
@@ -7617,7 +7835,7 @@ function useVoiceProviderSimulationControls(options) {
7617
7835
  }
7618
7836
 
7619
7837
  // src/vue/VoiceProviderSimulationControls.ts
7620
- var VoiceProviderSimulationControls = defineComponent10({
7838
+ var VoiceProviderSimulationControls = defineComponent11({
7621
7839
  name: "VoiceProviderSimulationControls",
7622
7840
  props: {
7623
7841
  class: { default: "", type: String },
@@ -7659,40 +7877,40 @@ var VoiceProviderSimulationControls = defineComponent10({
7659
7877
  const run = (provider, mode) => {
7660
7878
  controls.run(provider, mode).catch(() => {});
7661
7879
  };
7662
- return () => h10("section", {
7880
+ return () => h11("section", {
7663
7881
  class: [
7664
7882
  "absolute-voice-provider-simulation",
7665
7883
  `absolute-voice-provider-simulation--${controls.error.value ? "error" : controls.isRunning.value ? "running" : "ready"}`,
7666
7884
  props.class
7667
7885
  ]
7668
7886
  }, [
7669
- h10("header", { class: "absolute-voice-provider-simulation__header" }, [
7670
- h10("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
7671
- h10("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
7887
+ h11("header", { class: "absolute-voice-provider-simulation__header" }, [
7888
+ h11("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
7889
+ h11("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
7672
7890
  ]),
7673
- h10("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
7674
- model.value.canSimulateFailure ? null : h10("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
7675
- h10("div", { class: "absolute-voice-provider-simulation__actions" }, [
7676
- ...model.value.failureProviders.map((provider) => h10("button", {
7891
+ h11("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
7892
+ model.value.canSimulateFailure ? null : h11("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
7893
+ h11("div", { class: "absolute-voice-provider-simulation__actions" }, [
7894
+ ...model.value.failureProviders.map((provider) => h11("button", {
7677
7895
  disabled: !model.value.canSimulateFailure || controls.isRunning.value,
7678
7896
  key: `fail-${provider.provider}`,
7679
7897
  onClick: () => run(provider.provider, "failure"),
7680
7898
  type: "button"
7681
7899
  }, `Simulate ${provider.provider} ${props.kind.toUpperCase()} failure`)),
7682
- ...model.value.providers.map((provider) => h10("button", {
7900
+ ...model.value.providers.map((provider) => h11("button", {
7683
7901
  disabled: controls.isRunning.value,
7684
7902
  key: `recover-${provider.provider}`,
7685
7903
  onClick: () => run(provider.provider, "recovery"),
7686
7904
  type: "button"
7687
7905
  }, `Mark ${provider.provider} recovered`))
7688
7906
  ]),
7689
- controls.error.value ? h10("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
7690
- model.value.resultText ? h10("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
7907
+ controls.error.value ? h11("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
7908
+ model.value.resultText ? h11("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
7691
7909
  ]);
7692
7910
  }
7693
7911
  });
7694
7912
  // src/vue/VoiceProviderCapabilities.ts
7695
- import { computed as computed5, defineComponent as defineComponent11, h as h11 } from "vue";
7913
+ import { computed as computed5, defineComponent as defineComponent12, h as h12 } from "vue";
7696
7914
 
7697
7915
  // src/client/providerCapabilities.ts
7698
7916
  var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
@@ -7774,9 +7992,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
7774
7992
  };
7775
7993
 
7776
7994
  // src/client/providerCapabilitiesWidget.ts
7777
- var DEFAULT_TITLE10 = "Provider Capabilities";
7778
- var DEFAULT_DESCRIPTION10 = "Configured, selected, and healthy voice providers for this deployment.";
7779
- var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7995
+ var DEFAULT_TITLE11 = "Provider Capabilities";
7996
+ var DEFAULT_DESCRIPTION11 = "Configured, selected, and healthy voice providers for this deployment.";
7997
+ var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7780
7998
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
7781
7999
  var formatKind2 = (kind) => kind.toUpperCase();
7782
8000
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -7820,36 +8038,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
7820
8038
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
7821
8039
  return {
7822
8040
  capabilities,
7823
- description: options.description ?? DEFAULT_DESCRIPTION10,
8041
+ description: options.description ?? DEFAULT_DESCRIPTION11,
7824
8042
  error: snapshot.error,
7825
8043
  isLoading: snapshot.isLoading,
7826
8044
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
7827
8045
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
7828
- title: options.title ?? DEFAULT_TITLE10,
8046
+ title: options.title ?? DEFAULT_TITLE11,
7829
8047
  updatedAt: snapshot.updatedAt
7830
8048
  };
7831
8049
  };
7832
8050
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
7833
8051
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
7834
- const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${escapeHtml16(capability.status)}">
8052
+ 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--${escapeHtml17(capability.status)}">
7835
8053
  <header>
7836
- <strong>${escapeHtml16(capability.label)}</strong>
7837
- <span>${escapeHtml16(formatStatus3(capability.status))}</span>
8054
+ <strong>${escapeHtml17(capability.label)}</strong>
8055
+ <span>${escapeHtml17(formatStatus3(capability.status))}</span>
7838
8056
  </header>
7839
- <p>${escapeHtml16(capability.detail)}</p>
8057
+ <p>${escapeHtml17(capability.detail)}</p>
7840
8058
  <dl>${capability.rows.map((row) => `<div>
7841
- <dt>${escapeHtml16(row.label)}</dt>
7842
- <dd>${escapeHtml16(row.value)}</dd>
8059
+ <dt>${escapeHtml17(row.label)}</dt>
8060
+ <dd>${escapeHtml17(row.value)}</dd>
7843
8061
  </div>`).join("")}</dl>
7844
8062
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
7845
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml16(model.status)}">
8063
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml17(model.status)}">
7846
8064
  <header class="absolute-voice-provider-capabilities__header">
7847
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml16(model.title)}</span>
7848
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml16(model.label)}</strong>
8065
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml17(model.title)}</span>
8066
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml17(model.label)}</strong>
7849
8067
  </header>
7850
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml16(model.description)}</p>
8068
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml17(model.description)}</p>
7851
8069
  ${capabilities}
7852
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml16(model.error)}</p>` : ""}
8070
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml17(model.error)}</p>` : ""}
7853
8071
  </section>`;
7854
8072
  };
7855
8073
  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}`;
@@ -7922,7 +8140,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
7922
8140
  }
7923
8141
 
7924
8142
  // src/vue/VoiceProviderCapabilities.ts
7925
- var VoiceProviderCapabilities = defineComponent11({
8143
+ var VoiceProviderCapabilities = defineComponent12({
7926
8144
  name: "VoiceProviderCapabilities",
7927
8145
  props: {
7928
8146
  class: {
@@ -7959,41 +8177,41 @@ var VoiceProviderCapabilities = defineComponent11({
7959
8177
  report: capabilities.report.value,
7960
8178
  updatedAt: capabilities.updatedAt.value
7961
8179
  }, options));
7962
- return () => h11("section", {
8180
+ return () => h12("section", {
7963
8181
  class: [
7964
8182
  "absolute-voice-provider-capabilities",
7965
8183
  `absolute-voice-provider-capabilities--${model.value.status}`,
7966
8184
  props.class
7967
8185
  ]
7968
8186
  }, [
7969
- h11("header", { class: "absolute-voice-provider-capabilities__header" }, [
7970
- h11("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
7971
- h11("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
8187
+ h12("header", { class: "absolute-voice-provider-capabilities__header" }, [
8188
+ h12("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
8189
+ h12("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
7972
8190
  ]),
7973
- h11("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
7974
- model.value.capabilities.length ? h11("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h11("article", {
8191
+ h12("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
8192
+ model.value.capabilities.length ? h12("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h12("article", {
7975
8193
  class: [
7976
8194
  "absolute-voice-provider-capabilities__provider",
7977
8195
  `absolute-voice-provider-capabilities__provider--${capability.status}`
7978
8196
  ],
7979
8197
  key: `${capability.kind}:${capability.provider}`
7980
8198
  }, [
7981
- h11("header", [
7982
- h11("strong", capability.label),
7983
- h11("span", capability.status)
8199
+ h12("header", [
8200
+ h12("strong", capability.label),
8201
+ h12("span", capability.status)
7984
8202
  ]),
7985
- h11("p", capability.detail),
7986
- h11("dl", capability.rows.map((row) => h11("div", { key: row.label }, [
7987
- h11("dt", row.label),
7988
- h11("dd", row.value)
8203
+ h12("p", capability.detail),
8204
+ h12("dl", capability.rows.map((row) => h12("div", { key: row.label }, [
8205
+ h12("dt", row.label),
8206
+ h12("dd", row.value)
7989
8207
  ])))
7990
- ]))) : h11("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
7991
- model.value.error ? h11("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
8208
+ ]))) : h12("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
8209
+ model.value.error ? h12("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
7992
8210
  ]);
7993
8211
  }
7994
8212
  });
7995
8213
  // src/vue/VoiceProviderContracts.ts
7996
- import { defineComponent as defineComponent12, h as h12 } from "vue";
8214
+ import { defineComponent as defineComponent13, h as h13 } from "vue";
7997
8215
 
7998
8216
  // src/vue/useVoiceProviderContracts.ts
7999
8217
  import { onUnmounted as onUnmounted11, shallowRef as shallowRef10 } from "vue";
@@ -8104,9 +8322,9 @@ function useVoiceProviderContracts(path = "/api/provider-contracts", options = {
8104
8322
  }
8105
8323
 
8106
8324
  // src/client/providerContractsWidget.ts
8107
- var DEFAULT_TITLE11 = "Provider Contracts";
8108
- var DEFAULT_DESCRIPTION11 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
8109
- var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8325
+ var DEFAULT_TITLE12 = "Provider Contracts";
8326
+ var DEFAULT_DESCRIPTION12 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
8327
+ var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8110
8328
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
8111
8329
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
8112
8330
  var contractDetail = (row) => {
@@ -8138,38 +8356,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
8138
8356
  }));
8139
8357
  const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
8140
8358
  return {
8141
- description: options.description ?? DEFAULT_DESCRIPTION11,
8359
+ description: options.description ?? DEFAULT_DESCRIPTION12,
8142
8360
  error: snapshot.error,
8143
8361
  isLoading: snapshot.isLoading,
8144
8362
  label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
8145
8363
  rows,
8146
8364
  status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
8147
- title: options.title ?? DEFAULT_TITLE11,
8365
+ title: options.title ?? DEFAULT_TITLE12,
8148
8366
  updatedAt: snapshot.updatedAt
8149
8367
  };
8150
8368
  };
8151
8369
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
8152
8370
  const model = createVoiceProviderContractsViewModel(snapshot, options);
8153
- const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${escapeHtml17(row.status)}">
8371
+ 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--${escapeHtml18(row.status)}">
8154
8372
  <header>
8155
- <strong>${escapeHtml17(row.label)}</strong>
8156
- <span>${escapeHtml17(formatStatus4(row.status))}</span>
8373
+ <strong>${escapeHtml18(row.label)}</strong>
8374
+ <span>${escapeHtml18(formatStatus4(row.status))}</span>
8157
8375
  </header>
8158
- <p>${escapeHtml17(row.detail)}</p>
8159
- ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml17(remediation.href)}">${escapeHtml17(remediation.label)}</a>` : `<strong>${escapeHtml17(remediation.label)}</strong>`}<span>${escapeHtml17(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
8376
+ <p>${escapeHtml18(row.detail)}</p>
8377
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml18(remediation.href)}">${escapeHtml18(remediation.label)}</a>` : `<strong>${escapeHtml18(remediation.label)}</strong>`}<span>${escapeHtml18(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
8160
8378
  <dl>${row.rows.map((item) => `<div>
8161
- <dt>${escapeHtml17(item.label)}</dt>
8162
- <dd>${escapeHtml17(item.value)}</dd>
8379
+ <dt>${escapeHtml18(item.label)}</dt>
8380
+ <dd>${escapeHtml18(item.value)}</dd>
8163
8381
  </div>`).join("")}</dl>
8164
8382
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
8165
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml17(model.status)}">
8383
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml18(model.status)}">
8166
8384
  <header class="absolute-voice-provider-contracts__header">
8167
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml17(model.title)}</span>
8168
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml17(model.label)}</strong>
8385
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml18(model.title)}</span>
8386
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml18(model.label)}</strong>
8169
8387
  </header>
8170
- <p class="absolute-voice-provider-contracts__description">${escapeHtml17(model.description)}</p>
8388
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml18(model.description)}</p>
8171
8389
  ${rows}
8172
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml17(model.error)}</p>` : ""}
8390
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml18(model.error)}</p>` : ""}
8173
8391
  </section>`;
8174
8392
  };
8175
8393
  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}`;
@@ -8211,7 +8429,7 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
8211
8429
  };
8212
8430
 
8213
8431
  // src/vue/VoiceProviderContracts.ts
8214
- var VoiceProviderContracts = defineComponent12({
8432
+ var VoiceProviderContracts = defineComponent13({
8215
8433
  name: "VoiceProviderContracts",
8216
8434
  props: {
8217
8435
  description: String,
@@ -8239,49 +8457,49 @@ var VoiceProviderContracts = defineComponent12({
8239
8457
  intervalMs: props.intervalMs,
8240
8458
  title: props.title
8241
8459
  });
8242
- return h12("section", {
8460
+ return h13("section", {
8243
8461
  class: [
8244
8462
  "absolute-voice-provider-contracts",
8245
8463
  `absolute-voice-provider-contracts--${model.status}`
8246
8464
  ]
8247
8465
  }, [
8248
- h12("header", { class: "absolute-voice-provider-contracts__header" }, [
8249
- h12("span", { class: "absolute-voice-provider-contracts__eyebrow" }, model.title),
8250
- h12("strong", { class: "absolute-voice-provider-contracts__label" }, model.label)
8466
+ h13("header", { class: "absolute-voice-provider-contracts__header" }, [
8467
+ h13("span", { class: "absolute-voice-provider-contracts__eyebrow" }, model.title),
8468
+ h13("strong", { class: "absolute-voice-provider-contracts__label" }, model.label)
8251
8469
  ]),
8252
- h12("p", { class: "absolute-voice-provider-contracts__description" }, model.description),
8253
- model.rows.length ? h12("div", { class: "absolute-voice-provider-contracts__rows" }, model.rows.map((row) => h12("article", {
8470
+ h13("p", { class: "absolute-voice-provider-contracts__description" }, model.description),
8471
+ model.rows.length ? h13("div", { class: "absolute-voice-provider-contracts__rows" }, model.rows.map((row) => h13("article", {
8254
8472
  class: [
8255
8473
  "absolute-voice-provider-contracts__row",
8256
8474
  `absolute-voice-provider-contracts__row--${row.status}`
8257
8475
  ],
8258
8476
  key: `${row.kind}:${row.provider}`
8259
8477
  }, [
8260
- h12("header", [
8261
- h12("strong", row.label),
8262
- h12("span", row.status)
8478
+ h13("header", [
8479
+ h13("strong", row.label),
8480
+ h13("span", row.status)
8263
8481
  ]),
8264
- h12("p", row.detail),
8265
- row.remediations.length ? h12("ul", {
8482
+ h13("p", row.detail),
8483
+ row.remediations.length ? h13("ul", {
8266
8484
  class: "absolute-voice-provider-contracts__remediations"
8267
- }, row.remediations.map((remediation) => h12("li", {
8485
+ }, row.remediations.map((remediation) => h13("li", {
8268
8486
  key: `${row.kind}:${row.provider}:${remediation.label}`
8269
8487
  }, [
8270
- remediation.href ? h12("a", { href: remediation.href }, remediation.label) : h12("strong", remediation.label),
8271
- h12("span", remediation.detail)
8488
+ remediation.href ? h13("a", { href: remediation.href }, remediation.label) : h13("strong", remediation.label),
8489
+ h13("span", remediation.detail)
8272
8490
  ]))) : null,
8273
- h12("dl", row.rows.map((item) => h12("div", { key: item.label }, [
8274
- h12("dt", item.label),
8275
- h12("dd", item.value)
8491
+ h13("dl", row.rows.map((item) => h13("div", { key: item.label }, [
8492
+ h13("dt", item.label),
8493
+ h13("dd", item.value)
8276
8494
  ])))
8277
- ]))) : h12("p", { class: "absolute-voice-provider-contracts__empty" }, "Configure provider contracts to see production coverage."),
8278
- model.error ? h12("p", { class: "absolute-voice-provider-contracts__error" }, model.error) : null
8495
+ ]))) : h13("p", { class: "absolute-voice-provider-contracts__empty" }, "Configure provider contracts to see production coverage."),
8496
+ model.error ? h13("p", { class: "absolute-voice-provider-contracts__error" }, model.error) : null
8279
8497
  ]);
8280
8498
  };
8281
8499
  }
8282
8500
  });
8283
8501
  // src/vue/VoiceProviderStatus.ts
8284
- import { computed as computed6, defineComponent as defineComponent13, h as h13 } from "vue";
8502
+ import { computed as computed6, defineComponent as defineComponent14, h as h14 } from "vue";
8285
8503
 
8286
8504
  // src/client/providerStatus.ts
8287
8505
  var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
@@ -8364,9 +8582,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
8364
8582
  };
8365
8583
 
8366
8584
  // src/client/providerStatusWidget.ts
8367
- var DEFAULT_TITLE12 = "Voice Providers";
8368
- var DEFAULT_DESCRIPTION12 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
8369
- var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8585
+ var DEFAULT_TITLE13 = "Voice Providers";
8586
+ var DEFAULT_DESCRIPTION13 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
8587
+ var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8370
8588
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
8371
8589
  var formatStatus5 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
8372
8590
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -8410,37 +8628,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
8410
8628
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
8411
8629
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
8412
8630
  return {
8413
- description: options.description ?? DEFAULT_DESCRIPTION12,
8631
+ description: options.description ?? DEFAULT_DESCRIPTION13,
8414
8632
  error: snapshot.error,
8415
8633
  isLoading: snapshot.isLoading,
8416
8634
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
8417
8635
  providers,
8418
8636
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
8419
- title: options.title ?? DEFAULT_TITLE12,
8637
+ title: options.title ?? DEFAULT_TITLE13,
8420
8638
  updatedAt: snapshot.updatedAt
8421
8639
  };
8422
8640
  };
8423
8641
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
8424
8642
  const model = createVoiceProviderStatusViewModel(snapshot, options);
8425
- 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--${escapeHtml18(provider.status)}">
8643
+ 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--${escapeHtml19(provider.status)}">
8426
8644
  <header>
8427
- <strong>${escapeHtml18(provider.label)}</strong>
8428
- <span>${escapeHtml18(formatStatus5(provider.status))}</span>
8645
+ <strong>${escapeHtml19(provider.label)}</strong>
8646
+ <span>${escapeHtml19(formatStatus5(provider.status))}</span>
8429
8647
  </header>
8430
- <p>${escapeHtml18(provider.detail)}</p>
8648
+ <p>${escapeHtml19(provider.detail)}</p>
8431
8649
  <dl>${provider.rows.map((row) => `<div>
8432
- <dt>${escapeHtml18(row.label)}</dt>
8433
- <dd>${escapeHtml18(row.value)}</dd>
8650
+ <dt>${escapeHtml19(row.label)}</dt>
8651
+ <dd>${escapeHtml19(row.value)}</dd>
8434
8652
  </div>`).join("")}</dl>
8435
8653
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
8436
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml18(model.status)}">
8654
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml19(model.status)}">
8437
8655
  <header class="absolute-voice-provider-status__header">
8438
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml18(model.title)}</span>
8439
- <strong class="absolute-voice-provider-status__label">${escapeHtml18(model.label)}</strong>
8656
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml19(model.title)}</span>
8657
+ <strong class="absolute-voice-provider-status__label">${escapeHtml19(model.label)}</strong>
8440
8658
  </header>
8441
- <p class="absolute-voice-provider-status__description">${escapeHtml18(model.description)}</p>
8659
+ <p class="absolute-voice-provider-status__description">${escapeHtml19(model.description)}</p>
8442
8660
  ${providers}
8443
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml18(model.error)}</p>` : ""}
8661
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml19(model.error)}</p>` : ""}
8444
8662
  </section>`;
8445
8663
  };
8446
8664
  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}`;
@@ -8482,13 +8700,13 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
8482
8700
  };
8483
8701
 
8484
8702
  // src/vue/useVoiceProviderStatus.ts
8485
- import { onUnmounted as onUnmounted12, ref as ref9, shallowRef as shallowRef11 } from "vue";
8703
+ import { onUnmounted as onUnmounted12, ref as ref10, shallowRef as shallowRef11 } from "vue";
8486
8704
  function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
8487
8705
  const store = createVoiceProviderStatusStore(path, options);
8488
- const error = ref9(null);
8489
- const isLoading = ref9(false);
8706
+ const error = ref10(null);
8707
+ const isLoading = ref10(false);
8490
8708
  const providers = shallowRef11([]);
8491
- const updatedAt = ref9(undefined);
8709
+ const updatedAt = ref10(undefined);
8492
8710
  const sync = () => {
8493
8711
  const snapshot = store.getSnapshot();
8494
8712
  error.value = snapshot.error;
@@ -8513,7 +8731,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
8513
8731
  }
8514
8732
 
8515
8733
  // src/vue/VoiceProviderStatus.ts
8516
- var VoiceProviderStatus = defineComponent13({
8734
+ var VoiceProviderStatus = defineComponent14({
8517
8735
  name: "VoiceProviderStatus",
8518
8736
  props: {
8519
8737
  class: {
@@ -8550,41 +8768,41 @@ var VoiceProviderStatus = defineComponent13({
8550
8768
  providers: status.providers.value,
8551
8769
  updatedAt: status.updatedAt.value
8552
8770
  }, options));
8553
- return () => h13("section", {
8771
+ return () => h14("section", {
8554
8772
  class: [
8555
8773
  "absolute-voice-provider-status",
8556
8774
  `absolute-voice-provider-status--${model.value.status}`,
8557
8775
  props.class
8558
8776
  ]
8559
8777
  }, [
8560
- h13("header", { class: "absolute-voice-provider-status__header" }, [
8561
- h13("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
8562
- h13("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
8778
+ h14("header", { class: "absolute-voice-provider-status__header" }, [
8779
+ h14("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
8780
+ h14("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
8563
8781
  ]),
8564
- h13("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
8565
- model.value.providers.length ? h13("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h13("article", {
8782
+ h14("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
8783
+ model.value.providers.length ? h14("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h14("article", {
8566
8784
  class: [
8567
8785
  "absolute-voice-provider-status__provider",
8568
8786
  `absolute-voice-provider-status__provider--${provider.status}`
8569
8787
  ],
8570
8788
  key: provider.provider
8571
8789
  }, [
8572
- h13("header", [
8573
- h13("strong", provider.label),
8574
- h13("span", provider.status)
8790
+ h14("header", [
8791
+ h14("strong", provider.label),
8792
+ h14("span", provider.status)
8575
8793
  ]),
8576
- h13("p", provider.detail),
8577
- h13("dl", provider.rows.map((row) => h13("div", { key: row.label }, [
8578
- h13("dt", row.label),
8579
- h13("dd", row.value)
8794
+ h14("p", provider.detail),
8795
+ h14("dl", provider.rows.map((row) => h14("div", { key: row.label }, [
8796
+ h14("dt", row.label),
8797
+ h14("dd", row.value)
8580
8798
  ])))
8581
- ]))) : h13("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
8582
- model.value.error ? h13("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
8799
+ ]))) : h14("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
8800
+ model.value.error ? h14("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
8583
8801
  ]);
8584
8802
  }
8585
8803
  });
8586
8804
  // src/vue/VoiceRoutingStatus.ts
8587
- import { computed as computed7, defineComponent as defineComponent14, h as h14 } from "vue";
8805
+ import { computed as computed7, defineComponent as defineComponent15, h as h15 } from "vue";
8588
8806
 
8589
8807
  // src/client/routingStatus.ts
8590
8808
  var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
@@ -8667,9 +8885,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
8667
8885
  };
8668
8886
 
8669
8887
  // src/client/routingStatusWidget.ts
8670
- var DEFAULT_TITLE13 = "Voice Routing";
8671
- var DEFAULT_DESCRIPTION13 = "Latest provider routing decision from the self-hosted trace store.";
8672
- var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8888
+ var DEFAULT_TITLE14 = "Voice Routing";
8889
+ var DEFAULT_DESCRIPTION14 = "Latest provider routing decision from the self-hosted trace store.";
8890
+ var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8673
8891
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
8674
8892
  var formatProviderRoutes = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
8675
8893
  var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
@@ -8738,35 +8956,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
8738
8956
  return {
8739
8957
  activeStack,
8740
8958
  decision,
8741
- description: options.description ?? DEFAULT_DESCRIPTION13,
8959
+ description: options.description ?? DEFAULT_DESCRIPTION14,
8742
8960
  error: snapshot.error,
8743
8961
  isLoading: snapshot.isLoading,
8744
8962
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
8745
8963
  rows,
8746
8964
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
8747
- title: options.title ?? DEFAULT_TITLE13,
8965
+ title: options.title ?? DEFAULT_TITLE14,
8748
8966
  updatedAt: snapshot.updatedAt
8749
8967
  };
8750
8968
  };
8751
8969
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
8752
8970
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
8753
8971
  const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
8754
- <span>${escapeHtml19(item.label)}</span>
8755
- <strong>${escapeHtml19(item.value)}</strong>
8972
+ <span>${escapeHtml20(item.label)}</span>
8973
+ <strong>${escapeHtml20(item.value)}</strong>
8756
8974
  </div>`).join("")}</div>` : "";
8757
8975
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
8758
- <span>${escapeHtml19(row.label)}</span>
8759
- <strong>${escapeHtml19(row.value)}</strong>
8976
+ <span>${escapeHtml20(row.label)}</span>
8977
+ <strong>${escapeHtml20(row.value)}</strong>
8760
8978
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
8761
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml19(model.status)}">
8979
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml20(model.status)}">
8762
8980
  <header class="absolute-voice-routing-status__header">
8763
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml19(model.title)}</span>
8764
- <strong class="absolute-voice-routing-status__label">${escapeHtml19(model.label)}</strong>
8981
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml20(model.title)}</span>
8982
+ <strong class="absolute-voice-routing-status__label">${escapeHtml20(model.label)}</strong>
8765
8983
  </header>
8766
- <p class="absolute-voice-routing-status__description">${escapeHtml19(model.description)}</p>
8984
+ <p class="absolute-voice-routing-status__description">${escapeHtml20(model.description)}</p>
8767
8985
  ${activeStack}
8768
8986
  ${rows}
8769
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml19(model.error)}</p>` : ""}
8987
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml20(model.error)}</p>` : ""}
8770
8988
  </section>`;
8771
8989
  };
8772
8990
  var getVoiceRoutingStatusCSS = () => `.absolute-voice-routing-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-routing-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-routing-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-routing-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-routing-status__label{font-size:24px;line-height:1}.absolute-voice-routing-status__description{color:#514733;margin:12px 0 0}.absolute-voice-routing-status__stack{background:linear-gradient(135deg,#16130d,#49391f);border-radius:18px;color:#fff;display:grid;gap:8px;grid-template-columns:repeat(5,minmax(0,1fr));margin-top:14px;padding:12px}.absolute-voice-routing-status__stack div{border-left:1px solid rgba(255,255,255,.18);padding-left:10px}.absolute-voice-routing-status__stack div:first-child{border-left:0;padding-left:0}.absolute-voice-routing-status__stack span{color:#e9d9b8;display:block;font-size:11px;font-weight:800;letter-spacing:.08em;margin-bottom:5px;text-transform:uppercase}.absolute-voice-routing-status__stack strong{display:block;font-size:13px;line-height:1.25;overflow-wrap:anywhere}.absolute-voice-routing-status__grid{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:14px}.absolute-voice-routing-status__grid div{background:#fff;border:1px solid #eee4d2;border-radius:14px;padding:10px 12px}.absolute-voice-routing-status__grid span{color:#655944;display:block;font-size:12px;margin-bottom:4px}.absolute-voice-routing-status__grid strong{overflow-wrap:anywhere}.absolute-voice-routing-status__empty{color:#655944;margin:14px 0 0}.absolute-voice-routing-status__error{color:#9f1239;font-weight:700}@media (max-width:760px){.absolute-voice-routing-status__stack{grid-template-columns:repeat(2,minmax(0,1fr))}.absolute-voice-routing-status__stack div{border-left:0;border-top:1px solid rgba(255,255,255,.18);padding-left:0;padding-top:8px}.absolute-voice-routing-status__stack div:first-child{border-top:0;padding-top:0}}`;
@@ -8808,13 +9026,13 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
8808
9026
  };
8809
9027
 
8810
9028
  // src/vue/useVoiceRoutingStatus.ts
8811
- import { onUnmounted as onUnmounted13, ref as ref10, shallowRef as shallowRef12 } from "vue";
9029
+ import { onUnmounted as onUnmounted13, ref as ref11, shallowRef as shallowRef12 } from "vue";
8812
9030
  function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
8813
9031
  const store = createVoiceRoutingStatusStore(path, options);
8814
9032
  const decision = shallowRef12(null);
8815
- const error = ref10(null);
8816
- const isLoading = ref10(false);
8817
- const updatedAt = ref10(undefined);
9033
+ const error = ref11(null);
9034
+ const isLoading = ref11(false);
9035
+ const updatedAt = ref11(undefined);
8818
9036
  const sync = () => {
8819
9037
  const snapshot = store.getSnapshot();
8820
9038
  decision.value = snapshot.decision;
@@ -8839,7 +9057,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
8839
9057
  }
8840
9058
 
8841
9059
  // src/vue/VoiceRoutingStatus.ts
8842
- var VoiceRoutingStatus = defineComponent14({
9060
+ var VoiceRoutingStatus = defineComponent15({
8843
9061
  name: "VoiceRoutingStatus",
8844
9062
  props: {
8845
9063
  class: {
@@ -8876,28 +9094,28 @@ var VoiceRoutingStatus = defineComponent14({
8876
9094
  isLoading: status.isLoading.value,
8877
9095
  updatedAt: status.updatedAt.value
8878
9096
  }, options));
8879
- return () => h14("section", {
9097
+ return () => h15("section", {
8880
9098
  class: [
8881
9099
  "absolute-voice-routing-status",
8882
9100
  `absolute-voice-routing-status--${model.value.status}`,
8883
9101
  props.class
8884
9102
  ]
8885
9103
  }, [
8886
- h14("header", { class: "absolute-voice-routing-status__header" }, [
8887
- h14("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
8888
- h14("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
9104
+ h15("header", { class: "absolute-voice-routing-status__header" }, [
9105
+ h15("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
9106
+ h15("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
8889
9107
  ]),
8890
- h14("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
8891
- model.value.rows.length ? h14("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h14("div", { key: row.label }, [
8892
- h14("span", row.label),
8893
- h14("strong", row.value)
8894
- ]))) : h14("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
8895
- model.value.error ? h14("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
9108
+ h15("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
9109
+ model.value.rows.length ? h15("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h15("div", { key: row.label }, [
9110
+ h15("span", row.label),
9111
+ h15("strong", row.value)
9112
+ ]))) : h15("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
9113
+ model.value.error ? h15("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
8896
9114
  ]);
8897
9115
  }
8898
9116
  });
8899
9117
  // src/vue/useVoiceAgentSquadStatus.ts
8900
- import { onUnmounted as onUnmounted14, ref as ref11, shallowRef as shallowRef13 } from "vue";
9118
+ import { onUnmounted as onUnmounted14, ref as ref12, shallowRef as shallowRef13 } from "vue";
8901
9119
 
8902
9120
  // src/client/traceTimeline.ts
8903
9121
  var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
@@ -9057,10 +9275,10 @@ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}
9057
9275
  function useVoiceAgentSquadStatus(path = "/api/voice-traces", options = {}) {
9058
9276
  const store = createVoiceAgentSquadStatusStore(path, options);
9059
9277
  const current = shallowRef13(undefined);
9060
- const error = ref11(null);
9061
- const isLoading = ref11(false);
9278
+ const error = ref12(null);
9279
+ const isLoading = ref12(false);
9062
9280
  const report = shallowRef13(undefined);
9063
- const updatedAt = ref11(undefined);
9281
+ const updatedAt = ref12(undefined);
9064
9282
  const sync = () => {
9065
9283
  const snapshot = store.getSnapshot();
9066
9284
  current.value = snapshot.report.current;
@@ -9088,7 +9306,7 @@ function useVoiceAgentSquadStatus(path = "/api/voice-traces", options = {}) {
9088
9306
  };
9089
9307
  }
9090
9308
  // src/vue/VoiceTurnLatency.ts
9091
- import { computed as computed8, defineComponent as defineComponent15, h as h15 } from "vue";
9309
+ import { computed as computed8, defineComponent as defineComponent16, h as h16 } from "vue";
9092
9310
 
9093
9311
  // src/client/turnLatency.ts
9094
9312
  var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
@@ -9194,56 +9412,56 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
9194
9412
  };
9195
9413
 
9196
9414
  // src/client/turnLatencyWidget.ts
9197
- var DEFAULT_TITLE14 = "Turn Latency";
9198
- var DEFAULT_DESCRIPTION14 = "Per-turn timing from first transcript to commit and assistant response start.";
9415
+ var DEFAULT_TITLE15 = "Turn Latency";
9416
+ var DEFAULT_DESCRIPTION15 = "Per-turn timing from first transcript to commit and assistant response start.";
9199
9417
  var DEFAULT_PROOF_LABEL = "Run latency proof";
9200
- var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9201
- var formatMs3 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
9418
+ var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9419
+ var formatMs4 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
9202
9420
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
9203
9421
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
9204
9422
  ...turn,
9205
9423
  label: turn.text || "Empty turn",
9206
9424
  rows: turn.stages.map((stage) => ({
9207
9425
  label: stage.label,
9208
- value: formatMs3(stage.valueMs)
9426
+ value: formatMs4(stage.valueMs)
9209
9427
  }))
9210
9428
  }));
9211
9429
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
9212
9430
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
9213
9431
  return {
9214
- description: options.description ?? DEFAULT_DESCRIPTION14,
9432
+ description: options.description ?? DEFAULT_DESCRIPTION15,
9215
9433
  error: snapshot.error,
9216
9434
  isLoading: snapshot.isLoading,
9217
- label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs3(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
9435
+ label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs4(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
9218
9436
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
9219
9437
  showProofAction: Boolean(options.proofPath),
9220
9438
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
9221
- title: options.title ?? DEFAULT_TITLE14,
9439
+ title: options.title ?? DEFAULT_TITLE15,
9222
9440
  turns,
9223
9441
  updatedAt: snapshot.updatedAt
9224
9442
  };
9225
9443
  };
9226
9444
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
9227
9445
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
9228
- 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--${escapeHtml20(turn.status)}">
9446
+ 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--${escapeHtml21(turn.status)}">
9229
9447
  <header>
9230
- <strong>${escapeHtml20(turn.label)}</strong>
9231
- <span>${escapeHtml20(turn.status)}</span>
9448
+ <strong>${escapeHtml21(turn.label)}</strong>
9449
+ <span>${escapeHtml21(turn.status)}</span>
9232
9450
  </header>
9233
9451
  <dl>${turn.rows.map((row) => `<div>
9234
- <dt>${escapeHtml20(row.label)}</dt>
9235
- <dd>${escapeHtml20(row.value)}</dd>
9452
+ <dt>${escapeHtml21(row.label)}</dt>
9453
+ <dd>${escapeHtml21(row.value)}</dd>
9236
9454
  </div>`).join("")}</dl>
9237
9455
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
9238
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml20(model.status)}">
9456
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml21(model.status)}">
9239
9457
  <header class="absolute-voice-turn-latency__header">
9240
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml20(model.title)}</span>
9241
- <strong class="absolute-voice-turn-latency__label">${escapeHtml20(model.label)}</strong>
9458
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml21(model.title)}</span>
9459
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml21(model.label)}</strong>
9242
9460
  </header>
9243
- <p class="absolute-voice-turn-latency__description">${escapeHtml20(model.description)}</p>
9244
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml20(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
9461
+ <p class="absolute-voice-turn-latency__description">${escapeHtml21(model.description)}</p>
9462
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml21(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
9245
9463
  ${turns}
9246
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml20(model.error)}</p>` : ""}
9464
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml21(model.error)}</p>` : ""}
9247
9465
  </section>`;
9248
9466
  };
9249
9467
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -9326,7 +9544,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
9326
9544
  }
9327
9545
 
9328
9546
  // src/vue/VoiceTurnLatency.ts
9329
- var VoiceTurnLatency = defineComponent15({
9547
+ var VoiceTurnLatency = defineComponent16({
9330
9548
  name: "VoiceTurnLatency",
9331
9549
  props: {
9332
9550
  class: { default: "", type: String },
@@ -9352,47 +9570,47 @@ var VoiceTurnLatency = defineComponent15({
9352
9570
  report: latency.report.value,
9353
9571
  updatedAt: latency.updatedAt.value
9354
9572
  }, options));
9355
- return () => h15("section", {
9573
+ return () => h16("section", {
9356
9574
  class: [
9357
9575
  "absolute-voice-turn-latency",
9358
9576
  `absolute-voice-turn-latency--${model.value.status}`,
9359
9577
  props.class
9360
9578
  ]
9361
9579
  }, [
9362
- h15("header", { class: "absolute-voice-turn-latency__header" }, [
9363
- h15("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
9364
- h15("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
9580
+ h16("header", { class: "absolute-voice-turn-latency__header" }, [
9581
+ h16("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
9582
+ h16("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
9365
9583
  ]),
9366
- h15("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
9367
- model.value.showProofAction ? h15("button", {
9584
+ h16("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
9585
+ model.value.showProofAction ? h16("button", {
9368
9586
  class: "absolute-voice-turn-latency__proof",
9369
9587
  onClick: () => {
9370
9588
  latency.runProof().catch(() => {});
9371
9589
  },
9372
9590
  type: "button"
9373
9591
  }, model.value.proofLabel) : null,
9374
- model.value.turns.length ? h15("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h15("article", {
9592
+ model.value.turns.length ? h16("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h16("article", {
9375
9593
  class: [
9376
9594
  "absolute-voice-turn-latency__turn",
9377
9595
  `absolute-voice-turn-latency__turn--${turn.status}`
9378
9596
  ],
9379
9597
  key: `${turn.sessionId}:${turn.turnId}`
9380
9598
  }, [
9381
- h15("header", [
9382
- h15("strong", turn.label),
9383
- h15("span", turn.status)
9599
+ h16("header", [
9600
+ h16("strong", turn.label),
9601
+ h16("span", turn.status)
9384
9602
  ]),
9385
- h15("dl", turn.rows.map((row) => h15("div", { key: row.label }, [
9386
- h15("dt", row.label),
9387
- h15("dd", row.value)
9603
+ h16("dl", turn.rows.map((row) => h16("div", { key: row.label }, [
9604
+ h16("dt", row.label),
9605
+ h16("dd", row.value)
9388
9606
  ])))
9389
- ]))) : h15("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
9390
- model.value.error ? h15("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
9607
+ ]))) : h16("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
9608
+ model.value.error ? h16("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
9391
9609
  ]);
9392
9610
  }
9393
9611
  });
9394
9612
  // src/vue/VoiceTurnQuality.ts
9395
- import { computed as computed9, defineComponent as defineComponent16, h as h16 } from "vue";
9613
+ import { computed as computed9, defineComponent as defineComponent17, h as h17 } from "vue";
9396
9614
 
9397
9615
  // src/client/turnQuality.ts
9398
9616
  var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
@@ -9474,9 +9692,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
9474
9692
  };
9475
9693
 
9476
9694
  // src/client/turnQualityWidget.ts
9477
- var DEFAULT_TITLE15 = "Turn Quality";
9478
- var DEFAULT_DESCRIPTION15 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
9479
- var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9695
+ var DEFAULT_TITLE16 = "Turn Quality";
9696
+ var DEFAULT_DESCRIPTION16 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
9697
+ var escapeHtml22 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9480
9698
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
9481
9699
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
9482
9700
  var getTurnDetail = (turn) => {
@@ -9520,37 +9738,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
9520
9738
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
9521
9739
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
9522
9740
  return {
9523
- description: options.description ?? DEFAULT_DESCRIPTION15,
9741
+ description: options.description ?? DEFAULT_DESCRIPTION16,
9524
9742
  error: snapshot.error,
9525
9743
  isLoading: snapshot.isLoading,
9526
9744
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
9527
9745
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
9528
- title: options.title ?? DEFAULT_TITLE15,
9746
+ title: options.title ?? DEFAULT_TITLE16,
9529
9747
  turns,
9530
9748
  updatedAt: snapshot.updatedAt
9531
9749
  };
9532
9750
  };
9533
9751
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
9534
9752
  const model = createVoiceTurnQualityViewModel(snapshot, options);
9535
- 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--${escapeHtml21(turn.status)}">
9753
+ 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--${escapeHtml22(turn.status)}">
9536
9754
  <header>
9537
- <strong>${escapeHtml21(turn.label)}</strong>
9538
- <span>${escapeHtml21(turn.status)}</span>
9755
+ <strong>${escapeHtml22(turn.label)}</strong>
9756
+ <span>${escapeHtml22(turn.status)}</span>
9539
9757
  </header>
9540
- <p>${escapeHtml21(turn.detail)}</p>
9758
+ <p>${escapeHtml22(turn.detail)}</p>
9541
9759
  <dl>${turn.rows.map((row) => `<div>
9542
- <dt>${escapeHtml21(row.label)}</dt>
9543
- <dd>${escapeHtml21(row.value)}</dd>
9760
+ <dt>${escapeHtml22(row.label)}</dt>
9761
+ <dd>${escapeHtml22(row.value)}</dd>
9544
9762
  </div>`).join("")}</dl>
9545
9763
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
9546
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml21(model.status)}">
9764
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml22(model.status)}">
9547
9765
  <header class="absolute-voice-turn-quality__header">
9548
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml21(model.title)}</span>
9549
- <strong class="absolute-voice-turn-quality__label">${escapeHtml21(model.label)}</strong>
9766
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml22(model.title)}</span>
9767
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml22(model.label)}</strong>
9550
9768
  </header>
9551
- <p class="absolute-voice-turn-quality__description">${escapeHtml21(model.description)}</p>
9769
+ <p class="absolute-voice-turn-quality__description">${escapeHtml22(model.description)}</p>
9552
9770
  ${turns}
9553
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml21(model.error)}</p>` : ""}
9771
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml22(model.error)}</p>` : ""}
9554
9772
  </section>`;
9555
9773
  };
9556
9774
  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}`;
@@ -9617,7 +9835,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
9617
9835
  }
9618
9836
 
9619
9837
  // src/vue/VoiceTurnQuality.ts
9620
- var VoiceTurnQuality = defineComponent16({
9838
+ var VoiceTurnQuality = defineComponent17({
9621
9839
  name: "VoiceTurnQuality",
9622
9840
  props: {
9623
9841
  class: { default: "", type: String },
@@ -9639,41 +9857,71 @@ var VoiceTurnQuality = defineComponent16({
9639
9857
  report: quality.report.value,
9640
9858
  updatedAt: quality.updatedAt.value
9641
9859
  }, options));
9642
- return () => h16("section", {
9860
+ return () => h17("section", {
9643
9861
  class: [
9644
9862
  "absolute-voice-turn-quality",
9645
9863
  `absolute-voice-turn-quality--${model.value.status}`,
9646
9864
  props.class
9647
9865
  ]
9648
9866
  }, [
9649
- h16("header", { class: "absolute-voice-turn-quality__header" }, [
9650
- h16("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
9651
- h16("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
9867
+ h17("header", { class: "absolute-voice-turn-quality__header" }, [
9868
+ h17("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
9869
+ h17("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
9652
9870
  ]),
9653
- h16("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
9654
- model.value.turns.length ? h16("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h16("article", {
9871
+ h17("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
9872
+ model.value.turns.length ? h17("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h17("article", {
9655
9873
  class: [
9656
9874
  "absolute-voice-turn-quality__turn",
9657
9875
  `absolute-voice-turn-quality__turn--${turn.status}`
9658
9876
  ],
9659
9877
  key: `${turn.sessionId}:${turn.turnId}`
9660
9878
  }, [
9661
- h16("header", [
9662
- h16("strong", turn.label),
9663
- h16("span", turn.status)
9879
+ h17("header", [
9880
+ h17("strong", turn.label),
9881
+ h17("span", turn.status)
9664
9882
  ]),
9665
- h16("p", turn.detail),
9666
- h16("dl", turn.rows.map((row) => h16("div", { key: row.label }, [
9667
- h16("dt", row.label),
9668
- h16("dd", row.value)
9883
+ h17("p", turn.detail),
9884
+ h17("dl", turn.rows.map((row) => h17("div", { key: row.label }, [
9885
+ h17("dt", row.label),
9886
+ h17("dd", row.value)
9669
9887
  ])))
9670
- ]))) : h16("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
9671
- model.value.error ? h16("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
9888
+ ]))) : h17("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
9889
+ model.value.error ? h17("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
9672
9890
  ]);
9673
9891
  }
9674
9892
  });
9893
+ // src/vue/useVoiceSessionObservability.ts
9894
+ import { onUnmounted as onUnmounted17, ref as ref13, shallowRef as shallowRef16 } from "vue";
9895
+ function useVoiceSessionObservability(path = "/api/voice/session-observability/latest", options = {}) {
9896
+ const store = createVoiceSessionObservabilityStore(path, options);
9897
+ const error = ref13(null);
9898
+ const isLoading = ref13(false);
9899
+ const report = shallowRef16(null);
9900
+ const updatedAt = ref13(undefined);
9901
+ const sync = () => {
9902
+ const snapshot = store.getSnapshot();
9903
+ error.value = snapshot.error;
9904
+ isLoading.value = snapshot.isLoading;
9905
+ report.value = snapshot.report;
9906
+ updatedAt.value = snapshot.updatedAt;
9907
+ };
9908
+ const unsubscribe = store.subscribe(sync);
9909
+ sync();
9910
+ store.refresh().catch(() => {});
9911
+ onUnmounted17(() => {
9912
+ unsubscribe();
9913
+ store.close();
9914
+ });
9915
+ return {
9916
+ error,
9917
+ isLoading,
9918
+ refresh: store.refresh,
9919
+ report,
9920
+ updatedAt
9921
+ };
9922
+ }
9675
9923
  // src/vue/useVoiceProfileComparison.ts
9676
- import { onUnmounted as onUnmounted17, ref as ref12, shallowRef as shallowRef16 } from "vue";
9924
+ import { onUnmounted as onUnmounted18, ref as ref14, shallowRef as shallowRef17 } from "vue";
9677
9925
 
9678
9926
  // src/client/profileComparison.ts
9679
9927
  var fetchVoiceProfileComparison = async (path = "/api/voice/real-call-profile-history", options = {}) => {
@@ -9753,10 +10001,10 @@ var createVoiceProfileComparisonStore = (path = "/api/voice/real-call-profile-hi
9753
10001
  // src/vue/useVoiceProfileComparison.ts
9754
10002
  function useVoiceProfileComparison(path = "/api/voice/real-call-profile-history", options = {}) {
9755
10003
  const store = createVoiceProfileComparisonStore(path, options);
9756
- const error = ref12(null);
9757
- const isLoading = ref12(false);
9758
- const report = shallowRef16(undefined);
9759
- const updatedAt = ref12(undefined);
10004
+ const error = ref14(null);
10005
+ const isLoading = ref14(false);
10006
+ const report = shallowRef17(undefined);
10007
+ const updatedAt = ref14(undefined);
9760
10008
  const sync = () => {
9761
10009
  const snapshot = store.getSnapshot();
9762
10010
  error.value = snapshot.error;
@@ -9769,7 +10017,7 @@ function useVoiceProfileComparison(path = "/api/voice/real-call-profile-history"
9769
10017
  if (typeof window !== "undefined") {
9770
10018
  store.refresh().catch(() => {});
9771
10019
  }
9772
- onUnmounted17(() => {
10020
+ onUnmounted18(() => {
9773
10021
  unsubscribe();
9774
10022
  store.close();
9775
10023
  });
@@ -9782,7 +10030,7 @@ function useVoiceProfileComparison(path = "/api/voice/real-call-profile-history"
9782
10030
  };
9783
10031
  }
9784
10032
  // src/vue/useVoiceLiveOps.ts
9785
- import { onUnmounted as onUnmounted18, ref as ref13, shallowRef as shallowRef17 } from "vue";
10033
+ import { onUnmounted as onUnmounted19, ref as ref15, shallowRef as shallowRef18 } from "vue";
9786
10034
 
9787
10035
  // src/client/liveOps.ts
9788
10036
  var postVoiceLiveOpsAction = async (input, options = {}) => {
@@ -9873,11 +10121,11 @@ var createVoiceLiveOpsStore = (options = {}) => {
9873
10121
  // src/vue/useVoiceLiveOps.ts
9874
10122
  function useVoiceLiveOps(options = {}) {
9875
10123
  const store = createVoiceLiveOpsStore(options);
9876
- const error = ref13(null);
9877
- const isRunning = ref13(false);
9878
- const lastResult = shallowRef17(undefined);
9879
- const runningAction = ref13(undefined);
9880
- const updatedAt = ref13(undefined);
10124
+ const error = ref15(null);
10125
+ const isRunning = ref15(false);
10126
+ const lastResult = shallowRef18(undefined);
10127
+ const runningAction = ref15(undefined);
10128
+ const updatedAt = ref15(undefined);
9881
10129
  const sync = () => {
9882
10130
  const snapshot = store.getSnapshot();
9883
10131
  error.value = snapshot.error;
@@ -9888,7 +10136,7 @@ function useVoiceLiveOps(options = {}) {
9888
10136
  };
9889
10137
  const unsubscribe = store.subscribe(sync);
9890
10138
  sync();
9891
- onUnmounted18(() => {
10139
+ onUnmounted19(() => {
9892
10140
  unsubscribe();
9893
10141
  store.close();
9894
10142
  });
@@ -9902,7 +10150,7 @@ function useVoiceLiveOps(options = {}) {
9902
10150
  };
9903
10151
  }
9904
10152
  // src/vue/useVoiceCampaignDialerProof.ts
9905
- import { onUnmounted as onUnmounted19, shallowRef as shallowRef18 } from "vue";
10153
+ import { onUnmounted as onUnmounted20, shallowRef as shallowRef19 } from "vue";
9906
10154
 
9907
10155
  // src/client/campaignDialerProof.ts
9908
10156
  var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
@@ -10025,11 +10273,11 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
10025
10273
  // src/vue/useVoiceCampaignDialerProof.ts
10026
10274
  function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof", options = {}) {
10027
10275
  const store = createVoiceCampaignDialerProofStore(path, options);
10028
- const error = shallowRef18(null);
10029
- const isLoading = shallowRef18(false);
10030
- const report = shallowRef18();
10031
- const status = shallowRef18();
10032
- const updatedAt = shallowRef18(undefined);
10276
+ const error = shallowRef19(null);
10277
+ const isLoading = shallowRef19(false);
10278
+ const report = shallowRef19();
10279
+ const status = shallowRef19();
10280
+ const updatedAt = shallowRef19(undefined);
10033
10281
  const sync = () => {
10034
10282
  const snapshot = store.getSnapshot();
10035
10283
  error.value = snapshot.error;
@@ -10043,7 +10291,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
10043
10291
  if (typeof window !== "undefined") {
10044
10292
  store.refresh().catch(() => {});
10045
10293
  }
10046
- onUnmounted19(() => {
10294
+ onUnmounted20(() => {
10047
10295
  unsubscribe();
10048
10296
  store.close();
10049
10297
  });
@@ -10058,7 +10306,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
10058
10306
  };
10059
10307
  }
10060
10308
  // src/vue/useVoiceStream.ts
10061
- import { onUnmounted as onUnmounted20, ref as ref14, shallowRef as shallowRef19 } from "vue";
10309
+ import { onUnmounted as onUnmounted21, ref as ref16, shallowRef as shallowRef20 } from "vue";
10062
10310
 
10063
10311
  // src/client/actions.ts
10064
10312
  var normalizeErrorMessage = (value) => {
@@ -11463,17 +11711,17 @@ var createVoiceStream = (path, options = {}) => {
11463
11711
  // src/vue/useVoiceStream.ts
11464
11712
  function useVoiceStream(path, options = {}) {
11465
11713
  const stream = createVoiceStream(path, options);
11466
- const assistantAudio = shallowRef19([]);
11467
- const assistantTexts = shallowRef19([]);
11468
- const call = shallowRef19(null);
11469
- const error = ref14(null);
11470
- const isConnected = ref14(false);
11471
- const partial = ref14("");
11472
- const reconnect = shallowRef19(stream.reconnect);
11473
- const sessionId = ref14(stream.sessionId);
11474
- const sessionMetadata = shallowRef19(stream.sessionMetadata);
11475
- const status = ref14(stream.status);
11476
- const turns = shallowRef19([]);
11714
+ const assistantAudio = shallowRef20([]);
11715
+ const assistantTexts = shallowRef20([]);
11716
+ const call = shallowRef20(null);
11717
+ const error = ref16(null);
11718
+ const isConnected = ref16(false);
11719
+ const partial = ref16("");
11720
+ const reconnect = shallowRef20(stream.reconnect);
11721
+ const sessionId = ref16(stream.sessionId);
11722
+ const sessionMetadata = shallowRef20(stream.sessionMetadata);
11723
+ const status = ref16(stream.status);
11724
+ const turns = shallowRef20([]);
11477
11725
  const sync = () => {
11478
11726
  assistantAudio.value = [...stream.assistantAudio];
11479
11727
  assistantTexts.value = [...stream.assistantTexts];
@@ -11493,7 +11741,7 @@ function useVoiceStream(path, options = {}) {
11493
11741
  unsubscribe();
11494
11742
  stream.close();
11495
11743
  };
11496
- onUnmounted20(destroy);
11744
+ onUnmounted21(destroy);
11497
11745
  return {
11498
11746
  assistantAudio,
11499
11747
  assistantTexts,
@@ -11514,7 +11762,7 @@ function useVoiceStream(path, options = {}) {
11514
11762
  };
11515
11763
  }
11516
11764
  // src/vue/useVoiceController.ts
11517
- import { onUnmounted as onUnmounted21, ref as ref15, shallowRef as shallowRef20 } from "vue";
11765
+ import { onUnmounted as onUnmounted22, ref as ref17, shallowRef as shallowRef21 } from "vue";
11518
11766
 
11519
11767
  // src/client/htmx.ts
11520
11768
  var DEFAULT_EVENT_NAME = "voice-refresh";
@@ -12166,17 +12414,17 @@ var createVoiceController = (path, options = {}) => {
12166
12414
  // src/vue/useVoiceController.ts
12167
12415
  function useVoiceController(path, options = {}) {
12168
12416
  const controller = createVoiceController(path, options);
12169
- const assistantAudio = shallowRef20([]);
12170
- const assistantTexts = shallowRef20([]);
12171
- const error = ref15(null);
12172
- const isConnected = ref15(false);
12173
- const isRecording = ref15(false);
12174
- const partial = ref15("");
12175
- const reconnect = shallowRef20(controller.reconnect);
12176
- const recordingError = ref15(null);
12177
- const sessionId = ref15(controller.sessionId);
12178
- const status = ref15(controller.status);
12179
- const turns = shallowRef20([]);
12417
+ const assistantAudio = shallowRef21([]);
12418
+ const assistantTexts = shallowRef21([]);
12419
+ const error = ref17(null);
12420
+ const isConnected = ref17(false);
12421
+ const isRecording = ref17(false);
12422
+ const partial = ref17("");
12423
+ const reconnect = shallowRef21(controller.reconnect);
12424
+ const recordingError = ref17(null);
12425
+ const sessionId = ref17(controller.sessionId);
12426
+ const status = ref17(controller.status);
12427
+ const turns = shallowRef21([]);
12180
12428
  const sync = () => {
12181
12429
  assistantAudio.value = [...controller.assistantAudio];
12182
12430
  assistantTexts.value = [...controller.assistantTexts];
@@ -12196,7 +12444,7 @@ function useVoiceController(path, options = {}) {
12196
12444
  unsubscribe();
12197
12445
  controller.close();
12198
12446
  };
12199
- onUnmounted21(destroy);
12447
+ onUnmounted22(destroy);
12200
12448
  return {
12201
12449
  assistantAudio,
12202
12450
  assistantTexts,
@@ -12220,13 +12468,13 @@ function useVoiceController(path, options = {}) {
12220
12468
  };
12221
12469
  }
12222
12470
  // src/vue/useVoiceTraceTimeline.ts
12223
- import { onUnmounted as onUnmounted22, ref as ref16, shallowRef as shallowRef21 } from "vue";
12471
+ import { onUnmounted as onUnmounted23, ref as ref18, shallowRef as shallowRef22 } from "vue";
12224
12472
  function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
12225
12473
  const store = createVoiceTraceTimelineStore(path, options);
12226
- const error = ref16(null);
12227
- const isLoading = ref16(false);
12228
- const report = shallowRef21(null);
12229
- const updatedAt = ref16(undefined);
12474
+ const error = ref18(null);
12475
+ const isLoading = ref18(false);
12476
+ const report = shallowRef22(null);
12477
+ const updatedAt = ref18(undefined);
12230
12478
  const sync = () => {
12231
12479
  const snapshot = store.getSnapshot();
12232
12480
  error.value = snapshot.error;
@@ -12237,7 +12485,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
12237
12485
  const unsubscribe = store.subscribe(sync);
12238
12486
  sync();
12239
12487
  store.refresh().catch(() => {});
12240
- onUnmounted22(() => {
12488
+ onUnmounted23(() => {
12241
12489
  unsubscribe();
12242
12490
  store.close();
12243
12491
  });
@@ -12250,7 +12498,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
12250
12498
  };
12251
12499
  }
12252
12500
  // src/vue/useVoiceWorkflowStatus.ts
12253
- import { onUnmounted as onUnmounted23, ref as ref17, shallowRef as shallowRef22 } from "vue";
12501
+ import { onUnmounted as onUnmounted24, ref as ref19, shallowRef as shallowRef23 } from "vue";
12254
12502
 
12255
12503
  // src/client/workflowStatus.ts
12256
12504
  var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
@@ -12334,10 +12582,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
12334
12582
  // src/vue/useVoiceWorkflowStatus.ts
12335
12583
  function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
12336
12584
  const store = createVoiceWorkflowStatusStore(path, options);
12337
- const error = ref17(null);
12338
- const isLoading = ref17(false);
12339
- const report = shallowRef22(undefined);
12340
- const updatedAt = ref17(undefined);
12585
+ const error = ref19(null);
12586
+ const isLoading = ref19(false);
12587
+ const report = shallowRef23(undefined);
12588
+ const updatedAt = ref19(undefined);
12341
12589
  const sync = () => {
12342
12590
  const snapshot = store.getSnapshot();
12343
12591
  error.value = snapshot.error;
@@ -12350,7 +12598,7 @@ function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
12350
12598
  if (typeof window !== "undefined") {
12351
12599
  store.refresh().catch(() => {});
12352
12600
  }
12353
- onUnmounted23(() => {
12601
+ onUnmounted24(() => {
12354
12602
  unsubscribe();
12355
12603
  store.close();
12356
12604
  });
@@ -12369,6 +12617,7 @@ export {
12369
12617
  useVoiceTraceTimeline,
12370
12618
  useVoiceStream,
12371
12619
  useVoiceSessionSnapshot,
12620
+ useVoiceSessionObservability,
12372
12621
  useVoiceRoutingStatus,
12373
12622
  useVoiceReconnectProfileEvidence,
12374
12623
  useVoiceReadinessFailures,
@@ -12390,6 +12639,7 @@ export {
12390
12639
  VoiceTurnQuality,
12391
12640
  VoiceTurnLatency,
12392
12641
  VoiceSessionSnapshot,
12642
+ VoiceSessionObservability,
12393
12643
  VoiceRoutingStatus,
12394
12644
  VoiceReconnectProfileEvidence,
12395
12645
  VoiceReadinessFailures,