@absolutejs/voice 0.0.22-beta.152 → 0.0.22-beta.154
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/README.md +39 -0
- package/dist/angular/index.d.ts +1 -0
- package/dist/angular/index.js +471 -137
- package/dist/angular/voice-delivery-runtime.component.d.ts +3 -0
- package/dist/angular/voice-delivery-runtime.service.d.ts +4 -0
- package/dist/angular/voice-ops-action-center.service.d.ts +13 -0
- package/dist/client/deliveryRuntime.d.ts +15 -0
- package/dist/client/deliveryRuntimeWidget.d.ts +3 -0
- package/dist/client/index.d.ts +6 -2
- package/dist/client/index.js +454 -114
- package/dist/client/opsActionCenter.d.ts +50 -0
- package/dist/client/opsActionCenterWidget.d.ts +29 -0
- package/dist/deliveryRuntime.d.ts +13 -1
- package/dist/index.js +44 -1
- package/dist/react/VoiceDeliveryRuntime.d.ts +2 -1
- package/dist/react/VoiceOpsActionCenter.d.ts +5 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +720 -286
- package/dist/react/useVoiceDeliveryRuntime.d.ts +5 -0
- package/dist/react/useVoiceOpsActionCenter.d.ts +11 -0
- package/dist/svelte/createVoiceDeliveryRuntime.d.ts +2 -0
- package/dist/svelte/createVoiceOpsActionCenter.d.ts +10 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +464 -115
- package/dist/vue/VoiceDeliveryRuntime.d.ts +9 -0
- package/dist/vue/VoiceOpsActionCenter.d.ts +13 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.js +748 -292
- package/dist/vue/useVoiceDeliveryRuntime.d.ts +4 -0
- package/dist/vue/useVoiceOpsActionCenter.d.ts +11 -0
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -387,7 +387,333 @@ var VoiceOpsStatus = ({
|
|
|
387
387
|
]
|
|
388
388
|
}, undefined, true, undefined, this);
|
|
389
389
|
};
|
|
390
|
+
// src/client/opsActionCenter.ts
|
|
391
|
+
var createVoiceOpsActionCenterActions = (options = {}) => {
|
|
392
|
+
const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
|
|
393
|
+
const actions = [];
|
|
394
|
+
if (options.includeProductionReadiness !== false) {
|
|
395
|
+
actions.push({
|
|
396
|
+
description: "Refresh the production readiness report.",
|
|
397
|
+
id: "production-readiness",
|
|
398
|
+
label: "Refresh readiness",
|
|
399
|
+
method: "GET",
|
|
400
|
+
path: options.productionReadinessPath ?? "/api/production-readiness"
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
if (options.includeDeliveryRuntime !== false) {
|
|
404
|
+
actions.push({
|
|
405
|
+
description: "Drain pending and failed audit/trace deliveries.",
|
|
406
|
+
id: "delivery-runtime.tick",
|
|
407
|
+
label: "Tick delivery workers",
|
|
408
|
+
method: "POST",
|
|
409
|
+
path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
|
|
410
|
+
}, {
|
|
411
|
+
description: "Move reviewed dead letters back to live delivery queues.",
|
|
412
|
+
id: "delivery-runtime.requeue-dead-letters",
|
|
413
|
+
label: "Requeue dead letters",
|
|
414
|
+
method: "POST",
|
|
415
|
+
path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
if (options.includeTurnLatencyProof !== false) {
|
|
419
|
+
actions.push({
|
|
420
|
+
description: "Run the synthetic turn latency proof.",
|
|
421
|
+
id: "turn-latency.proof",
|
|
422
|
+
label: "Run latency proof",
|
|
423
|
+
method: "POST",
|
|
424
|
+
path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
if (options.includeProviderSimulation !== false) {
|
|
428
|
+
const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
|
|
429
|
+
for (const provider of options.providers ?? []) {
|
|
430
|
+
actions.push({
|
|
431
|
+
description: `Simulate ${provider} provider failure.`,
|
|
432
|
+
id: `provider.${provider}.failure`,
|
|
433
|
+
label: `Simulate ${provider} failure`,
|
|
434
|
+
method: "POST",
|
|
435
|
+
path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
|
|
436
|
+
}, {
|
|
437
|
+
description: `Mark ${provider} provider recovered.`,
|
|
438
|
+
id: `provider.${provider}.recovery`,
|
|
439
|
+
label: `Recover ${provider}`,
|
|
440
|
+
method: "POST",
|
|
441
|
+
path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return actions;
|
|
446
|
+
};
|
|
447
|
+
var runVoiceOpsAction = async (action, options = {}) => {
|
|
448
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
449
|
+
const response = await fetchImpl(action.path, {
|
|
450
|
+
method: action.method ?? "POST"
|
|
451
|
+
});
|
|
452
|
+
const body = await response.json().catch(() => null);
|
|
453
|
+
if (!response.ok) {
|
|
454
|
+
const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
|
|
455
|
+
throw new Error(message);
|
|
456
|
+
}
|
|
457
|
+
return {
|
|
458
|
+
actionId: action.id,
|
|
459
|
+
body,
|
|
460
|
+
ok: response.ok,
|
|
461
|
+
ranAt: Date.now(),
|
|
462
|
+
status: response.status
|
|
463
|
+
};
|
|
464
|
+
};
|
|
465
|
+
var createVoiceOpsActionCenterStore = (options = {}) => {
|
|
466
|
+
const listeners = new Set;
|
|
467
|
+
let closed = false;
|
|
468
|
+
let timer;
|
|
469
|
+
let snapshot = {
|
|
470
|
+
actions: options.actions ?? createVoiceOpsActionCenterActions(),
|
|
471
|
+
error: null,
|
|
472
|
+
isRunning: false
|
|
473
|
+
};
|
|
474
|
+
const emit = () => {
|
|
475
|
+
for (const listener of listeners) {
|
|
476
|
+
listener();
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
const setActions = (actions) => {
|
|
480
|
+
snapshot = { ...snapshot, actions, updatedAt: Date.now() };
|
|
481
|
+
emit();
|
|
482
|
+
};
|
|
483
|
+
const run = async (actionId) => {
|
|
484
|
+
if (closed) {
|
|
485
|
+
return snapshot.lastResult;
|
|
486
|
+
}
|
|
487
|
+
const action = snapshot.actions.find((item) => item.id === actionId);
|
|
488
|
+
if (!action) {
|
|
489
|
+
throw new Error(`Voice ops action "${actionId}" is not configured.`);
|
|
490
|
+
}
|
|
491
|
+
if (action.disabled) {
|
|
492
|
+
throw new Error(`Voice ops action "${actionId}" is disabled.`);
|
|
493
|
+
}
|
|
494
|
+
snapshot = {
|
|
495
|
+
...snapshot,
|
|
496
|
+
error: null,
|
|
497
|
+
isRunning: true,
|
|
498
|
+
runningActionId: action.id
|
|
499
|
+
};
|
|
500
|
+
emit();
|
|
501
|
+
try {
|
|
502
|
+
const result = await runVoiceOpsAction(action, options);
|
|
503
|
+
snapshot = {
|
|
504
|
+
...snapshot,
|
|
505
|
+
error: null,
|
|
506
|
+
isRunning: false,
|
|
507
|
+
lastResult: result,
|
|
508
|
+
runningActionId: undefined,
|
|
509
|
+
updatedAt: Date.now()
|
|
510
|
+
};
|
|
511
|
+
emit();
|
|
512
|
+
return result;
|
|
513
|
+
} catch (error) {
|
|
514
|
+
snapshot = {
|
|
515
|
+
...snapshot,
|
|
516
|
+
error: error instanceof Error ? error.message : String(error),
|
|
517
|
+
isRunning: false,
|
|
518
|
+
runningActionId: undefined
|
|
519
|
+
};
|
|
520
|
+
emit();
|
|
521
|
+
throw error;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
const close = () => {
|
|
525
|
+
closed = true;
|
|
526
|
+
if (timer) {
|
|
527
|
+
clearInterval(timer);
|
|
528
|
+
timer = undefined;
|
|
529
|
+
}
|
|
530
|
+
listeners.clear();
|
|
531
|
+
};
|
|
532
|
+
if (options.intervalMs && options.intervalMs > 0) {
|
|
533
|
+
timer = setInterval(() => {
|
|
534
|
+
emit();
|
|
535
|
+
}, options.intervalMs);
|
|
536
|
+
}
|
|
537
|
+
return {
|
|
538
|
+
close,
|
|
539
|
+
getServerSnapshot: () => snapshot,
|
|
540
|
+
getSnapshot: () => snapshot,
|
|
541
|
+
run,
|
|
542
|
+
setActions,
|
|
543
|
+
subscribe: (listener) => {
|
|
544
|
+
listeners.add(listener);
|
|
545
|
+
return () => {
|
|
546
|
+
listeners.delete(listener);
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
// src/client/opsActionCenterWidget.ts
|
|
553
|
+
var DEFAULT_TITLE2 = "Voice Ops Action Center";
|
|
554
|
+
var DEFAULT_DESCRIPTION2 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
555
|
+
var escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
556
|
+
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
557
|
+
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
558
|
+
return {
|
|
559
|
+
actions: snapshot.actions.map((action) => ({
|
|
560
|
+
description: action.description ?? "",
|
|
561
|
+
disabled: Boolean(action.disabled || snapshot.isRunning),
|
|
562
|
+
id: action.id,
|
|
563
|
+
isRunning: snapshot.runningActionId === action.id,
|
|
564
|
+
label: action.label
|
|
565
|
+
})),
|
|
566
|
+
description: options.description ?? DEFAULT_DESCRIPTION2,
|
|
567
|
+
error: snapshot.error,
|
|
568
|
+
isRunning: snapshot.isRunning,
|
|
569
|
+
label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
|
|
570
|
+
lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
|
|
571
|
+
status,
|
|
572
|
+
title: options.title ?? DEFAULT_TITLE2
|
|
573
|
+
};
|
|
574
|
+
};
|
|
575
|
+
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
576
|
+
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
577
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml2(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
578
|
+
${escapeHtml2(action.isRunning ? "Working..." : action.label)}
|
|
579
|
+
</button>`).join("");
|
|
580
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml2(model.status)}">
|
|
581
|
+
<header class="absolute-voice-ops-action-center__header">
|
|
582
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml2(model.title)}</span>
|
|
583
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml2(model.label)}</strong>
|
|
584
|
+
</header>
|
|
585
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml2(model.description)}</p>
|
|
586
|
+
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
587
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml2(model.lastResultLabel)}</p>
|
|
588
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml2(model.error)}</p>` : ""}
|
|
589
|
+
</section>`;
|
|
590
|
+
};
|
|
591
|
+
var getVoiceOpsActionCenterCSS = () => `.absolute-voice-ops-action-center{border:1px solid #d5cbb8;border-radius:20px;background:#fffaf1;color:#17130b;padding:18px;box-shadow:0 18px 40px rgba(58,42,16,.12);font-family:inherit}.absolute-voice-ops-action-center--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-ops-action-center__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-center__eyebrow{color:#725d37;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-center__label{font-size:28px;line-height:1}.absolute-voice-ops-action-center__description,.absolute-voice-ops-action-center__result{color:#5b4b2f;margin:12px 0 0}.absolute-voice-ops-action-center__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-ops-action-center__actions button{background:#7c4a03;border:0;border-radius:999px;color:#fff8e8;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-ops-action-center__actions button:disabled{cursor:not-allowed;opacity:.5}.absolute-voice-ops-action-center__error{color:#9f1239;font-weight:700}`;
|
|
592
|
+
var mountVoiceOpsActionCenter = (element, options = {}) => {
|
|
593
|
+
const store = createVoiceOpsActionCenterStore(options);
|
|
594
|
+
const render = () => {
|
|
595
|
+
element.innerHTML = renderVoiceOpsActionCenterHTML(store.getSnapshot(), options);
|
|
596
|
+
};
|
|
597
|
+
const unsubscribe = store.subscribe(render);
|
|
598
|
+
const handleClick = (event) => {
|
|
599
|
+
const target = event.target;
|
|
600
|
+
if (!(target instanceof Element)) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
const action = target.closest("[data-absolute-voice-ops-action]");
|
|
604
|
+
const actionId = action?.getAttribute("data-absolute-voice-ops-action");
|
|
605
|
+
if (actionId) {
|
|
606
|
+
store.run(actionId).catch(() => {});
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
element.addEventListener?.("click", handleClick);
|
|
610
|
+
render();
|
|
611
|
+
return {
|
|
612
|
+
close: () => {
|
|
613
|
+
element.removeEventListener?.("click", handleClick);
|
|
614
|
+
unsubscribe();
|
|
615
|
+
store.close();
|
|
616
|
+
},
|
|
617
|
+
run: store.run
|
|
618
|
+
};
|
|
619
|
+
};
|
|
620
|
+
var defineVoiceOpsActionCenterElement = (tagName = "absolute-voice-ops-action-center", options = {}) => {
|
|
621
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
customElements.define(tagName, class AbsoluteVoiceOpsActionCenterElement extends HTMLElement {
|
|
625
|
+
mounted;
|
|
626
|
+
connectedCallback() {
|
|
627
|
+
this.mounted = mountVoiceOpsActionCenter(this, {
|
|
628
|
+
...options,
|
|
629
|
+
description: this.getAttribute("description") ?? options.description,
|
|
630
|
+
title: this.getAttribute("title") ?? options.title
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
disconnectedCallback() {
|
|
634
|
+
this.mounted?.close();
|
|
635
|
+
this.mounted = undefined;
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
// src/react/useVoiceOpsActionCenter.tsx
|
|
641
|
+
import { useEffect as useEffect2, useRef as useRef2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
642
|
+
var useVoiceOpsActionCenter = (options = {}) => {
|
|
643
|
+
const storeRef = useRef2(null);
|
|
644
|
+
if (!storeRef.current) {
|
|
645
|
+
storeRef.current = createVoiceOpsActionCenterStore(options);
|
|
646
|
+
}
|
|
647
|
+
const store = storeRef.current;
|
|
648
|
+
useEffect2(() => () => store.close(), [store]);
|
|
649
|
+
return {
|
|
650
|
+
...useSyncExternalStore2(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
651
|
+
run: store.run,
|
|
652
|
+
setActions: store.setActions
|
|
653
|
+
};
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
// src/react/VoiceOpsActionCenter.tsx
|
|
657
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
658
|
+
var VoiceOpsActionCenter = ({
|
|
659
|
+
className,
|
|
660
|
+
...options
|
|
661
|
+
}) => {
|
|
662
|
+
const snapshot = useVoiceOpsActionCenter(options);
|
|
663
|
+
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
664
|
+
return /* @__PURE__ */ jsxDEV2("section", {
|
|
665
|
+
className: [
|
|
666
|
+
"absolute-voice-ops-action-center",
|
|
667
|
+
`absolute-voice-ops-action-center--${model.status}`,
|
|
668
|
+
className
|
|
669
|
+
].filter(Boolean).join(" "),
|
|
670
|
+
children: [
|
|
671
|
+
/* @__PURE__ */ jsxDEV2("header", {
|
|
672
|
+
className: "absolute-voice-ops-action-center__header",
|
|
673
|
+
children: [
|
|
674
|
+
/* @__PURE__ */ jsxDEV2("span", {
|
|
675
|
+
className: "absolute-voice-ops-action-center__eyebrow",
|
|
676
|
+
children: model.title
|
|
677
|
+
}, undefined, false, undefined, this),
|
|
678
|
+
/* @__PURE__ */ jsxDEV2("strong", {
|
|
679
|
+
className: "absolute-voice-ops-action-center__label",
|
|
680
|
+
children: model.label
|
|
681
|
+
}, undefined, false, undefined, this)
|
|
682
|
+
]
|
|
683
|
+
}, undefined, true, undefined, this),
|
|
684
|
+
/* @__PURE__ */ jsxDEV2("p", {
|
|
685
|
+
className: "absolute-voice-ops-action-center__description",
|
|
686
|
+
children: model.description
|
|
687
|
+
}, undefined, false, undefined, this),
|
|
688
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
689
|
+
className: "absolute-voice-ops-action-center__actions",
|
|
690
|
+
children: model.actions.map((action) => /* @__PURE__ */ jsxDEV2("button", {
|
|
691
|
+
disabled: action.disabled,
|
|
692
|
+
onClick: () => {
|
|
693
|
+
snapshot.run(action.id).catch(() => {});
|
|
694
|
+
},
|
|
695
|
+
type: "button",
|
|
696
|
+
children: action.isRunning ? "Working..." : action.label
|
|
697
|
+
}, action.id, false, undefined, this))
|
|
698
|
+
}, undefined, false, undefined, this),
|
|
699
|
+
/* @__PURE__ */ jsxDEV2("p", {
|
|
700
|
+
className: "absolute-voice-ops-action-center__result",
|
|
701
|
+
children: model.lastResultLabel
|
|
702
|
+
}, undefined, false, undefined, this),
|
|
703
|
+
model.error ? /* @__PURE__ */ jsxDEV2("p", {
|
|
704
|
+
className: "absolute-voice-ops-action-center__error",
|
|
705
|
+
children: model.error
|
|
706
|
+
}, undefined, false, undefined, this) : null
|
|
707
|
+
]
|
|
708
|
+
}, undefined, true, undefined, this);
|
|
709
|
+
};
|
|
390
710
|
// src/client/deliveryRuntime.ts
|
|
711
|
+
var getDefaultActionPath = (path, action, options) => {
|
|
712
|
+
if (action === "tick") {
|
|
713
|
+
return options.tickPath ?? `${path.replace(/\/$/, "")}/tick`;
|
|
714
|
+
}
|
|
715
|
+
return options.requeueDeadLettersPath ?? `${path.replace(/\/$/, "")}/requeue-dead-letters`;
|
|
716
|
+
};
|
|
391
717
|
var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
|
|
392
718
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
393
719
|
const response = await fetchImpl(path);
|
|
@@ -396,11 +722,29 @@ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", opt
|
|
|
396
722
|
}
|
|
397
723
|
return await response.json();
|
|
398
724
|
};
|
|
725
|
+
var runVoiceDeliveryRuntimeAction = async (action, path = "/api/voice-delivery-runtime", options = {}) => {
|
|
726
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
727
|
+
const response = await fetchImpl(getDefaultActionPath(path, action, options), {
|
|
728
|
+
method: "POST"
|
|
729
|
+
});
|
|
730
|
+
if (!response.ok) {
|
|
731
|
+
throw new Error(`Voice delivery runtime ${action} failed: HTTP ${response.status}`);
|
|
732
|
+
}
|
|
733
|
+
const body = await response.json();
|
|
734
|
+
return {
|
|
735
|
+
action,
|
|
736
|
+
result: body.result,
|
|
737
|
+
summary: body.summary,
|
|
738
|
+
updatedAt: Date.now()
|
|
739
|
+
};
|
|
740
|
+
};
|
|
399
741
|
var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
|
|
400
742
|
const listeners = new Set;
|
|
401
743
|
let closed = false;
|
|
402
744
|
let timer;
|
|
403
745
|
let snapshot = {
|
|
746
|
+
actionError: null,
|
|
747
|
+
actionStatus: "idle",
|
|
404
748
|
error: null,
|
|
405
749
|
isLoading: false
|
|
406
750
|
};
|
|
@@ -422,6 +766,7 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
422
766
|
try {
|
|
423
767
|
const report = await fetchVoiceDeliveryRuntime(path, options);
|
|
424
768
|
snapshot = {
|
|
769
|
+
...snapshot,
|
|
425
770
|
error: null,
|
|
426
771
|
isLoading: false,
|
|
427
772
|
report,
|
|
@@ -439,6 +784,37 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
439
784
|
throw error;
|
|
440
785
|
}
|
|
441
786
|
};
|
|
787
|
+
const runAction = async (action) => {
|
|
788
|
+
if (closed) {
|
|
789
|
+
return snapshot.lastAction;
|
|
790
|
+
}
|
|
791
|
+
snapshot = {
|
|
792
|
+
...snapshot,
|
|
793
|
+
actionError: null,
|
|
794
|
+
actionStatus: "running"
|
|
795
|
+
};
|
|
796
|
+
emit();
|
|
797
|
+
try {
|
|
798
|
+
const result = await runVoiceDeliveryRuntimeAction(action, path, options);
|
|
799
|
+
snapshot = {
|
|
800
|
+
...snapshot,
|
|
801
|
+
actionError: null,
|
|
802
|
+
actionStatus: "completed",
|
|
803
|
+
lastAction: result
|
|
804
|
+
};
|
|
805
|
+
emit();
|
|
806
|
+
await refresh();
|
|
807
|
+
return result;
|
|
808
|
+
} catch (error) {
|
|
809
|
+
snapshot = {
|
|
810
|
+
...snapshot,
|
|
811
|
+
actionError: error instanceof Error ? error.message : String(error),
|
|
812
|
+
actionStatus: "failed"
|
|
813
|
+
};
|
|
814
|
+
emit();
|
|
815
|
+
throw error;
|
|
816
|
+
}
|
|
817
|
+
};
|
|
442
818
|
const close = () => {
|
|
443
819
|
closed = true;
|
|
444
820
|
if (timer) {
|
|
@@ -456,7 +832,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
456
832
|
close,
|
|
457
833
|
getServerSnapshot: () => snapshot,
|
|
458
834
|
getSnapshot: () => snapshot,
|
|
835
|
+
requeueDeadLetters: () => runAction("requeue-dead-letters"),
|
|
459
836
|
refresh,
|
|
837
|
+
tick: () => runAction("tick"),
|
|
460
838
|
subscribe: (listener) => {
|
|
461
839
|
listeners.add(listener);
|
|
462
840
|
return () => {
|
|
@@ -467,9 +845,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
467
845
|
};
|
|
468
846
|
|
|
469
847
|
// src/client/deliveryRuntimeWidget.ts
|
|
470
|
-
var
|
|
471
|
-
var
|
|
472
|
-
var
|
|
848
|
+
var DEFAULT_TITLE3 = "Voice Delivery Runtime";
|
|
849
|
+
var DEFAULT_DESCRIPTION3 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
850
|
+
var escapeHtml3 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
473
851
|
var createSurface = (id, summary) => {
|
|
474
852
|
if (!summary) {
|
|
475
853
|
return {
|
|
@@ -503,45 +881,70 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
503
881
|
];
|
|
504
882
|
const hasWarnings = surfaces.some((surface) => surface.status === "warn");
|
|
505
883
|
return {
|
|
506
|
-
description: options.description ??
|
|
884
|
+
description: options.description ?? DEFAULT_DESCRIPTION3,
|
|
507
885
|
error: snapshot.error,
|
|
886
|
+
actionError: snapshot.actionError,
|
|
887
|
+
actionStatus: snapshot.actionStatus,
|
|
508
888
|
isLoading: snapshot.isLoading,
|
|
509
889
|
isRunning: Boolean(report?.isRunning),
|
|
510
890
|
label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
|
|
511
891
|
status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
|
|
512
892
|
surfaces,
|
|
513
|
-
title: options.title ??
|
|
893
|
+
title: options.title ?? DEFAULT_TITLE3,
|
|
514
894
|
updatedAt: snapshot.updatedAt
|
|
515
895
|
};
|
|
516
896
|
};
|
|
517
897
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
518
898
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
519
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
520
|
-
<span>${
|
|
521
|
-
<strong>${
|
|
899
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml3(surface.status)}">
|
|
900
|
+
<span>${escapeHtml3(surface.label)}</span>
|
|
901
|
+
<strong>${escapeHtml3(surface.detail)}</strong>
|
|
522
902
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
523
903
|
</li>`).join("");
|
|
524
|
-
|
|
904
|
+
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
905
|
+
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
906
|
+
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
907
|
+
</div>`;
|
|
908
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.actionError)}</p>` : "";
|
|
909
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml3(model.status)}">
|
|
525
910
|
<header class="absolute-voice-delivery-runtime__header">
|
|
526
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
527
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
911
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml3(model.title)}</span>
|
|
912
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml3(model.label)}</strong>
|
|
528
913
|
</header>
|
|
529
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
914
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml3(model.description)}</p>
|
|
530
915
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
531
|
-
${
|
|
916
|
+
${actions}
|
|
917
|
+
${actionError}
|
|
918
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.error)}</p>` : ""}
|
|
532
919
|
</section>`;
|
|
533
920
|
};
|
|
534
|
-
var getVoiceDeliveryRuntimeCSS = () => `.absolute-voice-delivery-runtime{border:1px solid #c9d8cf;border-radius:20px;background:#f6fff9;color:#0d1b12;padding:18px;box-shadow:0 18px 40px rgba(19,55,35,.12);font-family:inherit}.absolute-voice-delivery-runtime--warn,.absolute-voice-delivery-runtime--error{border-color:#f2b56b;background:#fff9ed}.absolute-voice-delivery-runtime__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-delivery-runtime__eyebrow{color:#4e6b59;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-delivery-runtime__label{font-size:28px;line-height:1}.absolute-voice-delivery-runtime__description{color:#33483b;margin:12px 0 0}.absolute-voice-delivery-runtime__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-delivery-runtime__surface{background:#fff;border:1px solid #d9eadf;border-radius:14px;display:grid;gap:4px;padding:10px 12px}.absolute-voice-delivery-runtime__surface--warn{border-color:#f2b56b}.absolute-voice-delivery-runtime__surface--disabled{opacity:.72}.absolute-voice-delivery-runtime__surface span,.absolute-voice-delivery-runtime__surface small{color:#587063}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
|
|
921
|
+
var getVoiceDeliveryRuntimeCSS = () => `.absolute-voice-delivery-runtime{border:1px solid #c9d8cf;border-radius:20px;background:#f6fff9;color:#0d1b12;padding:18px;box-shadow:0 18px 40px rgba(19,55,35,.12);font-family:inherit}.absolute-voice-delivery-runtime--warn,.absolute-voice-delivery-runtime--error{border-color:#f2b56b;background:#fff9ed}.absolute-voice-delivery-runtime__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-delivery-runtime__eyebrow{color:#4e6b59;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-delivery-runtime__label{font-size:28px;line-height:1}.absolute-voice-delivery-runtime__description{color:#33483b;margin:12px 0 0}.absolute-voice-delivery-runtime__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-delivery-runtime__surface{background:#fff;border:1px solid #d9eadf;border-radius:14px;display:grid;gap:4px;padding:10px 12px}.absolute-voice-delivery-runtime__surface--warn{border-color:#f2b56b}.absolute-voice-delivery-runtime__surface--disabled{opacity:.72}.absolute-voice-delivery-runtime__surface span,.absolute-voice-delivery-runtime__surface small{color:#587063}.absolute-voice-delivery-runtime__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-delivery-runtime__actions button{background:#134e2d;border:0;border-radius:999px;color:#f6fff9;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-delivery-runtime__actions button:disabled{cursor:not-allowed;opacity:.48}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
|
|
535
922
|
var mountVoiceDeliveryRuntime = (element, path = "/api/voice-delivery-runtime", options = {}) => {
|
|
536
923
|
const store = createVoiceDeliveryRuntimeStore(path, options);
|
|
537
924
|
const render = () => {
|
|
538
925
|
element.innerHTML = renderVoiceDeliveryRuntimeHTML(store.getSnapshot(), options);
|
|
539
926
|
};
|
|
540
927
|
const unsubscribe = store.subscribe(render);
|
|
928
|
+
const handleClick = (event) => {
|
|
929
|
+
const target = event.target;
|
|
930
|
+
if (!(target instanceof Element)) {
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
const action = target.closest("[data-absolute-voice-delivery-runtime-action]");
|
|
934
|
+
const actionName = action?.getAttribute("data-absolute-voice-delivery-runtime-action");
|
|
935
|
+
if (actionName === "tick") {
|
|
936
|
+
store.tick().catch(() => {});
|
|
937
|
+
}
|
|
938
|
+
if (actionName === "requeue-dead-letters") {
|
|
939
|
+
store.requeueDeadLetters().catch(() => {});
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
element.addEventListener?.("click", handleClick);
|
|
541
943
|
render();
|
|
542
944
|
store.refresh().catch(() => {});
|
|
543
945
|
return {
|
|
544
946
|
close: () => {
|
|
947
|
+
element.removeEventListener?.("click", handleClick);
|
|
545
948
|
unsubscribe();
|
|
546
949
|
store.close();
|
|
547
950
|
},
|
|
@@ -570,68 +973,72 @@ var defineVoiceDeliveryRuntimeElement = (tagName = "absolute-voice-delivery-runt
|
|
|
570
973
|
};
|
|
571
974
|
|
|
572
975
|
// src/react/useVoiceDeliveryRuntime.tsx
|
|
573
|
-
import { useEffect as
|
|
976
|
+
import { useEffect as useEffect3, useRef as useRef3, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
574
977
|
var useVoiceDeliveryRuntime = (path = "/api/voice-delivery-runtime", options = {}) => {
|
|
575
|
-
const storeRef =
|
|
978
|
+
const storeRef = useRef3(null);
|
|
576
979
|
if (!storeRef.current) {
|
|
577
980
|
storeRef.current = createVoiceDeliveryRuntimeStore(path, options);
|
|
578
981
|
}
|
|
579
982
|
const store = storeRef.current;
|
|
580
|
-
|
|
983
|
+
useEffect3(() => {
|
|
581
984
|
store.refresh().catch(() => {});
|
|
582
985
|
return () => store.close();
|
|
583
986
|
}, [store]);
|
|
584
987
|
return {
|
|
585
|
-
...
|
|
586
|
-
|
|
988
|
+
...useSyncExternalStore3(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
989
|
+
requeueDeadLetters: store.requeueDeadLetters,
|
|
990
|
+
refresh: store.refresh,
|
|
991
|
+
tick: store.tick
|
|
587
992
|
};
|
|
588
993
|
};
|
|
589
994
|
|
|
590
995
|
// src/react/VoiceDeliveryRuntime.tsx
|
|
591
|
-
import { jsxDEV as
|
|
996
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
592
997
|
var VoiceDeliveryRuntime = ({
|
|
593
998
|
className,
|
|
999
|
+
includeActions = true,
|
|
594
1000
|
path = "/api/voice-delivery-runtime",
|
|
595
1001
|
...options
|
|
596
1002
|
}) => {
|
|
597
1003
|
const snapshot = useVoiceDeliveryRuntime(path, options);
|
|
598
1004
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
599
|
-
|
|
1005
|
+
const hasDeadLetters = model.surfaces.some((surface) => surface.deadLettered > 0);
|
|
1006
|
+
return /* @__PURE__ */ jsxDEV3("section", {
|
|
600
1007
|
className: [
|
|
601
1008
|
"absolute-voice-delivery-runtime",
|
|
602
1009
|
`absolute-voice-delivery-runtime--${model.status}`,
|
|
603
1010
|
className
|
|
604
1011
|
].filter(Boolean).join(" "),
|
|
605
1012
|
children: [
|
|
606
|
-
/* @__PURE__ */
|
|
1013
|
+
/* @__PURE__ */ jsxDEV3("header", {
|
|
607
1014
|
className: "absolute-voice-delivery-runtime__header",
|
|
608
1015
|
children: [
|
|
609
|
-
/* @__PURE__ */
|
|
1016
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
610
1017
|
className: "absolute-voice-delivery-runtime__eyebrow",
|
|
611
1018
|
children: model.title
|
|
612
1019
|
}, undefined, false, undefined, this),
|
|
613
|
-
/* @__PURE__ */
|
|
1020
|
+
/* @__PURE__ */ jsxDEV3("strong", {
|
|
614
1021
|
className: "absolute-voice-delivery-runtime__label",
|
|
615
1022
|
children: model.label
|
|
616
1023
|
}, undefined, false, undefined, this)
|
|
617
1024
|
]
|
|
618
1025
|
}, undefined, true, undefined, this),
|
|
619
|
-
/* @__PURE__ */
|
|
1026
|
+
/* @__PURE__ */ jsxDEV3("p", {
|
|
620
1027
|
className: "absolute-voice-delivery-runtime__description",
|
|
621
1028
|
children: model.description
|
|
622
1029
|
}, undefined, false, undefined, this),
|
|
623
|
-
/* @__PURE__ */
|
|
1030
|
+
/* @__PURE__ */ jsxDEV3("ul", {
|
|
624
1031
|
className: "absolute-voice-delivery-runtime__surfaces",
|
|
625
|
-
children: model.surfaces.map((surface) => /* @__PURE__ */
|
|
1032
|
+
children: model.surfaces.map((surface) => /* @__PURE__ */ jsxDEV3("li", {
|
|
626
1033
|
className: `absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${surface.status}`,
|
|
627
1034
|
children: [
|
|
628
|
-
/* @__PURE__ */
|
|
1035
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
629
1036
|
children: surface.label
|
|
630
1037
|
}, undefined, false, undefined, this),
|
|
631
|
-
/* @__PURE__ */
|
|
1038
|
+
/* @__PURE__ */ jsxDEV3("strong", {
|
|
632
1039
|
children: surface.detail
|
|
633
1040
|
}, undefined, false, undefined, this),
|
|
634
|
-
/* @__PURE__ */
|
|
1041
|
+
/* @__PURE__ */ jsxDEV3("small", {
|
|
635
1042
|
children: [
|
|
636
1043
|
surface.failed,
|
|
637
1044
|
" failed / ",
|
|
@@ -642,7 +1049,32 @@ var VoiceDeliveryRuntime = ({
|
|
|
642
1049
|
]
|
|
643
1050
|
}, surface.id, true, undefined, this))
|
|
644
1051
|
}, undefined, false, undefined, this),
|
|
645
|
-
|
|
1052
|
+
includeActions ? /* @__PURE__ */ jsxDEV3("div", {
|
|
1053
|
+
className: "absolute-voice-delivery-runtime__actions",
|
|
1054
|
+
children: [
|
|
1055
|
+
/* @__PURE__ */ jsxDEV3("button", {
|
|
1056
|
+
disabled: model.actionStatus === "running",
|
|
1057
|
+
onClick: () => {
|
|
1058
|
+
snapshot.tick().catch(() => {});
|
|
1059
|
+
},
|
|
1060
|
+
type: "button",
|
|
1061
|
+
children: model.actionStatus === "running" ? "Working..." : "Tick workers"
|
|
1062
|
+
}, undefined, false, undefined, this),
|
|
1063
|
+
/* @__PURE__ */ jsxDEV3("button", {
|
|
1064
|
+
disabled: model.actionStatus === "running" || !hasDeadLetters,
|
|
1065
|
+
onClick: () => {
|
|
1066
|
+
snapshot.requeueDeadLetters().catch(() => {});
|
|
1067
|
+
},
|
|
1068
|
+
type: "button",
|
|
1069
|
+
children: "Requeue dead letters"
|
|
1070
|
+
}, undefined, false, undefined, this)
|
|
1071
|
+
]
|
|
1072
|
+
}, undefined, true, undefined, this) : null,
|
|
1073
|
+
model.actionError ? /* @__PURE__ */ jsxDEV3("p", {
|
|
1074
|
+
className: "absolute-voice-delivery-runtime__error",
|
|
1075
|
+
children: model.actionError
|
|
1076
|
+
}, undefined, false, undefined, this) : null,
|
|
1077
|
+
model.error ? /* @__PURE__ */ jsxDEV3("p", {
|
|
646
1078
|
className: "absolute-voice-delivery-runtime__error",
|
|
647
1079
|
children: model.error
|
|
648
1080
|
}, undefined, false, undefined, this) : null
|
|
@@ -729,7 +1161,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
729
1161
|
};
|
|
730
1162
|
|
|
731
1163
|
// src/client/providerSimulationControlsWidget.ts
|
|
732
|
-
var
|
|
1164
|
+
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
733
1165
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
734
1166
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
735
1167
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -749,18 +1181,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
749
1181
|
};
|
|
750
1182
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
751
1183
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
752
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
753
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
1184
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml4(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml4(provider.provider)} ${escapeHtml4(formatKind(options.kind))} failure</button>`).join("");
|
|
1185
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml4(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml4(provider.provider)} recovered</button>`).join("");
|
|
754
1186
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
755
1187
|
<header class="absolute-voice-provider-simulation__header">
|
|
756
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
757
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
1188
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml4(model.title)}</span>
|
|
1189
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml4(model.label)}</strong>
|
|
758
1190
|
</header>
|
|
759
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
760
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
1191
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml4(model.description)}</p>
|
|
1192
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml4(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
761
1193
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
762
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
763
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
1194
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml4(snapshot.error)}</p>` : ""}
|
|
1195
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml4(model.resultText)}</pre>` : ""}
|
|
764
1196
|
</section>`;
|
|
765
1197
|
};
|
|
766
1198
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -826,22 +1258,22 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
|
|
|
826
1258
|
};
|
|
827
1259
|
|
|
828
1260
|
// src/react/useVoiceProviderSimulationControls.tsx
|
|
829
|
-
import { useEffect as
|
|
1261
|
+
import { useEffect as useEffect4, useRef as useRef4, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
830
1262
|
var useVoiceProviderSimulationControls = (options) => {
|
|
831
|
-
const storeRef =
|
|
1263
|
+
const storeRef = useRef4(null);
|
|
832
1264
|
if (!storeRef.current) {
|
|
833
1265
|
storeRef.current = createVoiceProviderSimulationControlsStore(options);
|
|
834
1266
|
}
|
|
835
1267
|
const store = storeRef.current;
|
|
836
|
-
|
|
1268
|
+
useEffect4(() => () => store.close(), [store]);
|
|
837
1269
|
return {
|
|
838
|
-
...
|
|
1270
|
+
...useSyncExternalStore4(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
839
1271
|
run: store.run
|
|
840
1272
|
};
|
|
841
1273
|
};
|
|
842
1274
|
|
|
843
1275
|
// src/react/VoiceProviderSimulationControls.tsx
|
|
844
|
-
import { jsxDEV as
|
|
1276
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
845
1277
|
var VoiceProviderSimulationControls = ({
|
|
846
1278
|
className,
|
|
847
1279
|
...options
|
|
@@ -851,38 +1283,38 @@ var VoiceProviderSimulationControls = ({
|
|
|
851
1283
|
const run = (provider, mode) => {
|
|
852
1284
|
snapshot.run(provider, mode).catch(() => {});
|
|
853
1285
|
};
|
|
854
|
-
return /* @__PURE__ */
|
|
1286
|
+
return /* @__PURE__ */ jsxDEV4("section", {
|
|
855
1287
|
className: [
|
|
856
1288
|
"absolute-voice-provider-simulation",
|
|
857
1289
|
`absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}`,
|
|
858
1290
|
className
|
|
859
1291
|
].filter(Boolean).join(" "),
|
|
860
1292
|
children: [
|
|
861
|
-
/* @__PURE__ */
|
|
1293
|
+
/* @__PURE__ */ jsxDEV4("header", {
|
|
862
1294
|
className: "absolute-voice-provider-simulation__header",
|
|
863
1295
|
children: [
|
|
864
|
-
/* @__PURE__ */
|
|
1296
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
865
1297
|
className: "absolute-voice-provider-simulation__eyebrow",
|
|
866
1298
|
children: model.title
|
|
867
1299
|
}, undefined, false, undefined, this),
|
|
868
|
-
/* @__PURE__ */
|
|
1300
|
+
/* @__PURE__ */ jsxDEV4("strong", {
|
|
869
1301
|
className: "absolute-voice-provider-simulation__label",
|
|
870
1302
|
children: model.label
|
|
871
1303
|
}, undefined, false, undefined, this)
|
|
872
1304
|
]
|
|
873
1305
|
}, undefined, true, undefined, this),
|
|
874
|
-
/* @__PURE__ */
|
|
1306
|
+
/* @__PURE__ */ jsxDEV4("p", {
|
|
875
1307
|
className: "absolute-voice-provider-simulation__description",
|
|
876
1308
|
children: model.description
|
|
877
1309
|
}, undefined, false, undefined, this),
|
|
878
|
-
model.canSimulateFailure ? null : /* @__PURE__ */
|
|
1310
|
+
model.canSimulateFailure ? null : /* @__PURE__ */ jsxDEV4("p", {
|
|
879
1311
|
className: "absolute-voice-provider-simulation__empty",
|
|
880
1312
|
children: options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."
|
|
881
1313
|
}, undefined, false, undefined, this),
|
|
882
|
-
/* @__PURE__ */
|
|
1314
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
883
1315
|
className: "absolute-voice-provider-simulation__actions",
|
|
884
1316
|
children: [
|
|
885
|
-
model.failureProviders.map((provider) => /* @__PURE__ */
|
|
1317
|
+
model.failureProviders.map((provider) => /* @__PURE__ */ jsxDEV4("button", {
|
|
886
1318
|
disabled: !model.canSimulateFailure || snapshot.isRunning,
|
|
887
1319
|
onClick: () => run(provider.provider, "failure"),
|
|
888
1320
|
type: "button",
|
|
@@ -895,7 +1327,7 @@ var VoiceProviderSimulationControls = ({
|
|
|
895
1327
|
"failure"
|
|
896
1328
|
]
|
|
897
1329
|
}, `fail-${provider.provider}`, true, undefined, this)),
|
|
898
|
-
model.providers.map((provider) => /* @__PURE__ */
|
|
1330
|
+
model.providers.map((provider) => /* @__PURE__ */ jsxDEV4("button", {
|
|
899
1331
|
disabled: snapshot.isRunning,
|
|
900
1332
|
onClick: () => run(provider.provider, "recovery"),
|
|
901
1333
|
type: "button",
|
|
@@ -907,11 +1339,11 @@ var VoiceProviderSimulationControls = ({
|
|
|
907
1339
|
}, `recover-${provider.provider}`, true, undefined, this))
|
|
908
1340
|
]
|
|
909
1341
|
}, undefined, true, undefined, this),
|
|
910
|
-
snapshot.error ? /* @__PURE__ */
|
|
1342
|
+
snapshot.error ? /* @__PURE__ */ jsxDEV4("p", {
|
|
911
1343
|
className: "absolute-voice-provider-simulation__error",
|
|
912
1344
|
children: snapshot.error
|
|
913
1345
|
}, undefined, false, undefined, this) : null,
|
|
914
|
-
model.resultText ? /* @__PURE__ */
|
|
1346
|
+
model.resultText ? /* @__PURE__ */ jsxDEV4("pre", {
|
|
915
1347
|
className: "absolute-voice-provider-simulation__result",
|
|
916
1348
|
children: model.resultText
|
|
917
1349
|
}, undefined, false, undefined, this) : null
|
|
@@ -919,7 +1351,7 @@ var VoiceProviderSimulationControls = ({
|
|
|
919
1351
|
}, undefined, true, undefined, this);
|
|
920
1352
|
};
|
|
921
1353
|
// src/react/useVoiceProviderCapabilities.tsx
|
|
922
|
-
import { useEffect as
|
|
1354
|
+
import { useEffect as useEffect5, useRef as useRef5, useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
923
1355
|
|
|
924
1356
|
// src/client/providerCapabilities.ts
|
|
925
1357
|
var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
|
|
@@ -1002,25 +1434,25 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
|
|
|
1002
1434
|
|
|
1003
1435
|
// src/react/useVoiceProviderCapabilities.tsx
|
|
1004
1436
|
var useVoiceProviderCapabilities = (path = "/api/provider-capabilities", options = {}) => {
|
|
1005
|
-
const storeRef =
|
|
1437
|
+
const storeRef = useRef5(null);
|
|
1006
1438
|
if (!storeRef.current) {
|
|
1007
1439
|
storeRef.current = createVoiceProviderCapabilitiesStore(path, options);
|
|
1008
1440
|
}
|
|
1009
1441
|
const store = storeRef.current;
|
|
1010
|
-
|
|
1442
|
+
useEffect5(() => {
|
|
1011
1443
|
store.refresh().catch(() => {});
|
|
1012
1444
|
return () => store.close();
|
|
1013
1445
|
}, [store]);
|
|
1014
1446
|
return {
|
|
1015
|
-
...
|
|
1447
|
+
...useSyncExternalStore5(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1016
1448
|
refresh: store.refresh
|
|
1017
1449
|
};
|
|
1018
1450
|
};
|
|
1019
1451
|
|
|
1020
1452
|
// src/client/providerCapabilitiesWidget.ts
|
|
1021
|
-
var
|
|
1022
|
-
var
|
|
1023
|
-
var
|
|
1453
|
+
var DEFAULT_TITLE4 = "Provider Capabilities";
|
|
1454
|
+
var DEFAULT_DESCRIPTION4 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
1455
|
+
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1024
1456
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1025
1457
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
1026
1458
|
var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -1064,36 +1496,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
1064
1496
|
const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
|
|
1065
1497
|
return {
|
|
1066
1498
|
capabilities,
|
|
1067
|
-
description: options.description ??
|
|
1499
|
+
description: options.description ?? DEFAULT_DESCRIPTION4,
|
|
1068
1500
|
error: snapshot.error,
|
|
1069
1501
|
isLoading: snapshot.isLoading,
|
|
1070
1502
|
label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
|
|
1071
1503
|
status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1072
|
-
title: options.title ??
|
|
1504
|
+
title: options.title ?? DEFAULT_TITLE4,
|
|
1073
1505
|
updatedAt: snapshot.updatedAt
|
|
1074
1506
|
};
|
|
1075
1507
|
};
|
|
1076
1508
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
1077
1509
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
1078
|
-
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--${
|
|
1510
|
+
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--${escapeHtml5(capability.status)}">
|
|
1079
1511
|
<header>
|
|
1080
|
-
<strong>${
|
|
1081
|
-
<span>${
|
|
1512
|
+
<strong>${escapeHtml5(capability.label)}</strong>
|
|
1513
|
+
<span>${escapeHtml5(formatStatus(capability.status))}</span>
|
|
1082
1514
|
</header>
|
|
1083
|
-
<p>${
|
|
1515
|
+
<p>${escapeHtml5(capability.detail)}</p>
|
|
1084
1516
|
<dl>${capability.rows.map((row) => `<div>
|
|
1085
|
-
<dt>${
|
|
1086
|
-
<dd>${
|
|
1517
|
+
<dt>${escapeHtml5(row.label)}</dt>
|
|
1518
|
+
<dd>${escapeHtml5(row.value)}</dd>
|
|
1087
1519
|
</div>`).join("")}</dl>
|
|
1088
1520
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
1089
|
-
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${
|
|
1521
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml5(model.status)}">
|
|
1090
1522
|
<header class="absolute-voice-provider-capabilities__header">
|
|
1091
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
1092
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
1523
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml5(model.title)}</span>
|
|
1524
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml5(model.label)}</strong>
|
|
1093
1525
|
</header>
|
|
1094
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
1526
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml5(model.description)}</p>
|
|
1095
1527
|
${capabilities}
|
|
1096
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
1528
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml5(model.error)}</p>` : ""}
|
|
1097
1529
|
</section>`;
|
|
1098
1530
|
};
|
|
1099
1531
|
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}`;
|
|
@@ -1135,7 +1567,7 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
|
|
|
1135
1567
|
};
|
|
1136
1568
|
|
|
1137
1569
|
// src/react/VoiceProviderCapabilities.tsx
|
|
1138
|
-
import { jsxDEV as
|
|
1570
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
1139
1571
|
var VoiceProviderCapabilities = ({
|
|
1140
1572
|
className,
|
|
1141
1573
|
path = "/api/provider-capabilities",
|
|
@@ -1143,58 +1575,58 @@ var VoiceProviderCapabilities = ({
|
|
|
1143
1575
|
}) => {
|
|
1144
1576
|
const snapshot = useVoiceProviderCapabilities(path, options);
|
|
1145
1577
|
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
1146
|
-
return /* @__PURE__ */
|
|
1578
|
+
return /* @__PURE__ */ jsxDEV5("section", {
|
|
1147
1579
|
className: [
|
|
1148
1580
|
"absolute-voice-provider-capabilities",
|
|
1149
1581
|
`absolute-voice-provider-capabilities--${model.status}`,
|
|
1150
1582
|
className
|
|
1151
1583
|
].filter(Boolean).join(" "),
|
|
1152
1584
|
children: [
|
|
1153
|
-
/* @__PURE__ */
|
|
1585
|
+
/* @__PURE__ */ jsxDEV5("header", {
|
|
1154
1586
|
className: "absolute-voice-provider-capabilities__header",
|
|
1155
1587
|
children: [
|
|
1156
|
-
/* @__PURE__ */
|
|
1588
|
+
/* @__PURE__ */ jsxDEV5("span", {
|
|
1157
1589
|
className: "absolute-voice-provider-capabilities__eyebrow",
|
|
1158
1590
|
children: model.title
|
|
1159
1591
|
}, undefined, false, undefined, this),
|
|
1160
|
-
/* @__PURE__ */
|
|
1592
|
+
/* @__PURE__ */ jsxDEV5("strong", {
|
|
1161
1593
|
className: "absolute-voice-provider-capabilities__label",
|
|
1162
1594
|
children: model.label
|
|
1163
1595
|
}, undefined, false, undefined, this)
|
|
1164
1596
|
]
|
|
1165
1597
|
}, undefined, true, undefined, this),
|
|
1166
|
-
/* @__PURE__ */
|
|
1598
|
+
/* @__PURE__ */ jsxDEV5("p", {
|
|
1167
1599
|
className: "absolute-voice-provider-capabilities__description",
|
|
1168
1600
|
children: model.description
|
|
1169
1601
|
}, undefined, false, undefined, this),
|
|
1170
|
-
model.capabilities.length ? /* @__PURE__ */
|
|
1602
|
+
model.capabilities.length ? /* @__PURE__ */ jsxDEV5("div", {
|
|
1171
1603
|
className: "absolute-voice-provider-capabilities__providers",
|
|
1172
|
-
children: model.capabilities.map((capability) => /* @__PURE__ */
|
|
1604
|
+
children: model.capabilities.map((capability) => /* @__PURE__ */ jsxDEV5("article", {
|
|
1173
1605
|
className: [
|
|
1174
1606
|
"absolute-voice-provider-capabilities__provider",
|
|
1175
1607
|
`absolute-voice-provider-capabilities__provider--${capability.status}`
|
|
1176
1608
|
].join(" "),
|
|
1177
1609
|
children: [
|
|
1178
|
-
/* @__PURE__ */
|
|
1610
|
+
/* @__PURE__ */ jsxDEV5("header", {
|
|
1179
1611
|
children: [
|
|
1180
|
-
/* @__PURE__ */
|
|
1612
|
+
/* @__PURE__ */ jsxDEV5("strong", {
|
|
1181
1613
|
children: capability.label
|
|
1182
1614
|
}, undefined, false, undefined, this),
|
|
1183
|
-
/* @__PURE__ */
|
|
1615
|
+
/* @__PURE__ */ jsxDEV5("span", {
|
|
1184
1616
|
children: capability.status
|
|
1185
1617
|
}, undefined, false, undefined, this)
|
|
1186
1618
|
]
|
|
1187
1619
|
}, undefined, true, undefined, this),
|
|
1188
|
-
/* @__PURE__ */
|
|
1620
|
+
/* @__PURE__ */ jsxDEV5("p", {
|
|
1189
1621
|
children: capability.detail
|
|
1190
1622
|
}, undefined, false, undefined, this),
|
|
1191
|
-
/* @__PURE__ */
|
|
1192
|
-
children: capability.rows.map((row) => /* @__PURE__ */
|
|
1623
|
+
/* @__PURE__ */ jsxDEV5("dl", {
|
|
1624
|
+
children: capability.rows.map((row) => /* @__PURE__ */ jsxDEV5("div", {
|
|
1193
1625
|
children: [
|
|
1194
|
-
/* @__PURE__ */
|
|
1626
|
+
/* @__PURE__ */ jsxDEV5("dt", {
|
|
1195
1627
|
children: row.label
|
|
1196
1628
|
}, undefined, false, undefined, this),
|
|
1197
|
-
/* @__PURE__ */
|
|
1629
|
+
/* @__PURE__ */ jsxDEV5("dd", {
|
|
1198
1630
|
children: row.value
|
|
1199
1631
|
}, undefined, false, undefined, this)
|
|
1200
1632
|
]
|
|
@@ -1202,11 +1634,11 @@ var VoiceProviderCapabilities = ({
|
|
|
1202
1634
|
}, undefined, false, undefined, this)
|
|
1203
1635
|
]
|
|
1204
1636
|
}, `${capability.kind}:${capability.provider}`, true, undefined, this))
|
|
1205
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
1637
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5("p", {
|
|
1206
1638
|
className: "absolute-voice-provider-capabilities__empty",
|
|
1207
1639
|
children: "Configure provider capabilities to see deployment coverage."
|
|
1208
1640
|
}, undefined, false, undefined, this),
|
|
1209
|
-
model.error ? /* @__PURE__ */
|
|
1641
|
+
model.error ? /* @__PURE__ */ jsxDEV5("p", {
|
|
1210
1642
|
className: "absolute-voice-provider-capabilities__error",
|
|
1211
1643
|
children: model.error
|
|
1212
1644
|
}, undefined, false, undefined, this) : null
|
|
@@ -1214,7 +1646,7 @@ var VoiceProviderCapabilities = ({
|
|
|
1214
1646
|
}, undefined, true, undefined, this);
|
|
1215
1647
|
};
|
|
1216
1648
|
// src/react/useVoiceProviderStatus.tsx
|
|
1217
|
-
import { useEffect as
|
|
1649
|
+
import { useEffect as useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
|
|
1218
1650
|
|
|
1219
1651
|
// src/client/providerStatus.ts
|
|
1220
1652
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
@@ -1298,25 +1730,25 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
1298
1730
|
|
|
1299
1731
|
// src/react/useVoiceProviderStatus.tsx
|
|
1300
1732
|
var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
1301
|
-
const storeRef =
|
|
1733
|
+
const storeRef = useRef6(null);
|
|
1302
1734
|
if (!storeRef.current) {
|
|
1303
1735
|
storeRef.current = createVoiceProviderStatusStore(path, options);
|
|
1304
1736
|
}
|
|
1305
1737
|
const store = storeRef.current;
|
|
1306
|
-
|
|
1738
|
+
useEffect6(() => {
|
|
1307
1739
|
store.refresh().catch(() => {});
|
|
1308
1740
|
return () => store.close();
|
|
1309
1741
|
}, [store]);
|
|
1310
1742
|
return {
|
|
1311
|
-
...
|
|
1743
|
+
...useSyncExternalStore6(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1312
1744
|
refresh: store.refresh
|
|
1313
1745
|
};
|
|
1314
1746
|
};
|
|
1315
1747
|
|
|
1316
1748
|
// src/client/providerStatusWidget.ts
|
|
1317
|
-
var
|
|
1318
|
-
var
|
|
1319
|
-
var
|
|
1749
|
+
var DEFAULT_TITLE5 = "Voice Providers";
|
|
1750
|
+
var DEFAULT_DESCRIPTION5 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
1751
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1320
1752
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1321
1753
|
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1322
1754
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -1360,37 +1792,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
1360
1792
|
const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
|
|
1361
1793
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
1362
1794
|
return {
|
|
1363
|
-
description: options.description ??
|
|
1795
|
+
description: options.description ?? DEFAULT_DESCRIPTION5,
|
|
1364
1796
|
error: snapshot.error,
|
|
1365
1797
|
isLoading: snapshot.isLoading,
|
|
1366
1798
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
1367
1799
|
providers,
|
|
1368
1800
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1369
|
-
title: options.title ??
|
|
1801
|
+
title: options.title ?? DEFAULT_TITLE5,
|
|
1370
1802
|
updatedAt: snapshot.updatedAt
|
|
1371
1803
|
};
|
|
1372
1804
|
};
|
|
1373
1805
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
1374
1806
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
1375
|
-
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--${
|
|
1807
|
+
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--${escapeHtml6(provider.status)}">
|
|
1376
1808
|
<header>
|
|
1377
|
-
<strong>${
|
|
1378
|
-
<span>${
|
|
1809
|
+
<strong>${escapeHtml6(provider.label)}</strong>
|
|
1810
|
+
<span>${escapeHtml6(formatStatus2(provider.status))}</span>
|
|
1379
1811
|
</header>
|
|
1380
|
-
<p>${
|
|
1812
|
+
<p>${escapeHtml6(provider.detail)}</p>
|
|
1381
1813
|
<dl>${provider.rows.map((row) => `<div>
|
|
1382
|
-
<dt>${
|
|
1383
|
-
<dd>${
|
|
1814
|
+
<dt>${escapeHtml6(row.label)}</dt>
|
|
1815
|
+
<dd>${escapeHtml6(row.value)}</dd>
|
|
1384
1816
|
</div>`).join("")}</dl>
|
|
1385
1817
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
1386
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
1818
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml6(model.status)}">
|
|
1387
1819
|
<header class="absolute-voice-provider-status__header">
|
|
1388
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
1389
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
1820
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml6(model.title)}</span>
|
|
1821
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml6(model.label)}</strong>
|
|
1390
1822
|
</header>
|
|
1391
|
-
<p class="absolute-voice-provider-status__description">${
|
|
1823
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml6(model.description)}</p>
|
|
1392
1824
|
${providers}
|
|
1393
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
1825
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
1394
1826
|
</section>`;
|
|
1395
1827
|
};
|
|
1396
1828
|
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}`;
|
|
@@ -1432,7 +1864,7 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
1432
1864
|
};
|
|
1433
1865
|
|
|
1434
1866
|
// src/react/VoiceProviderStatus.tsx
|
|
1435
|
-
import { jsxDEV as
|
|
1867
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
1436
1868
|
var VoiceProviderStatus = ({
|
|
1437
1869
|
className,
|
|
1438
1870
|
path = "/api/provider-status",
|
|
@@ -1440,58 +1872,58 @@ var VoiceProviderStatus = ({
|
|
|
1440
1872
|
}) => {
|
|
1441
1873
|
const snapshot = useVoiceProviderStatus(path, options);
|
|
1442
1874
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
1443
|
-
return /* @__PURE__ */
|
|
1875
|
+
return /* @__PURE__ */ jsxDEV6("section", {
|
|
1444
1876
|
className: [
|
|
1445
1877
|
"absolute-voice-provider-status",
|
|
1446
1878
|
`absolute-voice-provider-status--${model.status}`,
|
|
1447
1879
|
className
|
|
1448
1880
|
].filter(Boolean).join(" "),
|
|
1449
1881
|
children: [
|
|
1450
|
-
/* @__PURE__ */
|
|
1882
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1451
1883
|
className: "absolute-voice-provider-status__header",
|
|
1452
1884
|
children: [
|
|
1453
|
-
/* @__PURE__ */
|
|
1885
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1454
1886
|
className: "absolute-voice-provider-status__eyebrow",
|
|
1455
1887
|
children: model.title
|
|
1456
1888
|
}, undefined, false, undefined, this),
|
|
1457
|
-
/* @__PURE__ */
|
|
1889
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1458
1890
|
className: "absolute-voice-provider-status__label",
|
|
1459
1891
|
children: model.label
|
|
1460
1892
|
}, undefined, false, undefined, this)
|
|
1461
1893
|
]
|
|
1462
1894
|
}, undefined, true, undefined, this),
|
|
1463
|
-
/* @__PURE__ */
|
|
1895
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1464
1896
|
className: "absolute-voice-provider-status__description",
|
|
1465
1897
|
children: model.description
|
|
1466
1898
|
}, undefined, false, undefined, this),
|
|
1467
|
-
model.providers.length ? /* @__PURE__ */
|
|
1899
|
+
model.providers.length ? /* @__PURE__ */ jsxDEV6("div", {
|
|
1468
1900
|
className: "absolute-voice-provider-status__providers",
|
|
1469
|
-
children: model.providers.map((provider) => /* @__PURE__ */
|
|
1901
|
+
children: model.providers.map((provider) => /* @__PURE__ */ jsxDEV6("article", {
|
|
1470
1902
|
className: [
|
|
1471
1903
|
"absolute-voice-provider-status__provider",
|
|
1472
1904
|
`absolute-voice-provider-status__provider--${provider.status}`
|
|
1473
1905
|
].join(" "),
|
|
1474
1906
|
children: [
|
|
1475
|
-
/* @__PURE__ */
|
|
1907
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1476
1908
|
children: [
|
|
1477
|
-
/* @__PURE__ */
|
|
1909
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1478
1910
|
children: provider.label
|
|
1479
1911
|
}, undefined, false, undefined, this),
|
|
1480
|
-
/* @__PURE__ */
|
|
1912
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1481
1913
|
children: provider.status
|
|
1482
1914
|
}, undefined, false, undefined, this)
|
|
1483
1915
|
]
|
|
1484
1916
|
}, undefined, true, undefined, this),
|
|
1485
|
-
/* @__PURE__ */
|
|
1917
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1486
1918
|
children: provider.detail
|
|
1487
1919
|
}, undefined, false, undefined, this),
|
|
1488
|
-
/* @__PURE__ */
|
|
1489
|
-
children: provider.rows.map((row) => /* @__PURE__ */
|
|
1920
|
+
/* @__PURE__ */ jsxDEV6("dl", {
|
|
1921
|
+
children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV6("div", {
|
|
1490
1922
|
children: [
|
|
1491
|
-
/* @__PURE__ */
|
|
1923
|
+
/* @__PURE__ */ jsxDEV6("dt", {
|
|
1492
1924
|
children: row.label
|
|
1493
1925
|
}, undefined, false, undefined, this),
|
|
1494
|
-
/* @__PURE__ */
|
|
1926
|
+
/* @__PURE__ */ jsxDEV6("dd", {
|
|
1495
1927
|
children: row.value
|
|
1496
1928
|
}, undefined, false, undefined, this)
|
|
1497
1929
|
]
|
|
@@ -1499,11 +1931,11 @@ var VoiceProviderStatus = ({
|
|
|
1499
1931
|
}, undefined, false, undefined, this)
|
|
1500
1932
|
]
|
|
1501
1933
|
}, provider.provider, true, undefined, this))
|
|
1502
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
1934
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV6("p", {
|
|
1503
1935
|
className: "absolute-voice-provider-status__empty",
|
|
1504
1936
|
children: "Run voice traffic to see provider health."
|
|
1505
1937
|
}, undefined, false, undefined, this),
|
|
1506
|
-
model.error ? /* @__PURE__ */
|
|
1938
|
+
model.error ? /* @__PURE__ */ jsxDEV6("p", {
|
|
1507
1939
|
className: "absolute-voice-provider-status__error",
|
|
1508
1940
|
children: model.error
|
|
1509
1941
|
}, undefined, false, undefined, this) : null
|
|
@@ -1511,7 +1943,7 @@ var VoiceProviderStatus = ({
|
|
|
1511
1943
|
}, undefined, true, undefined, this);
|
|
1512
1944
|
};
|
|
1513
1945
|
// src/react/useVoiceRoutingStatus.tsx
|
|
1514
|
-
import { useEffect as
|
|
1946
|
+
import { useEffect as useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
|
|
1515
1947
|
|
|
1516
1948
|
// src/client/routingStatus.ts
|
|
1517
1949
|
var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
|
|
@@ -1595,25 +2027,25 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
1595
2027
|
|
|
1596
2028
|
// src/react/useVoiceRoutingStatus.tsx
|
|
1597
2029
|
var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
1598
|
-
const storeRef =
|
|
2030
|
+
const storeRef = useRef7(null);
|
|
1599
2031
|
if (!storeRef.current) {
|
|
1600
2032
|
storeRef.current = createVoiceRoutingStatusStore(path, options);
|
|
1601
2033
|
}
|
|
1602
2034
|
const store = storeRef.current;
|
|
1603
|
-
|
|
2035
|
+
useEffect7(() => {
|
|
1604
2036
|
store.refresh().catch(() => {});
|
|
1605
2037
|
return () => store.close();
|
|
1606
2038
|
}, [store]);
|
|
1607
2039
|
return {
|
|
1608
|
-
...
|
|
2040
|
+
...useSyncExternalStore7(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1609
2041
|
refresh: store.refresh
|
|
1610
2042
|
};
|
|
1611
2043
|
};
|
|
1612
2044
|
|
|
1613
2045
|
// src/client/routingStatusWidget.ts
|
|
1614
|
-
var
|
|
1615
|
-
var
|
|
1616
|
-
var
|
|
2046
|
+
var DEFAULT_TITLE6 = "Voice Routing";
|
|
2047
|
+
var DEFAULT_DESCRIPTION6 = "Latest provider routing decision from the self-hosted trace store.";
|
|
2048
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1617
2049
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
1618
2050
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
1619
2051
|
const decision = snapshot.decision;
|
|
@@ -1637,30 +2069,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
1637
2069
|
] : [];
|
|
1638
2070
|
return {
|
|
1639
2071
|
decision,
|
|
1640
|
-
description: options.description ??
|
|
2072
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
1641
2073
|
error: snapshot.error,
|
|
1642
2074
|
isLoading: snapshot.isLoading,
|
|
1643
2075
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
1644
2076
|
rows,
|
|
1645
2077
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1646
|
-
title: options.title ??
|
|
2078
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
1647
2079
|
updatedAt: snapshot.updatedAt
|
|
1648
2080
|
};
|
|
1649
2081
|
};
|
|
1650
2082
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
1651
2083
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
1652
2084
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
1653
|
-
<span>${
|
|
1654
|
-
<strong>${
|
|
2085
|
+
<span>${escapeHtml7(row.label)}</span>
|
|
2086
|
+
<strong>${escapeHtml7(row.value)}</strong>
|
|
1655
2087
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
1656
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
2088
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml7(model.status)}">
|
|
1657
2089
|
<header class="absolute-voice-routing-status__header">
|
|
1658
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
1659
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
2090
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml7(model.title)}</span>
|
|
2091
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml7(model.label)}</strong>
|
|
1660
2092
|
</header>
|
|
1661
|
-
<p class="absolute-voice-routing-status__description">${
|
|
2093
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml7(model.description)}</p>
|
|
1662
2094
|
${rows}
|
|
1663
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
2095
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
1664
2096
|
</section>`;
|
|
1665
2097
|
};
|
|
1666
2098
|
var getVoiceRoutingStatusCSS = () => `.absolute-voice-routing-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-routing-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-routing-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-routing-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-routing-status__label{font-size:24px;line-height:1}.absolute-voice-routing-status__description{color:#514733;margin:12px 0 0}.absolute-voice-routing-status__grid{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:14px}.absolute-voice-routing-status__grid div{background:#fff;border:1px solid #eee4d2;border-radius:14px;padding:10px 12px}.absolute-voice-routing-status__grid span{color:#655944;display:block;font-size:12px;margin-bottom:4px}.absolute-voice-routing-status__grid strong{overflow-wrap:anywhere}.absolute-voice-routing-status__empty{color:#655944;margin:14px 0 0}.absolute-voice-routing-status__error{color:#9f1239;font-weight:700}`;
|
|
@@ -1702,7 +2134,7 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
|
|
|
1702
2134
|
};
|
|
1703
2135
|
|
|
1704
2136
|
// src/react/VoiceRoutingStatus.tsx
|
|
1705
|
-
import { jsxDEV as
|
|
2137
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
1706
2138
|
var VoiceRoutingStatus = ({
|
|
1707
2139
|
className,
|
|
1708
2140
|
path = "/api/routing/latest",
|
|
@@ -1710,47 +2142,47 @@ var VoiceRoutingStatus = ({
|
|
|
1710
2142
|
}) => {
|
|
1711
2143
|
const snapshot = useVoiceRoutingStatus(path, options);
|
|
1712
2144
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
1713
|
-
return /* @__PURE__ */
|
|
2145
|
+
return /* @__PURE__ */ jsxDEV7("section", {
|
|
1714
2146
|
className: [
|
|
1715
2147
|
"absolute-voice-routing-status",
|
|
1716
2148
|
`absolute-voice-routing-status--${model.status}`,
|
|
1717
2149
|
className
|
|
1718
2150
|
].filter(Boolean).join(" "),
|
|
1719
2151
|
children: [
|
|
1720
|
-
/* @__PURE__ */
|
|
2152
|
+
/* @__PURE__ */ jsxDEV7("header", {
|
|
1721
2153
|
className: "absolute-voice-routing-status__header",
|
|
1722
2154
|
children: [
|
|
1723
|
-
/* @__PURE__ */
|
|
2155
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1724
2156
|
className: "absolute-voice-routing-status__eyebrow",
|
|
1725
2157
|
children: model.title
|
|
1726
2158
|
}, undefined, false, undefined, this),
|
|
1727
|
-
/* @__PURE__ */
|
|
2159
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1728
2160
|
className: "absolute-voice-routing-status__label",
|
|
1729
2161
|
children: model.label
|
|
1730
2162
|
}, undefined, false, undefined, this)
|
|
1731
2163
|
]
|
|
1732
2164
|
}, undefined, true, undefined, this),
|
|
1733
|
-
/* @__PURE__ */
|
|
2165
|
+
/* @__PURE__ */ jsxDEV7("p", {
|
|
1734
2166
|
className: "absolute-voice-routing-status__description",
|
|
1735
2167
|
children: model.description
|
|
1736
2168
|
}, undefined, false, undefined, this),
|
|
1737
|
-
model.rows.length ? /* @__PURE__ */
|
|
2169
|
+
model.rows.length ? /* @__PURE__ */ jsxDEV7("div", {
|
|
1738
2170
|
className: "absolute-voice-routing-status__grid",
|
|
1739
|
-
children: model.rows.map((row) => /* @__PURE__ */
|
|
2171
|
+
children: model.rows.map((row) => /* @__PURE__ */ jsxDEV7("div", {
|
|
1740
2172
|
children: [
|
|
1741
|
-
/* @__PURE__ */
|
|
2173
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1742
2174
|
children: row.label
|
|
1743
2175
|
}, undefined, false, undefined, this),
|
|
1744
|
-
/* @__PURE__ */
|
|
2176
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1745
2177
|
children: row.value
|
|
1746
2178
|
}, undefined, false, undefined, this)
|
|
1747
2179
|
]
|
|
1748
2180
|
}, row.label, true, undefined, this))
|
|
1749
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2181
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("p", {
|
|
1750
2182
|
className: "absolute-voice-routing-status__empty",
|
|
1751
2183
|
children: "Start a voice session to see the selected provider."
|
|
1752
2184
|
}, undefined, false, undefined, this),
|
|
1753
|
-
model.error ? /* @__PURE__ */
|
|
2185
|
+
model.error ? /* @__PURE__ */ jsxDEV7("p", {
|
|
1754
2186
|
className: "absolute-voice-routing-status__error",
|
|
1755
2187
|
children: model.error
|
|
1756
2188
|
}, undefined, false, undefined, this) : null
|
|
@@ -1838,9 +2270,9 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
|
|
|
1838
2270
|
};
|
|
1839
2271
|
|
|
1840
2272
|
// src/client/traceTimelineWidget.ts
|
|
1841
|
-
var
|
|
1842
|
-
var
|
|
1843
|
-
var
|
|
2273
|
+
var DEFAULT_TITLE7 = "Voice Traces";
|
|
2274
|
+
var DEFAULT_DESCRIPTION7 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
2275
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1844
2276
|
var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
1845
2277
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
1846
2278
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -1854,34 +2286,34 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
|
1854
2286
|
const failed = sessions.filter((session) => session.status === "failed").length;
|
|
1855
2287
|
const warnings = sessions.filter((session) => session.status === "warning").length;
|
|
1856
2288
|
return {
|
|
1857
|
-
description: options.description ??
|
|
2289
|
+
description: options.description ?? DEFAULT_DESCRIPTION7,
|
|
1858
2290
|
error: snapshot.error,
|
|
1859
2291
|
isLoading: snapshot.isLoading,
|
|
1860
2292
|
label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
|
|
1861
2293
|
sessions,
|
|
1862
2294
|
status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1863
|
-
title: options.title ??
|
|
2295
|
+
title: options.title ?? DEFAULT_TITLE7,
|
|
1864
2296
|
updatedAt: snapshot.updatedAt
|
|
1865
2297
|
};
|
|
1866
2298
|
};
|
|
1867
2299
|
var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
1868
2300
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
1869
|
-
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
2301
|
+
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml8(session.status)}">
|
|
1870
2302
|
<header>
|
|
1871
|
-
<strong>${
|
|
1872
|
-
<span>${
|
|
2303
|
+
<strong>${escapeHtml8(session.sessionId)}</strong>
|
|
2304
|
+
<span>${escapeHtml8(session.status)}</span>
|
|
1873
2305
|
</header>
|
|
1874
|
-
<p>${
|
|
1875
|
-
<a href="${
|
|
2306
|
+
<p>${escapeHtml8(session.label)} \xB7 ${escapeHtml8(session.durationLabel)} \xB7 ${escapeHtml8(session.providerLabel)}</p>
|
|
2307
|
+
<a href="${escapeHtml8(session.detailHref)}">Open timeline</a>
|
|
1876
2308
|
</article>`).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
1877
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
2309
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml8(model.status)}">
|
|
1878
2310
|
<header class="absolute-voice-trace-timeline__header">
|
|
1879
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
1880
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
2311
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml8(model.title)}</span>
|
|
2312
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml8(model.label)}</strong>
|
|
1881
2313
|
</header>
|
|
1882
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
2314
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml8(model.description)}</p>
|
|
1883
2315
|
${sessions}
|
|
1884
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
2316
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml8(model.error)}</p>` : ""}
|
|
1885
2317
|
</section>`;
|
|
1886
2318
|
};
|
|
1887
2319
|
var getVoiceTraceTimelineCSS = () => `.absolute-voice-trace-timeline{border:1px solid #bad7d3;border-radius:20px;background:#f3fffb;color:#09201c;padding:18px;box-shadow:0 18px 40px rgba(9,32,28,.12);font-family:inherit}.absolute-voice-trace-timeline--error,.absolute-voice-trace-timeline--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-trace-timeline--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-trace-timeline__header,.absolute-voice-trace-timeline__session header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-trace-timeline__eyebrow{color:#17665b;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-trace-timeline__label{font-size:24px;line-height:1}.absolute-voice-trace-timeline__description,.absolute-voice-trace-timeline__session p,.absolute-voice-trace-timeline__empty{color:#35544f}.absolute-voice-trace-timeline__sessions{display:grid;gap:12px;margin-top:14px}.absolute-voice-trace-timeline__session{background:#fff;border:1px solid #cfe7e2;border-radius:16px;padding:14px}.absolute-voice-trace-timeline__session--failed{border-color:#f2a7a7}.absolute-voice-trace-timeline__session--warning{border-color:#fbbf24}.absolute-voice-trace-timeline__session p{margin:10px 0}.absolute-voice-trace-timeline__session a{color:#0f766e;font-weight:800}.absolute-voice-trace-timeline__empty{margin:14px 0 0}.absolute-voice-trace-timeline__error{color:#9f1239;font-weight:700}`;
|
|
@@ -1926,25 +2358,25 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
|
|
|
1926
2358
|
};
|
|
1927
2359
|
|
|
1928
2360
|
// src/react/useVoiceTraceTimeline.tsx
|
|
1929
|
-
import { useEffect as
|
|
2361
|
+
import { useEffect as useEffect8, useRef as useRef8, useSyncExternalStore as useSyncExternalStore8 } from "react";
|
|
1930
2362
|
var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
|
|
1931
|
-
const storeRef =
|
|
2363
|
+
const storeRef = useRef8(null);
|
|
1932
2364
|
if (!storeRef.current) {
|
|
1933
2365
|
storeRef.current = createVoiceTraceTimelineStore(path, options);
|
|
1934
2366
|
}
|
|
1935
2367
|
const store = storeRef.current;
|
|
1936
|
-
|
|
2368
|
+
useEffect8(() => {
|
|
1937
2369
|
store.refresh().catch(() => {});
|
|
1938
2370
|
return () => store.close();
|
|
1939
2371
|
}, [store]);
|
|
1940
2372
|
return {
|
|
1941
|
-
...
|
|
2373
|
+
...useSyncExternalStore8(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1942
2374
|
refresh: store.refresh
|
|
1943
2375
|
};
|
|
1944
2376
|
};
|
|
1945
2377
|
|
|
1946
2378
|
// src/react/VoiceTraceTimeline.tsx
|
|
1947
|
-
import { jsxDEV as
|
|
2379
|
+
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
1948
2380
|
var VoiceTraceTimeline = ({
|
|
1949
2381
|
className,
|
|
1950
2382
|
path = "/api/voice-traces",
|
|
@@ -1952,49 +2384,49 @@ var VoiceTraceTimeline = ({
|
|
|
1952
2384
|
}) => {
|
|
1953
2385
|
const snapshot = useVoiceTraceTimeline(path, options);
|
|
1954
2386
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
1955
|
-
return /* @__PURE__ */
|
|
2387
|
+
return /* @__PURE__ */ jsxDEV8("section", {
|
|
1956
2388
|
className: [
|
|
1957
2389
|
"absolute-voice-trace-timeline",
|
|
1958
2390
|
`absolute-voice-trace-timeline--${model.status}`,
|
|
1959
2391
|
className
|
|
1960
2392
|
].filter(Boolean).join(" "),
|
|
1961
2393
|
children: [
|
|
1962
|
-
/* @__PURE__ */
|
|
2394
|
+
/* @__PURE__ */ jsxDEV8("header", {
|
|
1963
2395
|
className: "absolute-voice-trace-timeline__header",
|
|
1964
2396
|
children: [
|
|
1965
|
-
/* @__PURE__ */
|
|
2397
|
+
/* @__PURE__ */ jsxDEV8("span", {
|
|
1966
2398
|
className: "absolute-voice-trace-timeline__eyebrow",
|
|
1967
2399
|
children: model.title
|
|
1968
2400
|
}, undefined, false, undefined, this),
|
|
1969
|
-
/* @__PURE__ */
|
|
2401
|
+
/* @__PURE__ */ jsxDEV8("strong", {
|
|
1970
2402
|
className: "absolute-voice-trace-timeline__label",
|
|
1971
2403
|
children: model.label
|
|
1972
2404
|
}, undefined, false, undefined, this)
|
|
1973
2405
|
]
|
|
1974
2406
|
}, undefined, true, undefined, this),
|
|
1975
|
-
/* @__PURE__ */
|
|
2407
|
+
/* @__PURE__ */ jsxDEV8("p", {
|
|
1976
2408
|
className: "absolute-voice-trace-timeline__description",
|
|
1977
2409
|
children: model.description
|
|
1978
2410
|
}, undefined, false, undefined, this),
|
|
1979
|
-
model.sessions.length ? /* @__PURE__ */
|
|
2411
|
+
model.sessions.length ? /* @__PURE__ */ jsxDEV8("div", {
|
|
1980
2412
|
className: "absolute-voice-trace-timeline__sessions",
|
|
1981
|
-
children: model.sessions.map((session) => /* @__PURE__ */
|
|
2413
|
+
children: model.sessions.map((session) => /* @__PURE__ */ jsxDEV8("article", {
|
|
1982
2414
|
className: [
|
|
1983
2415
|
"absolute-voice-trace-timeline__session",
|
|
1984
2416
|
`absolute-voice-trace-timeline__session--${session.status}`
|
|
1985
2417
|
].join(" "),
|
|
1986
2418
|
children: [
|
|
1987
|
-
/* @__PURE__ */
|
|
2419
|
+
/* @__PURE__ */ jsxDEV8("header", {
|
|
1988
2420
|
children: [
|
|
1989
|
-
/* @__PURE__ */
|
|
2421
|
+
/* @__PURE__ */ jsxDEV8("strong", {
|
|
1990
2422
|
children: session.sessionId
|
|
1991
2423
|
}, undefined, false, undefined, this),
|
|
1992
|
-
/* @__PURE__ */
|
|
2424
|
+
/* @__PURE__ */ jsxDEV8("span", {
|
|
1993
2425
|
children: session.status
|
|
1994
2426
|
}, undefined, false, undefined, this)
|
|
1995
2427
|
]
|
|
1996
2428
|
}, undefined, true, undefined, this),
|
|
1997
|
-
/* @__PURE__ */
|
|
2429
|
+
/* @__PURE__ */ jsxDEV8("p", {
|
|
1998
2430
|
children: [
|
|
1999
2431
|
session.label,
|
|
2000
2432
|
" \xB7 ",
|
|
@@ -2004,17 +2436,17 @@ var VoiceTraceTimeline = ({
|
|
|
2004
2436
|
session.providerLabel
|
|
2005
2437
|
]
|
|
2006
2438
|
}, undefined, true, undefined, this),
|
|
2007
|
-
/* @__PURE__ */
|
|
2439
|
+
/* @__PURE__ */ jsxDEV8("a", {
|
|
2008
2440
|
href: session.detailHref,
|
|
2009
2441
|
children: "Open timeline"
|
|
2010
2442
|
}, undefined, false, undefined, this)
|
|
2011
2443
|
]
|
|
2012
2444
|
}, session.sessionId, true, undefined, this))
|
|
2013
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2445
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV8("p", {
|
|
2014
2446
|
className: "absolute-voice-trace-timeline__empty",
|
|
2015
2447
|
children: "Run a voice session to see call timelines."
|
|
2016
2448
|
}, undefined, false, undefined, this),
|
|
2017
|
-
model.error ? /* @__PURE__ */
|
|
2449
|
+
model.error ? /* @__PURE__ */ jsxDEV8("p", {
|
|
2018
2450
|
className: "absolute-voice-trace-timeline__error",
|
|
2019
2451
|
children: model.error
|
|
2020
2452
|
}, undefined, false, undefined, this) : null
|
|
@@ -2022,7 +2454,7 @@ var VoiceTraceTimeline = ({
|
|
|
2022
2454
|
}, undefined, true, undefined, this);
|
|
2023
2455
|
};
|
|
2024
2456
|
// src/react/useVoiceTurnLatency.tsx
|
|
2025
|
-
import { useEffect as
|
|
2457
|
+
import { useEffect as useEffect9, useRef as useRef9, useSyncExternalStore as useSyncExternalStore9 } from "react";
|
|
2026
2458
|
|
|
2027
2459
|
// src/client/turnLatency.ts
|
|
2028
2460
|
var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
|
|
@@ -2129,27 +2561,27 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
|
|
|
2129
2561
|
|
|
2130
2562
|
// src/react/useVoiceTurnLatency.tsx
|
|
2131
2563
|
var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
|
|
2132
|
-
const storeRef =
|
|
2564
|
+
const storeRef = useRef9(null);
|
|
2133
2565
|
if (!storeRef.current) {
|
|
2134
2566
|
storeRef.current = createVoiceTurnLatencyStore(path, options);
|
|
2135
2567
|
}
|
|
2136
2568
|
const store = storeRef.current;
|
|
2137
|
-
|
|
2569
|
+
useEffect9(() => {
|
|
2138
2570
|
store.refresh().catch(() => {});
|
|
2139
2571
|
return () => store.close();
|
|
2140
2572
|
}, [store]);
|
|
2141
2573
|
return {
|
|
2142
|
-
...
|
|
2574
|
+
...useSyncExternalStore9(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2143
2575
|
refresh: store.refresh,
|
|
2144
2576
|
runProof: store.runProof
|
|
2145
2577
|
};
|
|
2146
2578
|
};
|
|
2147
2579
|
|
|
2148
2580
|
// src/client/turnLatencyWidget.ts
|
|
2149
|
-
var
|
|
2150
|
-
var
|
|
2581
|
+
var DEFAULT_TITLE8 = "Turn Latency";
|
|
2582
|
+
var DEFAULT_DESCRIPTION8 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
2151
2583
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
2152
|
-
var
|
|
2584
|
+
var escapeHtml9 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2153
2585
|
var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
2154
2586
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
2155
2587
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -2163,39 +2595,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
2163
2595
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
2164
2596
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
2165
2597
|
return {
|
|
2166
|
-
description: options.description ??
|
|
2598
|
+
description: options.description ?? DEFAULT_DESCRIPTION8,
|
|
2167
2599
|
error: snapshot.error,
|
|
2168
2600
|
isLoading: snapshot.isLoading,
|
|
2169
2601
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
2170
2602
|
proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
|
|
2171
2603
|
showProofAction: Boolean(options.proofPath),
|
|
2172
2604
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2173
|
-
title: options.title ??
|
|
2605
|
+
title: options.title ?? DEFAULT_TITLE8,
|
|
2174
2606
|
turns,
|
|
2175
2607
|
updatedAt: snapshot.updatedAt
|
|
2176
2608
|
};
|
|
2177
2609
|
};
|
|
2178
2610
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
2179
2611
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
2180
|
-
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--${
|
|
2612
|
+
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--${escapeHtml9(turn.status)}">
|
|
2181
2613
|
<header>
|
|
2182
|
-
<strong>${
|
|
2183
|
-
<span>${
|
|
2614
|
+
<strong>${escapeHtml9(turn.label)}</strong>
|
|
2615
|
+
<span>${escapeHtml9(turn.status)}</span>
|
|
2184
2616
|
</header>
|
|
2185
2617
|
<dl>${turn.rows.map((row) => `<div>
|
|
2186
|
-
<dt>${
|
|
2187
|
-
<dd>${
|
|
2618
|
+
<dt>${escapeHtml9(row.label)}</dt>
|
|
2619
|
+
<dd>${escapeHtml9(row.value)}</dd>
|
|
2188
2620
|
</div>`).join("")}</dl>
|
|
2189
2621
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
2190
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
2622
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml9(model.status)}">
|
|
2191
2623
|
<header class="absolute-voice-turn-latency__header">
|
|
2192
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
2193
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
2624
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml9(model.title)}</span>
|
|
2625
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml9(model.label)}</strong>
|
|
2194
2626
|
</header>
|
|
2195
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
2196
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
2627
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml9(model.description)}</p>
|
|
2628
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml9(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
2197
2629
|
${turns}
|
|
2198
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
2630
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml9(model.error)}</p>` : ""}
|
|
2199
2631
|
</section>`;
|
|
2200
2632
|
};
|
|
2201
2633
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -2246,7 +2678,7 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
2246
2678
|
};
|
|
2247
2679
|
|
|
2248
2680
|
// src/react/VoiceTurnLatency.tsx
|
|
2249
|
-
import { jsxDEV as
|
|
2681
|
+
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
2250
2682
|
var VoiceTurnLatency = ({
|
|
2251
2683
|
className,
|
|
2252
2684
|
path = "/api/turn-latency",
|
|
@@ -2254,31 +2686,31 @@ var VoiceTurnLatency = ({
|
|
|
2254
2686
|
}) => {
|
|
2255
2687
|
const latency = useVoiceTurnLatency(path, options);
|
|
2256
2688
|
const model = createVoiceTurnLatencyViewModel(latency, options);
|
|
2257
|
-
return /* @__PURE__ */
|
|
2689
|
+
return /* @__PURE__ */ jsxDEV9("section", {
|
|
2258
2690
|
className: [
|
|
2259
2691
|
"absolute-voice-turn-latency",
|
|
2260
2692
|
`absolute-voice-turn-latency--${model.status}`,
|
|
2261
2693
|
className
|
|
2262
2694
|
].filter(Boolean).join(" "),
|
|
2263
2695
|
children: [
|
|
2264
|
-
/* @__PURE__ */
|
|
2696
|
+
/* @__PURE__ */ jsxDEV9("header", {
|
|
2265
2697
|
className: "absolute-voice-turn-latency__header",
|
|
2266
2698
|
children: [
|
|
2267
|
-
/* @__PURE__ */
|
|
2699
|
+
/* @__PURE__ */ jsxDEV9("span", {
|
|
2268
2700
|
className: "absolute-voice-turn-latency__eyebrow",
|
|
2269
2701
|
children: model.title
|
|
2270
2702
|
}, undefined, false, undefined, this),
|
|
2271
|
-
/* @__PURE__ */
|
|
2703
|
+
/* @__PURE__ */ jsxDEV9("strong", {
|
|
2272
2704
|
className: "absolute-voice-turn-latency__label",
|
|
2273
2705
|
children: model.label
|
|
2274
2706
|
}, undefined, false, undefined, this)
|
|
2275
2707
|
]
|
|
2276
2708
|
}, undefined, true, undefined, this),
|
|
2277
|
-
/* @__PURE__ */
|
|
2709
|
+
/* @__PURE__ */ jsxDEV9("p", {
|
|
2278
2710
|
className: "absolute-voice-turn-latency__description",
|
|
2279
2711
|
children: model.description
|
|
2280
2712
|
}, undefined, false, undefined, this),
|
|
2281
|
-
model.showProofAction ? /* @__PURE__ */
|
|
2713
|
+
model.showProofAction ? /* @__PURE__ */ jsxDEV9("button", {
|
|
2282
2714
|
className: "absolute-voice-turn-latency__proof",
|
|
2283
2715
|
onClick: () => {
|
|
2284
2716
|
latency.runProof().catch(() => {});
|
|
@@ -2286,31 +2718,31 @@ var VoiceTurnLatency = ({
|
|
|
2286
2718
|
type: "button",
|
|
2287
2719
|
children: model.proofLabel
|
|
2288
2720
|
}, undefined, false, undefined, this) : null,
|
|
2289
|
-
model.turns.length ? /* @__PURE__ */
|
|
2721
|
+
model.turns.length ? /* @__PURE__ */ jsxDEV9("div", {
|
|
2290
2722
|
className: "absolute-voice-turn-latency__turns",
|
|
2291
|
-
children: model.turns.map((turn) => /* @__PURE__ */
|
|
2723
|
+
children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV9("article", {
|
|
2292
2724
|
className: [
|
|
2293
2725
|
"absolute-voice-turn-latency__turn",
|
|
2294
2726
|
`absolute-voice-turn-latency__turn--${turn.status}`
|
|
2295
2727
|
].join(" "),
|
|
2296
2728
|
children: [
|
|
2297
|
-
/* @__PURE__ */
|
|
2729
|
+
/* @__PURE__ */ jsxDEV9("header", {
|
|
2298
2730
|
children: [
|
|
2299
|
-
/* @__PURE__ */
|
|
2731
|
+
/* @__PURE__ */ jsxDEV9("strong", {
|
|
2300
2732
|
children: turn.label
|
|
2301
2733
|
}, undefined, false, undefined, this),
|
|
2302
|
-
/* @__PURE__ */
|
|
2734
|
+
/* @__PURE__ */ jsxDEV9("span", {
|
|
2303
2735
|
children: turn.status
|
|
2304
2736
|
}, undefined, false, undefined, this)
|
|
2305
2737
|
]
|
|
2306
2738
|
}, undefined, true, undefined, this),
|
|
2307
|
-
/* @__PURE__ */
|
|
2308
|
-
children: turn.rows.map((row) => /* @__PURE__ */
|
|
2739
|
+
/* @__PURE__ */ jsxDEV9("dl", {
|
|
2740
|
+
children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV9("div", {
|
|
2309
2741
|
children: [
|
|
2310
|
-
/* @__PURE__ */
|
|
2742
|
+
/* @__PURE__ */ jsxDEV9("dt", {
|
|
2311
2743
|
children: row.label
|
|
2312
2744
|
}, undefined, false, undefined, this),
|
|
2313
|
-
/* @__PURE__ */
|
|
2745
|
+
/* @__PURE__ */ jsxDEV9("dd", {
|
|
2314
2746
|
children: row.value
|
|
2315
2747
|
}, undefined, false, undefined, this)
|
|
2316
2748
|
]
|
|
@@ -2318,11 +2750,11 @@ var VoiceTurnLatency = ({
|
|
|
2318
2750
|
}, undefined, false, undefined, this)
|
|
2319
2751
|
]
|
|
2320
2752
|
}, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
|
|
2321
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2753
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9("p", {
|
|
2322
2754
|
className: "absolute-voice-turn-latency__empty",
|
|
2323
2755
|
children: "Complete a voice turn to see latency diagnostics."
|
|
2324
2756
|
}, undefined, false, undefined, this),
|
|
2325
|
-
model.error ? /* @__PURE__ */
|
|
2757
|
+
model.error ? /* @__PURE__ */ jsxDEV9("p", {
|
|
2326
2758
|
className: "absolute-voice-turn-latency__error",
|
|
2327
2759
|
children: model.error
|
|
2328
2760
|
}, undefined, false, undefined, this) : null
|
|
@@ -2330,7 +2762,7 @@ var VoiceTurnLatency = ({
|
|
|
2330
2762
|
}, undefined, true, undefined, this);
|
|
2331
2763
|
};
|
|
2332
2764
|
// src/react/useVoiceTurnQuality.tsx
|
|
2333
|
-
import { useEffect as
|
|
2765
|
+
import { useEffect as useEffect10, useRef as useRef10, useSyncExternalStore as useSyncExternalStore10 } from "react";
|
|
2334
2766
|
|
|
2335
2767
|
// src/client/turnQuality.ts
|
|
2336
2768
|
var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
|
|
@@ -2413,25 +2845,25 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
2413
2845
|
|
|
2414
2846
|
// src/react/useVoiceTurnQuality.tsx
|
|
2415
2847
|
var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
2416
|
-
const storeRef =
|
|
2848
|
+
const storeRef = useRef10(null);
|
|
2417
2849
|
if (!storeRef.current) {
|
|
2418
2850
|
storeRef.current = createVoiceTurnQualityStore(path, options);
|
|
2419
2851
|
}
|
|
2420
2852
|
const store = storeRef.current;
|
|
2421
|
-
|
|
2853
|
+
useEffect10(() => {
|
|
2422
2854
|
store.refresh().catch(() => {});
|
|
2423
2855
|
return () => store.close();
|
|
2424
2856
|
}, [store]);
|
|
2425
2857
|
return {
|
|
2426
|
-
...
|
|
2858
|
+
...useSyncExternalStore10(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2427
2859
|
refresh: store.refresh
|
|
2428
2860
|
};
|
|
2429
2861
|
};
|
|
2430
2862
|
|
|
2431
2863
|
// src/client/turnQualityWidget.ts
|
|
2432
|
-
var
|
|
2433
|
-
var
|
|
2434
|
-
var
|
|
2864
|
+
var DEFAULT_TITLE9 = "Turn Quality";
|
|
2865
|
+
var DEFAULT_DESCRIPTION9 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
2866
|
+
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2435
2867
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
2436
2868
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
2437
2869
|
var getTurnDetail = (turn) => {
|
|
@@ -2469,37 +2901,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
2469
2901
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
2470
2902
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
2471
2903
|
return {
|
|
2472
|
-
description: options.description ??
|
|
2904
|
+
description: options.description ?? DEFAULT_DESCRIPTION9,
|
|
2473
2905
|
error: snapshot.error,
|
|
2474
2906
|
isLoading: snapshot.isLoading,
|
|
2475
2907
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
2476
2908
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2477
|
-
title: options.title ??
|
|
2909
|
+
title: options.title ?? DEFAULT_TITLE9,
|
|
2478
2910
|
turns,
|
|
2479
2911
|
updatedAt: snapshot.updatedAt
|
|
2480
2912
|
};
|
|
2481
2913
|
};
|
|
2482
2914
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
2483
2915
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
2484
|
-
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--${
|
|
2916
|
+
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--${escapeHtml10(turn.status)}">
|
|
2485
2917
|
<header>
|
|
2486
|
-
<strong>${
|
|
2487
|
-
<span>${
|
|
2918
|
+
<strong>${escapeHtml10(turn.label)}</strong>
|
|
2919
|
+
<span>${escapeHtml10(turn.status)}</span>
|
|
2488
2920
|
</header>
|
|
2489
|
-
<p>${
|
|
2921
|
+
<p>${escapeHtml10(turn.detail)}</p>
|
|
2490
2922
|
<dl>${turn.rows.map((row) => `<div>
|
|
2491
|
-
<dt>${
|
|
2492
|
-
<dd>${
|
|
2923
|
+
<dt>${escapeHtml10(row.label)}</dt>
|
|
2924
|
+
<dd>${escapeHtml10(row.value)}</dd>
|
|
2493
2925
|
</div>`).join("")}</dl>
|
|
2494
2926
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
2495
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
2927
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml10(model.status)}">
|
|
2496
2928
|
<header class="absolute-voice-turn-quality__header">
|
|
2497
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
2498
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
2929
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml10(model.title)}</span>
|
|
2930
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml10(model.label)}</strong>
|
|
2499
2931
|
</header>
|
|
2500
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
2932
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml10(model.description)}</p>
|
|
2501
2933
|
${turns}
|
|
2502
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
2934
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml10(model.error)}</p>` : ""}
|
|
2503
2935
|
</section>`;
|
|
2504
2936
|
};
|
|
2505
2937
|
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}`;
|
|
@@ -2541,7 +2973,7 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
2541
2973
|
};
|
|
2542
2974
|
|
|
2543
2975
|
// src/react/VoiceTurnQuality.tsx
|
|
2544
|
-
import { jsxDEV as
|
|
2976
|
+
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
2545
2977
|
var VoiceTurnQuality = ({
|
|
2546
2978
|
className,
|
|
2547
2979
|
path = "/api/turn-quality",
|
|
@@ -2549,58 +2981,58 @@ var VoiceTurnQuality = ({
|
|
|
2549
2981
|
}) => {
|
|
2550
2982
|
const snapshot = useVoiceTurnQuality(path, options);
|
|
2551
2983
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
2552
|
-
return /* @__PURE__ */
|
|
2984
|
+
return /* @__PURE__ */ jsxDEV10("section", {
|
|
2553
2985
|
className: [
|
|
2554
2986
|
"absolute-voice-turn-quality",
|
|
2555
2987
|
`absolute-voice-turn-quality--${model.status}`,
|
|
2556
2988
|
className
|
|
2557
2989
|
].filter(Boolean).join(" "),
|
|
2558
2990
|
children: [
|
|
2559
|
-
/* @__PURE__ */
|
|
2991
|
+
/* @__PURE__ */ jsxDEV10("header", {
|
|
2560
2992
|
className: "absolute-voice-turn-quality__header",
|
|
2561
2993
|
children: [
|
|
2562
|
-
/* @__PURE__ */
|
|
2994
|
+
/* @__PURE__ */ jsxDEV10("span", {
|
|
2563
2995
|
className: "absolute-voice-turn-quality__eyebrow",
|
|
2564
2996
|
children: model.title
|
|
2565
2997
|
}, undefined, false, undefined, this),
|
|
2566
|
-
/* @__PURE__ */
|
|
2998
|
+
/* @__PURE__ */ jsxDEV10("strong", {
|
|
2567
2999
|
className: "absolute-voice-turn-quality__label",
|
|
2568
3000
|
children: model.label
|
|
2569
3001
|
}, undefined, false, undefined, this)
|
|
2570
3002
|
]
|
|
2571
3003
|
}, undefined, true, undefined, this),
|
|
2572
|
-
/* @__PURE__ */
|
|
3004
|
+
/* @__PURE__ */ jsxDEV10("p", {
|
|
2573
3005
|
className: "absolute-voice-turn-quality__description",
|
|
2574
3006
|
children: model.description
|
|
2575
3007
|
}, undefined, false, undefined, this),
|
|
2576
|
-
model.turns.length ? /* @__PURE__ */
|
|
3008
|
+
model.turns.length ? /* @__PURE__ */ jsxDEV10("div", {
|
|
2577
3009
|
className: "absolute-voice-turn-quality__turns",
|
|
2578
|
-
children: model.turns.map((turn) => /* @__PURE__ */
|
|
3010
|
+
children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV10("article", {
|
|
2579
3011
|
className: [
|
|
2580
3012
|
"absolute-voice-turn-quality__turn",
|
|
2581
3013
|
`absolute-voice-turn-quality__turn--${turn.status}`
|
|
2582
3014
|
].join(" "),
|
|
2583
3015
|
children: [
|
|
2584
|
-
/* @__PURE__ */
|
|
3016
|
+
/* @__PURE__ */ jsxDEV10("header", {
|
|
2585
3017
|
children: [
|
|
2586
|
-
/* @__PURE__ */
|
|
3018
|
+
/* @__PURE__ */ jsxDEV10("strong", {
|
|
2587
3019
|
children: turn.label
|
|
2588
3020
|
}, undefined, false, undefined, this),
|
|
2589
|
-
/* @__PURE__ */
|
|
3021
|
+
/* @__PURE__ */ jsxDEV10("span", {
|
|
2590
3022
|
children: turn.status
|
|
2591
3023
|
}, undefined, false, undefined, this)
|
|
2592
3024
|
]
|
|
2593
3025
|
}, undefined, true, undefined, this),
|
|
2594
|
-
/* @__PURE__ */
|
|
3026
|
+
/* @__PURE__ */ jsxDEV10("p", {
|
|
2595
3027
|
children: turn.detail
|
|
2596
3028
|
}, undefined, false, undefined, this),
|
|
2597
|
-
/* @__PURE__ */
|
|
2598
|
-
children: turn.rows.map((row) => /* @__PURE__ */
|
|
3029
|
+
/* @__PURE__ */ jsxDEV10("dl", {
|
|
3030
|
+
children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV10("div", {
|
|
2599
3031
|
children: [
|
|
2600
|
-
/* @__PURE__ */
|
|
3032
|
+
/* @__PURE__ */ jsxDEV10("dt", {
|
|
2601
3033
|
children: row.label
|
|
2602
3034
|
}, undefined, false, undefined, this),
|
|
2603
|
-
/* @__PURE__ */
|
|
3035
|
+
/* @__PURE__ */ jsxDEV10("dd", {
|
|
2604
3036
|
children: row.value
|
|
2605
3037
|
}, undefined, false, undefined, this)
|
|
2606
3038
|
]
|
|
@@ -2608,11 +3040,11 @@ var VoiceTurnQuality = ({
|
|
|
2608
3040
|
}, undefined, false, undefined, this)
|
|
2609
3041
|
]
|
|
2610
3042
|
}, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
|
|
2611
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
3043
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV10("p", {
|
|
2612
3044
|
className: "absolute-voice-turn-quality__empty",
|
|
2613
3045
|
children: "Complete a voice turn to see STT quality diagnostics."
|
|
2614
3046
|
}, undefined, false, undefined, this),
|
|
2615
|
-
model.error ? /* @__PURE__ */
|
|
3047
|
+
model.error ? /* @__PURE__ */ jsxDEV10("p", {
|
|
2616
3048
|
className: "absolute-voice-turn-quality__error",
|
|
2617
3049
|
children: model.error
|
|
2618
3050
|
}, undefined, false, undefined, this) : null
|
|
@@ -2620,7 +3052,7 @@ var VoiceTurnQuality = ({
|
|
|
2620
3052
|
}, undefined, true, undefined, this);
|
|
2621
3053
|
};
|
|
2622
3054
|
// src/react/useVoiceCampaignDialerProof.tsx
|
|
2623
|
-
import { useEffect as
|
|
3055
|
+
import { useEffect as useEffect11, useRef as useRef11, useSyncExternalStore as useSyncExternalStore11 } from "react";
|
|
2624
3056
|
|
|
2625
3057
|
// src/client/campaignDialerProof.ts
|
|
2626
3058
|
var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
|
|
@@ -2742,23 +3174,23 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
|
|
|
2742
3174
|
|
|
2743
3175
|
// src/react/useVoiceCampaignDialerProof.tsx
|
|
2744
3176
|
var useVoiceCampaignDialerProof = (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
|
|
2745
|
-
const storeRef =
|
|
3177
|
+
const storeRef = useRef11(null);
|
|
2746
3178
|
if (!storeRef.current) {
|
|
2747
3179
|
storeRef.current = createVoiceCampaignDialerProofStore(path, options);
|
|
2748
3180
|
}
|
|
2749
3181
|
const store = storeRef.current;
|
|
2750
|
-
|
|
3182
|
+
useEffect11(() => {
|
|
2751
3183
|
store.refresh().catch(() => {});
|
|
2752
3184
|
return () => store.close();
|
|
2753
3185
|
}, [store]);
|
|
2754
3186
|
return {
|
|
2755
|
-
...
|
|
3187
|
+
...useSyncExternalStore11(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2756
3188
|
refresh: store.refresh,
|
|
2757
3189
|
runProof: store.runProof
|
|
2758
3190
|
};
|
|
2759
3191
|
};
|
|
2760
3192
|
// src/react/useVoiceStream.tsx
|
|
2761
|
-
import { useEffect as
|
|
3193
|
+
import { useEffect as useEffect12, useRef as useRef12, useSyncExternalStore as useSyncExternalStore12 } from "react";
|
|
2762
3194
|
|
|
2763
3195
|
// src/client/actions.ts
|
|
2764
3196
|
var normalizeErrorMessage = (value) => {
|
|
@@ -3418,13 +3850,13 @@ var EMPTY_SNAPSHOT = {
|
|
|
3418
3850
|
turns: []
|
|
3419
3851
|
};
|
|
3420
3852
|
var useVoiceStream = (path, options = {}) => {
|
|
3421
|
-
const streamRef =
|
|
3853
|
+
const streamRef = useRef12(null);
|
|
3422
3854
|
if (!streamRef.current) {
|
|
3423
3855
|
streamRef.current = createVoiceStream(path, options);
|
|
3424
3856
|
}
|
|
3425
3857
|
const stream = streamRef.current;
|
|
3426
|
-
|
|
3427
|
-
const snapshot =
|
|
3858
|
+
useEffect12(() => () => stream.close(), [stream]);
|
|
3859
|
+
const snapshot = useSyncExternalStore12(stream.subscribe, stream.getSnapshot, stream.getServerSnapshot) ?? EMPTY_SNAPSHOT;
|
|
3428
3860
|
return {
|
|
3429
3861
|
...snapshot,
|
|
3430
3862
|
callControl: (message) => stream.callControl(message),
|
|
@@ -3434,7 +3866,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
3434
3866
|
};
|
|
3435
3867
|
};
|
|
3436
3868
|
// src/react/useVoiceController.tsx
|
|
3437
|
-
import { useEffect as
|
|
3869
|
+
import { useEffect as useEffect13, useRef as useRef13, useSyncExternalStore as useSyncExternalStore13 } from "react";
|
|
3438
3870
|
|
|
3439
3871
|
// src/client/htmx.ts
|
|
3440
3872
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -4097,13 +4529,13 @@ var EMPTY_SNAPSHOT2 = {
|
|
|
4097
4529
|
turns: []
|
|
4098
4530
|
};
|
|
4099
4531
|
var useVoiceController = (path, options = {}) => {
|
|
4100
|
-
const controllerRef =
|
|
4532
|
+
const controllerRef = useRef13(null);
|
|
4101
4533
|
if (!controllerRef.current) {
|
|
4102
4534
|
controllerRef.current = createVoiceController(path, options);
|
|
4103
4535
|
}
|
|
4104
4536
|
const controller = controllerRef.current;
|
|
4105
|
-
|
|
4106
|
-
const snapshot =
|
|
4537
|
+
useEffect13(() => () => controller.close(), [controller]);
|
|
4538
|
+
const snapshot = useSyncExternalStore13(controller.subscribe, controller.getSnapshot, controller.getServerSnapshot) ?? EMPTY_SNAPSHOT2;
|
|
4107
4539
|
return {
|
|
4108
4540
|
...snapshot,
|
|
4109
4541
|
bindHTMX: controller.bindHTMX,
|
|
@@ -4117,7 +4549,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
4117
4549
|
};
|
|
4118
4550
|
};
|
|
4119
4551
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
4120
|
-
import { useEffect as
|
|
4552
|
+
import { useEffect as useEffect14, useRef as useRef14, useSyncExternalStore as useSyncExternalStore14 } from "react";
|
|
4121
4553
|
|
|
4122
4554
|
// src/client/workflowStatus.ts
|
|
4123
4555
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -4200,17 +4632,17 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
|
|
|
4200
4632
|
|
|
4201
4633
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
4202
4634
|
var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
4203
|
-
const storeRef =
|
|
4635
|
+
const storeRef = useRef14(null);
|
|
4204
4636
|
if (!storeRef.current) {
|
|
4205
4637
|
storeRef.current = createVoiceWorkflowStatusStore(path, options);
|
|
4206
4638
|
}
|
|
4207
4639
|
const store = storeRef.current;
|
|
4208
|
-
|
|
4640
|
+
useEffect14(() => {
|
|
4209
4641
|
store.refresh().catch(() => {});
|
|
4210
4642
|
return () => store.close();
|
|
4211
4643
|
}, [store]);
|
|
4212
4644
|
return {
|
|
4213
|
-
...
|
|
4645
|
+
...useSyncExternalStore14(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
4214
4646
|
refresh: store.refresh
|
|
4215
4647
|
};
|
|
4216
4648
|
};
|
|
@@ -4225,6 +4657,7 @@ export {
|
|
|
4225
4657
|
useVoiceProviderSimulationControls,
|
|
4226
4658
|
useVoiceProviderCapabilities,
|
|
4227
4659
|
useVoiceOpsStatus,
|
|
4660
|
+
useVoiceOpsActionCenter,
|
|
4228
4661
|
useVoiceDeliveryRuntime,
|
|
4229
4662
|
useVoiceController,
|
|
4230
4663
|
useVoiceCampaignDialerProof,
|
|
@@ -4236,5 +4669,6 @@ export {
|
|
|
4236
4669
|
VoiceProviderSimulationControls,
|
|
4237
4670
|
VoiceProviderCapabilities,
|
|
4238
4671
|
VoiceOpsStatus,
|
|
4672
|
+
VoiceOpsActionCenter,
|
|
4239
4673
|
VoiceDeliveryRuntime
|
|
4240
4674
|
};
|