@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/vue/index.js
CHANGED
|
@@ -374,10 +374,355 @@ var VoiceOpsStatus = defineComponent({
|
|
|
374
374
|
};
|
|
375
375
|
}
|
|
376
376
|
});
|
|
377
|
-
// src/vue/
|
|
377
|
+
// src/vue/VoiceOpsActionCenter.ts
|
|
378
378
|
import { defineComponent as defineComponent2, h as h2 } from "vue";
|
|
379
379
|
|
|
380
|
+
// src/client/opsActionCenter.ts
|
|
381
|
+
var createVoiceOpsActionCenterActions = (options = {}) => {
|
|
382
|
+
const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
|
|
383
|
+
const actions = [];
|
|
384
|
+
if (options.includeProductionReadiness !== false) {
|
|
385
|
+
actions.push({
|
|
386
|
+
description: "Refresh the production readiness report.",
|
|
387
|
+
id: "production-readiness",
|
|
388
|
+
label: "Refresh readiness",
|
|
389
|
+
method: "GET",
|
|
390
|
+
path: options.productionReadinessPath ?? "/api/production-readiness"
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
if (options.includeDeliveryRuntime !== false) {
|
|
394
|
+
actions.push({
|
|
395
|
+
description: "Drain pending and failed audit/trace deliveries.",
|
|
396
|
+
id: "delivery-runtime.tick",
|
|
397
|
+
label: "Tick delivery workers",
|
|
398
|
+
method: "POST",
|
|
399
|
+
path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
|
|
400
|
+
}, {
|
|
401
|
+
description: "Move reviewed dead letters back to live delivery queues.",
|
|
402
|
+
id: "delivery-runtime.requeue-dead-letters",
|
|
403
|
+
label: "Requeue dead letters",
|
|
404
|
+
method: "POST",
|
|
405
|
+
path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
if (options.includeTurnLatencyProof !== false) {
|
|
409
|
+
actions.push({
|
|
410
|
+
description: "Run the synthetic turn latency proof.",
|
|
411
|
+
id: "turn-latency.proof",
|
|
412
|
+
label: "Run latency proof",
|
|
413
|
+
method: "POST",
|
|
414
|
+
path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
if (options.includeProviderSimulation !== false) {
|
|
418
|
+
const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
|
|
419
|
+
for (const provider of options.providers ?? []) {
|
|
420
|
+
actions.push({
|
|
421
|
+
description: `Simulate ${provider} provider failure.`,
|
|
422
|
+
id: `provider.${provider}.failure`,
|
|
423
|
+
label: `Simulate ${provider} failure`,
|
|
424
|
+
method: "POST",
|
|
425
|
+
path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
|
|
426
|
+
}, {
|
|
427
|
+
description: `Mark ${provider} provider recovered.`,
|
|
428
|
+
id: `provider.${provider}.recovery`,
|
|
429
|
+
label: `Recover ${provider}`,
|
|
430
|
+
method: "POST",
|
|
431
|
+
path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return actions;
|
|
436
|
+
};
|
|
437
|
+
var runVoiceOpsAction = async (action, options = {}) => {
|
|
438
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
439
|
+
const response = await fetchImpl(action.path, {
|
|
440
|
+
method: action.method ?? "POST"
|
|
441
|
+
});
|
|
442
|
+
const body = await response.json().catch(() => null);
|
|
443
|
+
if (!response.ok) {
|
|
444
|
+
const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
|
|
445
|
+
throw new Error(message);
|
|
446
|
+
}
|
|
447
|
+
return {
|
|
448
|
+
actionId: action.id,
|
|
449
|
+
body,
|
|
450
|
+
ok: response.ok,
|
|
451
|
+
ranAt: Date.now(),
|
|
452
|
+
status: response.status
|
|
453
|
+
};
|
|
454
|
+
};
|
|
455
|
+
var createVoiceOpsActionCenterStore = (options = {}) => {
|
|
456
|
+
const listeners = new Set;
|
|
457
|
+
let closed = false;
|
|
458
|
+
let timer;
|
|
459
|
+
let snapshot = {
|
|
460
|
+
actions: options.actions ?? createVoiceOpsActionCenterActions(),
|
|
461
|
+
error: null,
|
|
462
|
+
isRunning: false
|
|
463
|
+
};
|
|
464
|
+
const emit = () => {
|
|
465
|
+
for (const listener of listeners) {
|
|
466
|
+
listener();
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
const setActions = (actions) => {
|
|
470
|
+
snapshot = { ...snapshot, actions, updatedAt: Date.now() };
|
|
471
|
+
emit();
|
|
472
|
+
};
|
|
473
|
+
const run = async (actionId) => {
|
|
474
|
+
if (closed) {
|
|
475
|
+
return snapshot.lastResult;
|
|
476
|
+
}
|
|
477
|
+
const action = snapshot.actions.find((item) => item.id === actionId);
|
|
478
|
+
if (!action) {
|
|
479
|
+
throw new Error(`Voice ops action "${actionId}" is not configured.`);
|
|
480
|
+
}
|
|
481
|
+
if (action.disabled) {
|
|
482
|
+
throw new Error(`Voice ops action "${actionId}" is disabled.`);
|
|
483
|
+
}
|
|
484
|
+
snapshot = {
|
|
485
|
+
...snapshot,
|
|
486
|
+
error: null,
|
|
487
|
+
isRunning: true,
|
|
488
|
+
runningActionId: action.id
|
|
489
|
+
};
|
|
490
|
+
emit();
|
|
491
|
+
try {
|
|
492
|
+
const result = await runVoiceOpsAction(action, options);
|
|
493
|
+
snapshot = {
|
|
494
|
+
...snapshot,
|
|
495
|
+
error: null,
|
|
496
|
+
isRunning: false,
|
|
497
|
+
lastResult: result,
|
|
498
|
+
runningActionId: undefined,
|
|
499
|
+
updatedAt: Date.now()
|
|
500
|
+
};
|
|
501
|
+
emit();
|
|
502
|
+
return result;
|
|
503
|
+
} catch (error) {
|
|
504
|
+
snapshot = {
|
|
505
|
+
...snapshot,
|
|
506
|
+
error: error instanceof Error ? error.message : String(error),
|
|
507
|
+
isRunning: false,
|
|
508
|
+
runningActionId: undefined
|
|
509
|
+
};
|
|
510
|
+
emit();
|
|
511
|
+
throw error;
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
const close = () => {
|
|
515
|
+
closed = true;
|
|
516
|
+
if (timer) {
|
|
517
|
+
clearInterval(timer);
|
|
518
|
+
timer = undefined;
|
|
519
|
+
}
|
|
520
|
+
listeners.clear();
|
|
521
|
+
};
|
|
522
|
+
if (options.intervalMs && options.intervalMs > 0) {
|
|
523
|
+
timer = setInterval(() => {
|
|
524
|
+
emit();
|
|
525
|
+
}, options.intervalMs);
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
close,
|
|
529
|
+
getServerSnapshot: () => snapshot,
|
|
530
|
+
getSnapshot: () => snapshot,
|
|
531
|
+
run,
|
|
532
|
+
setActions,
|
|
533
|
+
subscribe: (listener) => {
|
|
534
|
+
listeners.add(listener);
|
|
535
|
+
return () => {
|
|
536
|
+
listeners.delete(listener);
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
// src/client/opsActionCenterWidget.ts
|
|
543
|
+
var DEFAULT_TITLE2 = "Voice Ops Action Center";
|
|
544
|
+
var DEFAULT_DESCRIPTION2 = "Run production voice proofs and operator actions from one primitive panel.";
|
|
545
|
+
var escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
546
|
+
var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
|
|
547
|
+
const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
|
|
548
|
+
return {
|
|
549
|
+
actions: snapshot.actions.map((action) => ({
|
|
550
|
+
description: action.description ?? "",
|
|
551
|
+
disabled: Boolean(action.disabled || snapshot.isRunning),
|
|
552
|
+
id: action.id,
|
|
553
|
+
isRunning: snapshot.runningActionId === action.id,
|
|
554
|
+
label: action.label
|
|
555
|
+
})),
|
|
556
|
+
description: options.description ?? DEFAULT_DESCRIPTION2,
|
|
557
|
+
error: snapshot.error,
|
|
558
|
+
isRunning: snapshot.isRunning,
|
|
559
|
+
label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
|
|
560
|
+
lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
|
|
561
|
+
status,
|
|
562
|
+
title: options.title ?? DEFAULT_TITLE2
|
|
563
|
+
};
|
|
564
|
+
};
|
|
565
|
+
var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
|
|
566
|
+
const model = createVoiceOpsActionCenterViewModel(snapshot, options);
|
|
567
|
+
const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml2(action.id)}"${action.disabled ? " disabled" : ""}>
|
|
568
|
+
${escapeHtml2(action.isRunning ? "Working..." : action.label)}
|
|
569
|
+
</button>`).join("");
|
|
570
|
+
return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml2(model.status)}">
|
|
571
|
+
<header class="absolute-voice-ops-action-center__header">
|
|
572
|
+
<span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml2(model.title)}</span>
|
|
573
|
+
<strong class="absolute-voice-ops-action-center__label">${escapeHtml2(model.label)}</strong>
|
|
574
|
+
</header>
|
|
575
|
+
<p class="absolute-voice-ops-action-center__description">${escapeHtml2(model.description)}</p>
|
|
576
|
+
<div class="absolute-voice-ops-action-center__actions">${actions}</div>
|
|
577
|
+
<p class="absolute-voice-ops-action-center__result">${escapeHtml2(model.lastResultLabel)}</p>
|
|
578
|
+
${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml2(model.error)}</p>` : ""}
|
|
579
|
+
</section>`;
|
|
580
|
+
};
|
|
581
|
+
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}`;
|
|
582
|
+
var mountVoiceOpsActionCenter = (element, options = {}) => {
|
|
583
|
+
const store = createVoiceOpsActionCenterStore(options);
|
|
584
|
+
const render = () => {
|
|
585
|
+
element.innerHTML = renderVoiceOpsActionCenterHTML(store.getSnapshot(), options);
|
|
586
|
+
};
|
|
587
|
+
const unsubscribe = store.subscribe(render);
|
|
588
|
+
const handleClick = (event) => {
|
|
589
|
+
const target = event.target;
|
|
590
|
+
if (!(target instanceof Element)) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const action = target.closest("[data-absolute-voice-ops-action]");
|
|
594
|
+
const actionId = action?.getAttribute("data-absolute-voice-ops-action");
|
|
595
|
+
if (actionId) {
|
|
596
|
+
store.run(actionId).catch(() => {});
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
element.addEventListener?.("click", handleClick);
|
|
600
|
+
render();
|
|
601
|
+
return {
|
|
602
|
+
close: () => {
|
|
603
|
+
element.removeEventListener?.("click", handleClick);
|
|
604
|
+
unsubscribe();
|
|
605
|
+
store.close();
|
|
606
|
+
},
|
|
607
|
+
run: store.run
|
|
608
|
+
};
|
|
609
|
+
};
|
|
610
|
+
var defineVoiceOpsActionCenterElement = (tagName = "absolute-voice-ops-action-center", options = {}) => {
|
|
611
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
customElements.define(tagName, class AbsoluteVoiceOpsActionCenterElement extends HTMLElement {
|
|
615
|
+
mounted;
|
|
616
|
+
connectedCallback() {
|
|
617
|
+
this.mounted = mountVoiceOpsActionCenter(this, {
|
|
618
|
+
...options,
|
|
619
|
+
description: this.getAttribute("description") ?? options.description,
|
|
620
|
+
title: this.getAttribute("title") ?? options.title
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
disconnectedCallback() {
|
|
624
|
+
this.mounted?.close();
|
|
625
|
+
this.mounted = undefined;
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// src/vue/useVoiceOpsActionCenter.ts
|
|
631
|
+
import { onUnmounted as onUnmounted2, ref as ref2, shallowRef as shallowRef2 } from "vue";
|
|
632
|
+
function useVoiceOpsActionCenter(options = {}) {
|
|
633
|
+
const store = createVoiceOpsActionCenterStore(options);
|
|
634
|
+
const actions = shallowRef2([]);
|
|
635
|
+
const error = ref2(null);
|
|
636
|
+
const isRunning = ref2(false);
|
|
637
|
+
const lastResult = shallowRef2(undefined);
|
|
638
|
+
const runningActionId = ref2(undefined);
|
|
639
|
+
const updatedAt = ref2(undefined);
|
|
640
|
+
const sync = () => {
|
|
641
|
+
const snapshot = store.getSnapshot();
|
|
642
|
+
actions.value = snapshot.actions;
|
|
643
|
+
error.value = snapshot.error;
|
|
644
|
+
isRunning.value = snapshot.isRunning;
|
|
645
|
+
lastResult.value = snapshot.lastResult;
|
|
646
|
+
runningActionId.value = snapshot.runningActionId;
|
|
647
|
+
updatedAt.value = snapshot.updatedAt;
|
|
648
|
+
};
|
|
649
|
+
const unsubscribe = store.subscribe(sync);
|
|
650
|
+
sync();
|
|
651
|
+
onUnmounted2(() => {
|
|
652
|
+
unsubscribe();
|
|
653
|
+
store.close();
|
|
654
|
+
});
|
|
655
|
+
return {
|
|
656
|
+
actions,
|
|
657
|
+
error,
|
|
658
|
+
isRunning,
|
|
659
|
+
lastResult,
|
|
660
|
+
run: store.run,
|
|
661
|
+
runningActionId,
|
|
662
|
+
setActions: store.setActions,
|
|
663
|
+
updatedAt
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// src/vue/VoiceOpsActionCenter.ts
|
|
668
|
+
var VoiceOpsActionCenter = defineComponent2({
|
|
669
|
+
name: "VoiceOpsActionCenter",
|
|
670
|
+
props: {
|
|
671
|
+
actions: Array,
|
|
672
|
+
description: String,
|
|
673
|
+
title: String
|
|
674
|
+
},
|
|
675
|
+
setup(props) {
|
|
676
|
+
const options = {
|
|
677
|
+
actions: props.actions,
|
|
678
|
+
description: props.description,
|
|
679
|
+
title: props.title
|
|
680
|
+
};
|
|
681
|
+
const center = useVoiceOpsActionCenter(options);
|
|
682
|
+
return () => {
|
|
683
|
+
const model = createVoiceOpsActionCenterViewModel({
|
|
684
|
+
actions: center.actions.value,
|
|
685
|
+
error: center.error.value,
|
|
686
|
+
isRunning: center.isRunning.value,
|
|
687
|
+
lastResult: center.lastResult.value,
|
|
688
|
+
runningActionId: center.runningActionId.value,
|
|
689
|
+
updatedAt: center.updatedAt.value
|
|
690
|
+
}, options);
|
|
691
|
+
return h2("section", {
|
|
692
|
+
class: [
|
|
693
|
+
"absolute-voice-ops-action-center",
|
|
694
|
+
`absolute-voice-ops-action-center--${model.status}`
|
|
695
|
+
]
|
|
696
|
+
}, [
|
|
697
|
+
h2("header", { class: "absolute-voice-ops-action-center__header" }, [
|
|
698
|
+
h2("span", { class: "absolute-voice-ops-action-center__eyebrow" }, model.title),
|
|
699
|
+
h2("strong", { class: "absolute-voice-ops-action-center__label" }, model.label)
|
|
700
|
+
]),
|
|
701
|
+
h2("p", { class: "absolute-voice-ops-action-center__description" }, model.description),
|
|
702
|
+
h2("div", { class: "absolute-voice-ops-action-center__actions" }, model.actions.map((action) => h2("button", {
|
|
703
|
+
disabled: action.disabled,
|
|
704
|
+
key: action.id,
|
|
705
|
+
onClick: () => {
|
|
706
|
+
center.run(action.id).catch(() => {});
|
|
707
|
+
},
|
|
708
|
+
type: "button"
|
|
709
|
+
}, action.isRunning ? "Working..." : action.label))),
|
|
710
|
+
h2("p", { class: "absolute-voice-ops-action-center__result" }, model.lastResultLabel),
|
|
711
|
+
model.error ? h2("p", { class: "absolute-voice-ops-action-center__error" }, model.error) : null
|
|
712
|
+
]);
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
// src/vue/VoiceDeliveryRuntime.ts
|
|
717
|
+
import { defineComponent as defineComponent3, h as h3 } from "vue";
|
|
718
|
+
|
|
380
719
|
// src/client/deliveryRuntime.ts
|
|
720
|
+
var getDefaultActionPath = (path, action, options) => {
|
|
721
|
+
if (action === "tick") {
|
|
722
|
+
return options.tickPath ?? `${path.replace(/\/$/, "")}/tick`;
|
|
723
|
+
}
|
|
724
|
+
return options.requeueDeadLettersPath ?? `${path.replace(/\/$/, "")}/requeue-dead-letters`;
|
|
725
|
+
};
|
|
381
726
|
var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
|
|
382
727
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
383
728
|
const response = await fetchImpl(path);
|
|
@@ -386,11 +731,29 @@ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", opt
|
|
|
386
731
|
}
|
|
387
732
|
return await response.json();
|
|
388
733
|
};
|
|
734
|
+
var runVoiceDeliveryRuntimeAction = async (action, path = "/api/voice-delivery-runtime", options = {}) => {
|
|
735
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
736
|
+
const response = await fetchImpl(getDefaultActionPath(path, action, options), {
|
|
737
|
+
method: "POST"
|
|
738
|
+
});
|
|
739
|
+
if (!response.ok) {
|
|
740
|
+
throw new Error(`Voice delivery runtime ${action} failed: HTTP ${response.status}`);
|
|
741
|
+
}
|
|
742
|
+
const body = await response.json();
|
|
743
|
+
return {
|
|
744
|
+
action,
|
|
745
|
+
result: body.result,
|
|
746
|
+
summary: body.summary,
|
|
747
|
+
updatedAt: Date.now()
|
|
748
|
+
};
|
|
749
|
+
};
|
|
389
750
|
var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
|
|
390
751
|
const listeners = new Set;
|
|
391
752
|
let closed = false;
|
|
392
753
|
let timer;
|
|
393
754
|
let snapshot = {
|
|
755
|
+
actionError: null,
|
|
756
|
+
actionStatus: "idle",
|
|
394
757
|
error: null,
|
|
395
758
|
isLoading: false
|
|
396
759
|
};
|
|
@@ -412,6 +775,7 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
412
775
|
try {
|
|
413
776
|
const report = await fetchVoiceDeliveryRuntime(path, options);
|
|
414
777
|
snapshot = {
|
|
778
|
+
...snapshot,
|
|
415
779
|
error: null,
|
|
416
780
|
isLoading: false,
|
|
417
781
|
report,
|
|
@@ -429,6 +793,37 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
429
793
|
throw error;
|
|
430
794
|
}
|
|
431
795
|
};
|
|
796
|
+
const runAction = async (action) => {
|
|
797
|
+
if (closed) {
|
|
798
|
+
return snapshot.lastAction;
|
|
799
|
+
}
|
|
800
|
+
snapshot = {
|
|
801
|
+
...snapshot,
|
|
802
|
+
actionError: null,
|
|
803
|
+
actionStatus: "running"
|
|
804
|
+
};
|
|
805
|
+
emit();
|
|
806
|
+
try {
|
|
807
|
+
const result = await runVoiceDeliveryRuntimeAction(action, path, options);
|
|
808
|
+
snapshot = {
|
|
809
|
+
...snapshot,
|
|
810
|
+
actionError: null,
|
|
811
|
+
actionStatus: "completed",
|
|
812
|
+
lastAction: result
|
|
813
|
+
};
|
|
814
|
+
emit();
|
|
815
|
+
await refresh();
|
|
816
|
+
return result;
|
|
817
|
+
} catch (error) {
|
|
818
|
+
snapshot = {
|
|
819
|
+
...snapshot,
|
|
820
|
+
actionError: error instanceof Error ? error.message : String(error),
|
|
821
|
+
actionStatus: "failed"
|
|
822
|
+
};
|
|
823
|
+
emit();
|
|
824
|
+
throw error;
|
|
825
|
+
}
|
|
826
|
+
};
|
|
432
827
|
const close = () => {
|
|
433
828
|
closed = true;
|
|
434
829
|
if (timer) {
|
|
@@ -446,7 +841,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
446
841
|
close,
|
|
447
842
|
getServerSnapshot: () => snapshot,
|
|
448
843
|
getSnapshot: () => snapshot,
|
|
844
|
+
requeueDeadLetters: () => runAction("requeue-dead-letters"),
|
|
449
845
|
refresh,
|
|
846
|
+
tick: () => runAction("tick"),
|
|
450
847
|
subscribe: (listener) => {
|
|
451
848
|
listeners.add(listener);
|
|
452
849
|
return () => {
|
|
@@ -457,9 +854,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
|
|
|
457
854
|
};
|
|
458
855
|
|
|
459
856
|
// src/client/deliveryRuntimeWidget.ts
|
|
460
|
-
var
|
|
461
|
-
var
|
|
462
|
-
var
|
|
857
|
+
var DEFAULT_TITLE3 = "Voice Delivery Runtime";
|
|
858
|
+
var DEFAULT_DESCRIPTION3 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
|
|
859
|
+
var escapeHtml3 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
463
860
|
var createSurface = (id, summary) => {
|
|
464
861
|
if (!summary) {
|
|
465
862
|
return {
|
|
@@ -493,45 +890,70 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
|
|
|
493
890
|
];
|
|
494
891
|
const hasWarnings = surfaces.some((surface) => surface.status === "warn");
|
|
495
892
|
return {
|
|
496
|
-
description: options.description ??
|
|
893
|
+
description: options.description ?? DEFAULT_DESCRIPTION3,
|
|
497
894
|
error: snapshot.error,
|
|
895
|
+
actionError: snapshot.actionError,
|
|
896
|
+
actionStatus: snapshot.actionStatus,
|
|
498
897
|
isLoading: snapshot.isLoading,
|
|
499
898
|
isRunning: Boolean(report?.isRunning),
|
|
500
899
|
label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
|
|
501
900
|
status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
|
|
502
901
|
surfaces,
|
|
503
|
-
title: options.title ??
|
|
902
|
+
title: options.title ?? DEFAULT_TITLE3,
|
|
504
903
|
updatedAt: snapshot.updatedAt
|
|
505
904
|
};
|
|
506
905
|
};
|
|
507
906
|
var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
|
|
508
907
|
const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
|
|
509
|
-
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${
|
|
510
|
-
<span>${
|
|
511
|
-
<strong>${
|
|
908
|
+
const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml3(surface.status)}">
|
|
909
|
+
<span>${escapeHtml3(surface.label)}</span>
|
|
910
|
+
<strong>${escapeHtml3(surface.detail)}</strong>
|
|
512
911
|
<small>${String(surface.failed)} failed · ${String(surface.deadLettered)} dead-lettered</small>
|
|
513
912
|
</li>`).join("");
|
|
514
|
-
|
|
913
|
+
const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
|
|
914
|
+
<button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
|
|
915
|
+
<button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
|
|
916
|
+
</div>`;
|
|
917
|
+
const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.actionError)}</p>` : "";
|
|
918
|
+
return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml3(model.status)}">
|
|
515
919
|
<header class="absolute-voice-delivery-runtime__header">
|
|
516
|
-
<span class="absolute-voice-delivery-runtime__eyebrow">${
|
|
517
|
-
<strong class="absolute-voice-delivery-runtime__label">${
|
|
920
|
+
<span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml3(model.title)}</span>
|
|
921
|
+
<strong class="absolute-voice-delivery-runtime__label">${escapeHtml3(model.label)}</strong>
|
|
518
922
|
</header>
|
|
519
|
-
<p class="absolute-voice-delivery-runtime__description">${
|
|
923
|
+
<p class="absolute-voice-delivery-runtime__description">${escapeHtml3(model.description)}</p>
|
|
520
924
|
<ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
|
|
521
|
-
${
|
|
925
|
+
${actions}
|
|
926
|
+
${actionError}
|
|
927
|
+
${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.error)}</p>` : ""}
|
|
522
928
|
</section>`;
|
|
523
929
|
};
|
|
524
|
-
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}`;
|
|
930
|
+
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}`;
|
|
525
931
|
var mountVoiceDeliveryRuntime = (element, path = "/api/voice-delivery-runtime", options = {}) => {
|
|
526
932
|
const store = createVoiceDeliveryRuntimeStore(path, options);
|
|
527
933
|
const render = () => {
|
|
528
934
|
element.innerHTML = renderVoiceDeliveryRuntimeHTML(store.getSnapshot(), options);
|
|
529
935
|
};
|
|
530
936
|
const unsubscribe = store.subscribe(render);
|
|
937
|
+
const handleClick = (event) => {
|
|
938
|
+
const target = event.target;
|
|
939
|
+
if (!(target instanceof Element)) {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
const action = target.closest("[data-absolute-voice-delivery-runtime-action]");
|
|
943
|
+
const actionName = action?.getAttribute("data-absolute-voice-delivery-runtime-action");
|
|
944
|
+
if (actionName === "tick") {
|
|
945
|
+
store.tick().catch(() => {});
|
|
946
|
+
}
|
|
947
|
+
if (actionName === "requeue-dead-letters") {
|
|
948
|
+
store.requeueDeadLetters().catch(() => {});
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
element.addEventListener?.("click", handleClick);
|
|
531
952
|
render();
|
|
532
953
|
store.refresh().catch(() => {});
|
|
533
954
|
return {
|
|
534
955
|
close: () => {
|
|
956
|
+
element.removeEventListener?.("click", handleClick);
|
|
535
957
|
unsubscribe();
|
|
536
958
|
store.close();
|
|
537
959
|
},
|
|
@@ -560,15 +982,19 @@ var defineVoiceDeliveryRuntimeElement = (tagName = "absolute-voice-delivery-runt
|
|
|
560
982
|
};
|
|
561
983
|
|
|
562
984
|
// src/vue/useVoiceDeliveryRuntime.ts
|
|
563
|
-
import { onUnmounted as
|
|
985
|
+
import { onUnmounted as onUnmounted3, ref as ref3, shallowRef as shallowRef3 } from "vue";
|
|
564
986
|
function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options = {}) {
|
|
565
987
|
const store = createVoiceDeliveryRuntimeStore(path, options);
|
|
566
|
-
const
|
|
567
|
-
const
|
|
568
|
-
const
|
|
569
|
-
const
|
|
988
|
+
const actionError = ref3(null);
|
|
989
|
+
const actionStatus = ref3("idle");
|
|
990
|
+
const error = ref3(null);
|
|
991
|
+
const isLoading = ref3(false);
|
|
992
|
+
const report = shallowRef3(undefined);
|
|
993
|
+
const updatedAt = ref3(undefined);
|
|
570
994
|
const sync = () => {
|
|
571
995
|
const snapshot = store.getSnapshot();
|
|
996
|
+
actionError.value = snapshot.actionError;
|
|
997
|
+
actionStatus.value = snapshot.actionStatus;
|
|
572
998
|
error.value = snapshot.error;
|
|
573
999
|
isLoading.value = snapshot.isLoading;
|
|
574
1000
|
report.value = snapshot.report;
|
|
@@ -579,24 +1005,32 @@ function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options =
|
|
|
579
1005
|
if (typeof window !== "undefined") {
|
|
580
1006
|
store.refresh().catch(() => {});
|
|
581
1007
|
}
|
|
582
|
-
|
|
1008
|
+
onUnmounted3(() => {
|
|
583
1009
|
unsubscribe();
|
|
584
1010
|
store.close();
|
|
585
1011
|
});
|
|
586
1012
|
return {
|
|
1013
|
+
actionError,
|
|
1014
|
+
actionStatus,
|
|
587
1015
|
error,
|
|
588
1016
|
isLoading,
|
|
1017
|
+
requeueDeadLetters: store.requeueDeadLetters,
|
|
589
1018
|
refresh: store.refresh,
|
|
590
1019
|
report,
|
|
1020
|
+
tick: store.tick,
|
|
591
1021
|
updatedAt
|
|
592
1022
|
};
|
|
593
1023
|
}
|
|
594
1024
|
|
|
595
1025
|
// src/vue/VoiceDeliveryRuntime.ts
|
|
596
|
-
var VoiceDeliveryRuntime =
|
|
1026
|
+
var VoiceDeliveryRuntime = defineComponent3({
|
|
597
1027
|
name: "VoiceDeliveryRuntime",
|
|
598
1028
|
props: {
|
|
599
1029
|
description: String,
|
|
1030
|
+
includeActions: {
|
|
1031
|
+
default: true,
|
|
1032
|
+
type: Boolean
|
|
1033
|
+
},
|
|
600
1034
|
intervalMs: Number,
|
|
601
1035
|
path: {
|
|
602
1036
|
default: "/api/voice-delivery-runtime",
|
|
@@ -614,39 +1048,59 @@ var VoiceDeliveryRuntime = defineComponent2({
|
|
|
614
1048
|
return () => {
|
|
615
1049
|
const model = createVoiceDeliveryRuntimeViewModel({
|
|
616
1050
|
error: runtime.error.value,
|
|
1051
|
+
actionError: runtime.actionError.value,
|
|
1052
|
+
actionStatus: runtime.actionStatus.value,
|
|
617
1053
|
isLoading: runtime.isLoading.value,
|
|
618
1054
|
report: runtime.report.value,
|
|
619
1055
|
updatedAt: runtime.updatedAt.value
|
|
620
1056
|
}, options);
|
|
621
|
-
|
|
1057
|
+
const hasDeadLetters = model.surfaces.some((surface) => surface.deadLettered > 0);
|
|
1058
|
+
return h3("section", {
|
|
622
1059
|
class: [
|
|
623
1060
|
"absolute-voice-delivery-runtime",
|
|
624
1061
|
`absolute-voice-delivery-runtime--${model.status}`
|
|
625
1062
|
]
|
|
626
1063
|
}, [
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
1064
|
+
h3("header", { class: "absolute-voice-delivery-runtime__header" }, [
|
|
1065
|
+
h3("span", { class: "absolute-voice-delivery-runtime__eyebrow" }, model.title),
|
|
1066
|
+
h3("strong", { class: "absolute-voice-delivery-runtime__label" }, model.label)
|
|
630
1067
|
]),
|
|
631
|
-
|
|
632
|
-
|
|
1068
|
+
h3("p", { class: "absolute-voice-delivery-runtime__description" }, model.description),
|
|
1069
|
+
h3("ul", { class: "absolute-voice-delivery-runtime__surfaces" }, model.surfaces.map((surface) => h3("li", {
|
|
633
1070
|
class: [
|
|
634
1071
|
"absolute-voice-delivery-runtime__surface",
|
|
635
1072
|
`absolute-voice-delivery-runtime__surface--${surface.status}`
|
|
636
1073
|
],
|
|
637
1074
|
key: surface.id
|
|
638
1075
|
}, [
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
1076
|
+
h3("span", surface.label),
|
|
1077
|
+
h3("strong", surface.detail),
|
|
1078
|
+
h3("small", `${surface.failed} failed / ${surface.deadLettered} dead-lettered`)
|
|
642
1079
|
]))),
|
|
643
|
-
|
|
1080
|
+
props.includeActions ? h3("div", { class: "absolute-voice-delivery-runtime__actions" }, [
|
|
1081
|
+
h3("button", {
|
|
1082
|
+
disabled: model.actionStatus === "running",
|
|
1083
|
+
onClick: () => {
|
|
1084
|
+
runtime.tick().catch(() => {});
|
|
1085
|
+
},
|
|
1086
|
+
type: "button"
|
|
1087
|
+
}, model.actionStatus === "running" ? "Working..." : "Tick workers"),
|
|
1088
|
+
h3("button", {
|
|
1089
|
+
disabled: model.actionStatus === "running" || !hasDeadLetters,
|
|
1090
|
+
onClick: () => {
|
|
1091
|
+
runtime.requeueDeadLetters().catch(() => {});
|
|
1092
|
+
},
|
|
1093
|
+
type: "button"
|
|
1094
|
+
}, "Requeue dead letters")
|
|
1095
|
+
]) : null,
|
|
1096
|
+
model.actionError ? h3("p", { class: "absolute-voice-delivery-runtime__error" }, model.actionError) : null,
|
|
1097
|
+
model.error ? h3("p", { class: "absolute-voice-delivery-runtime__error" }, model.error) : null
|
|
644
1098
|
]);
|
|
645
1099
|
};
|
|
646
1100
|
}
|
|
647
1101
|
});
|
|
648
1102
|
// src/vue/VoiceProviderSimulationControls.ts
|
|
649
|
-
import { computed, defineComponent as
|
|
1103
|
+
import { computed, defineComponent as defineComponent4, h as h4 } from "vue";
|
|
650
1104
|
|
|
651
1105
|
// src/client/providerSimulationControls.ts
|
|
652
1106
|
var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
|
|
@@ -728,7 +1182,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
728
1182
|
};
|
|
729
1183
|
|
|
730
1184
|
// src/client/providerSimulationControlsWidget.ts
|
|
731
|
-
var
|
|
1185
|
+
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
732
1186
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
733
1187
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
734
1188
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -748,18 +1202,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
748
1202
|
};
|
|
749
1203
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
750
1204
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
751
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
752
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
1205
|
+
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("");
|
|
1206
|
+
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("");
|
|
753
1207
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
754
1208
|
<header class="absolute-voice-provider-simulation__header">
|
|
755
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
756
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
1209
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml4(model.title)}</span>
|
|
1210
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml4(model.label)}</strong>
|
|
757
1211
|
</header>
|
|
758
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
759
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
1212
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml4(model.description)}</p>
|
|
1213
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml4(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
760
1214
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
761
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
762
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
1215
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml4(snapshot.error)}</p>` : ""}
|
|
1216
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml4(model.resultText)}</pre>` : ""}
|
|
763
1217
|
</section>`;
|
|
764
1218
|
};
|
|
765
1219
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -825,15 +1279,15 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
|
|
|
825
1279
|
};
|
|
826
1280
|
|
|
827
1281
|
// src/vue/useVoiceProviderSimulationControls.ts
|
|
828
|
-
import { onUnmounted as
|
|
1282
|
+
import { onUnmounted as onUnmounted4, ref as ref4 } from "vue";
|
|
829
1283
|
function useVoiceProviderSimulationControls(options) {
|
|
830
1284
|
const store = createVoiceProviderSimulationControlsStore(options);
|
|
831
|
-
const error =
|
|
832
|
-
const isRunning =
|
|
833
|
-
const lastResult =
|
|
834
|
-
const mode =
|
|
835
|
-
const provider =
|
|
836
|
-
const updatedAt =
|
|
1285
|
+
const error = ref4(null);
|
|
1286
|
+
const isRunning = ref4(false);
|
|
1287
|
+
const lastResult = ref4(null);
|
|
1288
|
+
const mode = ref4(null);
|
|
1289
|
+
const provider = ref4(null);
|
|
1290
|
+
const updatedAt = ref4(undefined);
|
|
837
1291
|
const sync = () => {
|
|
838
1292
|
const snapshot = store.getSnapshot();
|
|
839
1293
|
error.value = snapshot.error;
|
|
@@ -845,7 +1299,7 @@ function useVoiceProviderSimulationControls(options) {
|
|
|
845
1299
|
};
|
|
846
1300
|
const unsubscribe = store.subscribe(sync);
|
|
847
1301
|
sync();
|
|
848
|
-
|
|
1302
|
+
onUnmounted4(() => {
|
|
849
1303
|
unsubscribe();
|
|
850
1304
|
store.close();
|
|
851
1305
|
});
|
|
@@ -861,7 +1315,7 @@ function useVoiceProviderSimulationControls(options) {
|
|
|
861
1315
|
}
|
|
862
1316
|
|
|
863
1317
|
// src/vue/VoiceProviderSimulationControls.ts
|
|
864
|
-
var VoiceProviderSimulationControls =
|
|
1318
|
+
var VoiceProviderSimulationControls = defineComponent4({
|
|
865
1319
|
name: "VoiceProviderSimulationControls",
|
|
866
1320
|
props: {
|
|
867
1321
|
class: { default: "", type: String },
|
|
@@ -903,40 +1357,40 @@ var VoiceProviderSimulationControls = defineComponent3({
|
|
|
903
1357
|
const run = (provider, mode) => {
|
|
904
1358
|
controls.run(provider, mode).catch(() => {});
|
|
905
1359
|
};
|
|
906
|
-
return () =>
|
|
1360
|
+
return () => h4("section", {
|
|
907
1361
|
class: [
|
|
908
1362
|
"absolute-voice-provider-simulation",
|
|
909
1363
|
`absolute-voice-provider-simulation--${controls.error.value ? "error" : controls.isRunning.value ? "running" : "ready"}`,
|
|
910
1364
|
props.class
|
|
911
1365
|
]
|
|
912
1366
|
}, [
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
1367
|
+
h4("header", { class: "absolute-voice-provider-simulation__header" }, [
|
|
1368
|
+
h4("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
|
|
1369
|
+
h4("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
|
|
916
1370
|
]),
|
|
917
|
-
|
|
918
|
-
model.value.canSimulateFailure ? null :
|
|
919
|
-
|
|
920
|
-
...model.value.failureProviders.map((provider) =>
|
|
1371
|
+
h4("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
|
|
1372
|
+
model.value.canSimulateFailure ? null : h4("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
|
|
1373
|
+
h4("div", { class: "absolute-voice-provider-simulation__actions" }, [
|
|
1374
|
+
...model.value.failureProviders.map((provider) => h4("button", {
|
|
921
1375
|
disabled: !model.value.canSimulateFailure || controls.isRunning.value,
|
|
922
1376
|
key: `fail-${provider.provider}`,
|
|
923
1377
|
onClick: () => run(provider.provider, "failure"),
|
|
924
1378
|
type: "button"
|
|
925
1379
|
}, `Simulate ${provider.provider} ${props.kind.toUpperCase()} failure`)),
|
|
926
|
-
...model.value.providers.map((provider) =>
|
|
1380
|
+
...model.value.providers.map((provider) => h4("button", {
|
|
927
1381
|
disabled: controls.isRunning.value,
|
|
928
1382
|
key: `recover-${provider.provider}`,
|
|
929
1383
|
onClick: () => run(provider.provider, "recovery"),
|
|
930
1384
|
type: "button"
|
|
931
1385
|
}, `Mark ${provider.provider} recovered`))
|
|
932
1386
|
]),
|
|
933
|
-
controls.error.value ?
|
|
934
|
-
model.value.resultText ?
|
|
1387
|
+
controls.error.value ? h4("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
|
|
1388
|
+
model.value.resultText ? h4("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
|
|
935
1389
|
]);
|
|
936
1390
|
}
|
|
937
1391
|
});
|
|
938
1392
|
// src/vue/VoiceProviderCapabilities.ts
|
|
939
|
-
import { computed as computed2, defineComponent as
|
|
1393
|
+
import { computed as computed2, defineComponent as defineComponent5, h as h5 } from "vue";
|
|
940
1394
|
|
|
941
1395
|
// src/client/providerCapabilities.ts
|
|
942
1396
|
var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
|
|
@@ -1018,9 +1472,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
|
|
|
1018
1472
|
};
|
|
1019
1473
|
|
|
1020
1474
|
// src/client/providerCapabilitiesWidget.ts
|
|
1021
|
-
var
|
|
1022
|
-
var
|
|
1023
|
-
var
|
|
1475
|
+
var DEFAULT_TITLE4 = "Provider Capabilities";
|
|
1476
|
+
var DEFAULT_DESCRIPTION4 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
1477
|
+
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1024
1478
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1025
1479
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
1026
1480
|
var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -1064,36 +1518,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
1064
1518
|
const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
|
|
1065
1519
|
return {
|
|
1066
1520
|
capabilities,
|
|
1067
|
-
description: options.description ??
|
|
1521
|
+
description: options.description ?? DEFAULT_DESCRIPTION4,
|
|
1068
1522
|
error: snapshot.error,
|
|
1069
1523
|
isLoading: snapshot.isLoading,
|
|
1070
1524
|
label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
|
|
1071
1525
|
status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1072
|
-
title: options.title ??
|
|
1526
|
+
title: options.title ?? DEFAULT_TITLE4,
|
|
1073
1527
|
updatedAt: snapshot.updatedAt
|
|
1074
1528
|
};
|
|
1075
1529
|
};
|
|
1076
1530
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
1077
1531
|
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--${
|
|
1532
|
+
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
1533
|
<header>
|
|
1080
|
-
<strong>${
|
|
1081
|
-
<span>${
|
|
1534
|
+
<strong>${escapeHtml5(capability.label)}</strong>
|
|
1535
|
+
<span>${escapeHtml5(formatStatus(capability.status))}</span>
|
|
1082
1536
|
</header>
|
|
1083
|
-
<p>${
|
|
1537
|
+
<p>${escapeHtml5(capability.detail)}</p>
|
|
1084
1538
|
<dl>${capability.rows.map((row) => `<div>
|
|
1085
|
-
<dt>${
|
|
1086
|
-
<dd>${
|
|
1539
|
+
<dt>${escapeHtml5(row.label)}</dt>
|
|
1540
|
+
<dd>${escapeHtml5(row.value)}</dd>
|
|
1087
1541
|
</div>`).join("")}</dl>
|
|
1088
1542
|
</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--${
|
|
1543
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml5(model.status)}">
|
|
1090
1544
|
<header class="absolute-voice-provider-capabilities__header">
|
|
1091
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
1092
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
1545
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml5(model.title)}</span>
|
|
1546
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml5(model.label)}</strong>
|
|
1093
1547
|
</header>
|
|
1094
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
1548
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml5(model.description)}</p>
|
|
1095
1549
|
${capabilities}
|
|
1096
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
1550
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml5(model.error)}</p>` : ""}
|
|
1097
1551
|
</section>`;
|
|
1098
1552
|
};
|
|
1099
1553
|
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,13 +1589,13 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
|
|
|
1135
1589
|
};
|
|
1136
1590
|
|
|
1137
1591
|
// src/vue/useVoiceProviderCapabilities.ts
|
|
1138
|
-
import { onUnmounted as
|
|
1592
|
+
import { onUnmounted as onUnmounted5, shallowRef as shallowRef4 } from "vue";
|
|
1139
1593
|
function useVoiceProviderCapabilities(path = "/api/provider-capabilities", options = {}) {
|
|
1140
1594
|
const store = createVoiceProviderCapabilitiesStore(path, options);
|
|
1141
|
-
const error =
|
|
1142
|
-
const isLoading =
|
|
1143
|
-
const report =
|
|
1144
|
-
const updatedAt =
|
|
1595
|
+
const error = shallowRef4(null);
|
|
1596
|
+
const isLoading = shallowRef4(false);
|
|
1597
|
+
const report = shallowRef4();
|
|
1598
|
+
const updatedAt = shallowRef4(undefined);
|
|
1145
1599
|
const sync = () => {
|
|
1146
1600
|
const snapshot = store.getSnapshot();
|
|
1147
1601
|
error.value = snapshot.error;
|
|
@@ -1152,7 +1606,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
|
|
|
1152
1606
|
const unsubscribe = store.subscribe(sync);
|
|
1153
1607
|
sync();
|
|
1154
1608
|
store.refresh().catch(() => {});
|
|
1155
|
-
|
|
1609
|
+
onUnmounted5(() => {
|
|
1156
1610
|
unsubscribe();
|
|
1157
1611
|
store.close();
|
|
1158
1612
|
});
|
|
@@ -1166,7 +1620,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
|
|
|
1166
1620
|
}
|
|
1167
1621
|
|
|
1168
1622
|
// src/vue/VoiceProviderCapabilities.ts
|
|
1169
|
-
var VoiceProviderCapabilities =
|
|
1623
|
+
var VoiceProviderCapabilities = defineComponent5({
|
|
1170
1624
|
name: "VoiceProviderCapabilities",
|
|
1171
1625
|
props: {
|
|
1172
1626
|
class: {
|
|
@@ -1203,41 +1657,41 @@ var VoiceProviderCapabilities = defineComponent4({
|
|
|
1203
1657
|
report: capabilities.report.value,
|
|
1204
1658
|
updatedAt: capabilities.updatedAt.value
|
|
1205
1659
|
}, options));
|
|
1206
|
-
return () =>
|
|
1660
|
+
return () => h5("section", {
|
|
1207
1661
|
class: [
|
|
1208
1662
|
"absolute-voice-provider-capabilities",
|
|
1209
1663
|
`absolute-voice-provider-capabilities--${model.value.status}`,
|
|
1210
1664
|
props.class
|
|
1211
1665
|
]
|
|
1212
1666
|
}, [
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1667
|
+
h5("header", { class: "absolute-voice-provider-capabilities__header" }, [
|
|
1668
|
+
h5("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
|
|
1669
|
+
h5("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
|
|
1216
1670
|
]),
|
|
1217
|
-
|
|
1218
|
-
model.value.capabilities.length ?
|
|
1671
|
+
h5("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
|
|
1672
|
+
model.value.capabilities.length ? h5("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h5("article", {
|
|
1219
1673
|
class: [
|
|
1220
1674
|
"absolute-voice-provider-capabilities__provider",
|
|
1221
1675
|
`absolute-voice-provider-capabilities__provider--${capability.status}`
|
|
1222
1676
|
],
|
|
1223
1677
|
key: `${capability.kind}:${capability.provider}`
|
|
1224
1678
|
}, [
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1679
|
+
h5("header", [
|
|
1680
|
+
h5("strong", capability.label),
|
|
1681
|
+
h5("span", capability.status)
|
|
1228
1682
|
]),
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1683
|
+
h5("p", capability.detail),
|
|
1684
|
+
h5("dl", capability.rows.map((row) => h5("div", { key: row.label }, [
|
|
1685
|
+
h5("dt", row.label),
|
|
1686
|
+
h5("dd", row.value)
|
|
1233
1687
|
])))
|
|
1234
|
-
]))) :
|
|
1235
|
-
model.value.error ?
|
|
1688
|
+
]))) : h5("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
|
|
1689
|
+
model.value.error ? h5("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
|
|
1236
1690
|
]);
|
|
1237
1691
|
}
|
|
1238
1692
|
});
|
|
1239
1693
|
// src/vue/VoiceProviderStatus.ts
|
|
1240
|
-
import { computed as computed3, defineComponent as
|
|
1694
|
+
import { computed as computed3, defineComponent as defineComponent6, h as h6 } from "vue";
|
|
1241
1695
|
|
|
1242
1696
|
// src/client/providerStatus.ts
|
|
1243
1697
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
@@ -1320,9 +1774,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
1320
1774
|
};
|
|
1321
1775
|
|
|
1322
1776
|
// src/client/providerStatusWidget.ts
|
|
1323
|
-
var
|
|
1324
|
-
var
|
|
1325
|
-
var
|
|
1777
|
+
var DEFAULT_TITLE5 = "Voice Providers";
|
|
1778
|
+
var DEFAULT_DESCRIPTION5 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
1779
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1326
1780
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1327
1781
|
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1328
1782
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -1366,37 +1820,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
1366
1820
|
const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
|
|
1367
1821
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
1368
1822
|
return {
|
|
1369
|
-
description: options.description ??
|
|
1823
|
+
description: options.description ?? DEFAULT_DESCRIPTION5,
|
|
1370
1824
|
error: snapshot.error,
|
|
1371
1825
|
isLoading: snapshot.isLoading,
|
|
1372
1826
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
1373
1827
|
providers,
|
|
1374
1828
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1375
|
-
title: options.title ??
|
|
1829
|
+
title: options.title ?? DEFAULT_TITLE5,
|
|
1376
1830
|
updatedAt: snapshot.updatedAt
|
|
1377
1831
|
};
|
|
1378
1832
|
};
|
|
1379
1833
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
1380
1834
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
1381
|
-
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--${
|
|
1835
|
+
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)}">
|
|
1382
1836
|
<header>
|
|
1383
|
-
<strong>${
|
|
1384
|
-
<span>${
|
|
1837
|
+
<strong>${escapeHtml6(provider.label)}</strong>
|
|
1838
|
+
<span>${escapeHtml6(formatStatus2(provider.status))}</span>
|
|
1385
1839
|
</header>
|
|
1386
|
-
<p>${
|
|
1840
|
+
<p>${escapeHtml6(provider.detail)}</p>
|
|
1387
1841
|
<dl>${provider.rows.map((row) => `<div>
|
|
1388
|
-
<dt>${
|
|
1389
|
-
<dd>${
|
|
1842
|
+
<dt>${escapeHtml6(row.label)}</dt>
|
|
1843
|
+
<dd>${escapeHtml6(row.value)}</dd>
|
|
1390
1844
|
</div>`).join("")}</dl>
|
|
1391
1845
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
1392
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
1846
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml6(model.status)}">
|
|
1393
1847
|
<header class="absolute-voice-provider-status__header">
|
|
1394
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
1395
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
1848
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml6(model.title)}</span>
|
|
1849
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml6(model.label)}</strong>
|
|
1396
1850
|
</header>
|
|
1397
|
-
<p class="absolute-voice-provider-status__description">${
|
|
1851
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml6(model.description)}</p>
|
|
1398
1852
|
${providers}
|
|
1399
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
1853
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
1400
1854
|
</section>`;
|
|
1401
1855
|
};
|
|
1402
1856
|
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}`;
|
|
@@ -1438,13 +1892,13 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
1438
1892
|
};
|
|
1439
1893
|
|
|
1440
1894
|
// src/vue/useVoiceProviderStatus.ts
|
|
1441
|
-
import { onUnmounted as
|
|
1895
|
+
import { onUnmounted as onUnmounted6, ref as ref5, shallowRef as shallowRef5 } from "vue";
|
|
1442
1896
|
function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
|
|
1443
1897
|
const store = createVoiceProviderStatusStore(path, options);
|
|
1444
|
-
const error =
|
|
1445
|
-
const isLoading =
|
|
1446
|
-
const providers =
|
|
1447
|
-
const updatedAt =
|
|
1898
|
+
const error = ref5(null);
|
|
1899
|
+
const isLoading = ref5(false);
|
|
1900
|
+
const providers = shallowRef5([]);
|
|
1901
|
+
const updatedAt = ref5(undefined);
|
|
1448
1902
|
const sync = () => {
|
|
1449
1903
|
const snapshot = store.getSnapshot();
|
|
1450
1904
|
error.value = snapshot.error;
|
|
@@ -1455,7 +1909,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
|
|
|
1455
1909
|
const unsubscribe = store.subscribe(sync);
|
|
1456
1910
|
sync();
|
|
1457
1911
|
store.refresh().catch(() => {});
|
|
1458
|
-
|
|
1912
|
+
onUnmounted6(() => {
|
|
1459
1913
|
unsubscribe();
|
|
1460
1914
|
store.close();
|
|
1461
1915
|
});
|
|
@@ -1469,7 +1923,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
|
|
|
1469
1923
|
}
|
|
1470
1924
|
|
|
1471
1925
|
// src/vue/VoiceProviderStatus.ts
|
|
1472
|
-
var VoiceProviderStatus =
|
|
1926
|
+
var VoiceProviderStatus = defineComponent6({
|
|
1473
1927
|
name: "VoiceProviderStatus",
|
|
1474
1928
|
props: {
|
|
1475
1929
|
class: {
|
|
@@ -1506,41 +1960,41 @@ var VoiceProviderStatus = defineComponent5({
|
|
|
1506
1960
|
providers: status.providers.value,
|
|
1507
1961
|
updatedAt: status.updatedAt.value
|
|
1508
1962
|
}, options));
|
|
1509
|
-
return () =>
|
|
1963
|
+
return () => h6("section", {
|
|
1510
1964
|
class: [
|
|
1511
1965
|
"absolute-voice-provider-status",
|
|
1512
1966
|
`absolute-voice-provider-status--${model.value.status}`,
|
|
1513
1967
|
props.class
|
|
1514
1968
|
]
|
|
1515
1969
|
}, [
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1970
|
+
h6("header", { class: "absolute-voice-provider-status__header" }, [
|
|
1971
|
+
h6("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
|
|
1972
|
+
h6("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
|
|
1519
1973
|
]),
|
|
1520
|
-
|
|
1521
|
-
model.value.providers.length ?
|
|
1974
|
+
h6("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
|
|
1975
|
+
model.value.providers.length ? h6("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h6("article", {
|
|
1522
1976
|
class: [
|
|
1523
1977
|
"absolute-voice-provider-status__provider",
|
|
1524
1978
|
`absolute-voice-provider-status__provider--${provider.status}`
|
|
1525
1979
|
],
|
|
1526
1980
|
key: provider.provider
|
|
1527
1981
|
}, [
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1982
|
+
h6("header", [
|
|
1983
|
+
h6("strong", provider.label),
|
|
1984
|
+
h6("span", provider.status)
|
|
1531
1985
|
]),
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1986
|
+
h6("p", provider.detail),
|
|
1987
|
+
h6("dl", provider.rows.map((row) => h6("div", { key: row.label }, [
|
|
1988
|
+
h6("dt", row.label),
|
|
1989
|
+
h6("dd", row.value)
|
|
1536
1990
|
])))
|
|
1537
|
-
]))) :
|
|
1538
|
-
model.value.error ?
|
|
1991
|
+
]))) : h6("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
|
|
1992
|
+
model.value.error ? h6("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
|
|
1539
1993
|
]);
|
|
1540
1994
|
}
|
|
1541
1995
|
});
|
|
1542
1996
|
// src/vue/VoiceRoutingStatus.ts
|
|
1543
|
-
import { computed as computed4, defineComponent as
|
|
1997
|
+
import { computed as computed4, defineComponent as defineComponent7, h as h7 } from "vue";
|
|
1544
1998
|
|
|
1545
1999
|
// src/client/routingStatus.ts
|
|
1546
2000
|
var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
|
|
@@ -1623,9 +2077,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
1623
2077
|
};
|
|
1624
2078
|
|
|
1625
2079
|
// src/client/routingStatusWidget.ts
|
|
1626
|
-
var
|
|
1627
|
-
var
|
|
1628
|
-
var
|
|
2080
|
+
var DEFAULT_TITLE6 = "Voice Routing";
|
|
2081
|
+
var DEFAULT_DESCRIPTION6 = "Latest provider routing decision from the self-hosted trace store.";
|
|
2082
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1629
2083
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
1630
2084
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
1631
2085
|
const decision = snapshot.decision;
|
|
@@ -1649,30 +2103,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
1649
2103
|
] : [];
|
|
1650
2104
|
return {
|
|
1651
2105
|
decision,
|
|
1652
|
-
description: options.description ??
|
|
2106
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
1653
2107
|
error: snapshot.error,
|
|
1654
2108
|
isLoading: snapshot.isLoading,
|
|
1655
2109
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
1656
2110
|
rows,
|
|
1657
2111
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1658
|
-
title: options.title ??
|
|
2112
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
1659
2113
|
updatedAt: snapshot.updatedAt
|
|
1660
2114
|
};
|
|
1661
2115
|
};
|
|
1662
2116
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
1663
2117
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
1664
2118
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
1665
|
-
<span>${
|
|
1666
|
-
<strong>${
|
|
2119
|
+
<span>${escapeHtml7(row.label)}</span>
|
|
2120
|
+
<strong>${escapeHtml7(row.value)}</strong>
|
|
1667
2121
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
1668
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
2122
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml7(model.status)}">
|
|
1669
2123
|
<header class="absolute-voice-routing-status__header">
|
|
1670
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
1671
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
2124
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml7(model.title)}</span>
|
|
2125
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml7(model.label)}</strong>
|
|
1672
2126
|
</header>
|
|
1673
|
-
<p class="absolute-voice-routing-status__description">${
|
|
2127
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml7(model.description)}</p>
|
|
1674
2128
|
${rows}
|
|
1675
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
2129
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
1676
2130
|
</section>`;
|
|
1677
2131
|
};
|
|
1678
2132
|
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}`;
|
|
@@ -1714,13 +2168,13 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
|
|
|
1714
2168
|
};
|
|
1715
2169
|
|
|
1716
2170
|
// src/vue/useVoiceRoutingStatus.ts
|
|
1717
|
-
import { onUnmounted as
|
|
2171
|
+
import { onUnmounted as onUnmounted7, ref as ref6, shallowRef as shallowRef6 } from "vue";
|
|
1718
2172
|
function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
|
|
1719
2173
|
const store = createVoiceRoutingStatusStore(path, options);
|
|
1720
|
-
const decision =
|
|
1721
|
-
const error =
|
|
1722
|
-
const isLoading =
|
|
1723
|
-
const updatedAt =
|
|
2174
|
+
const decision = shallowRef6(null);
|
|
2175
|
+
const error = ref6(null);
|
|
2176
|
+
const isLoading = ref6(false);
|
|
2177
|
+
const updatedAt = ref6(undefined);
|
|
1724
2178
|
const sync = () => {
|
|
1725
2179
|
const snapshot = store.getSnapshot();
|
|
1726
2180
|
decision.value = snapshot.decision;
|
|
@@ -1731,7 +2185,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
|
|
|
1731
2185
|
const unsubscribe = store.subscribe(sync);
|
|
1732
2186
|
sync();
|
|
1733
2187
|
store.refresh().catch(() => {});
|
|
1734
|
-
|
|
2188
|
+
onUnmounted7(() => {
|
|
1735
2189
|
unsubscribe();
|
|
1736
2190
|
store.close();
|
|
1737
2191
|
});
|
|
@@ -1745,7 +2199,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
|
|
|
1745
2199
|
}
|
|
1746
2200
|
|
|
1747
2201
|
// src/vue/VoiceRoutingStatus.ts
|
|
1748
|
-
var VoiceRoutingStatus =
|
|
2202
|
+
var VoiceRoutingStatus = defineComponent7({
|
|
1749
2203
|
name: "VoiceRoutingStatus",
|
|
1750
2204
|
props: {
|
|
1751
2205
|
class: {
|
|
@@ -1782,28 +2236,28 @@ var VoiceRoutingStatus = defineComponent6({
|
|
|
1782
2236
|
isLoading: status.isLoading.value,
|
|
1783
2237
|
updatedAt: status.updatedAt.value
|
|
1784
2238
|
}, options));
|
|
1785
|
-
return () =>
|
|
2239
|
+
return () => h7("section", {
|
|
1786
2240
|
class: [
|
|
1787
2241
|
"absolute-voice-routing-status",
|
|
1788
2242
|
`absolute-voice-routing-status--${model.value.status}`,
|
|
1789
2243
|
props.class
|
|
1790
2244
|
]
|
|
1791
2245
|
}, [
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
2246
|
+
h7("header", { class: "absolute-voice-routing-status__header" }, [
|
|
2247
|
+
h7("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
|
|
2248
|
+
h7("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
|
|
1795
2249
|
]),
|
|
1796
|
-
|
|
1797
|
-
model.value.rows.length ?
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
]))) :
|
|
1801
|
-
model.value.error ?
|
|
2250
|
+
h7("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
|
|
2251
|
+
model.value.rows.length ? h7("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h7("div", { key: row.label }, [
|
|
2252
|
+
h7("span", row.label),
|
|
2253
|
+
h7("strong", row.value)
|
|
2254
|
+
]))) : h7("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
|
|
2255
|
+
model.value.error ? h7("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
|
|
1802
2256
|
]);
|
|
1803
2257
|
}
|
|
1804
2258
|
});
|
|
1805
2259
|
// src/vue/VoiceTurnLatency.ts
|
|
1806
|
-
import { computed as computed5, defineComponent as
|
|
2260
|
+
import { computed as computed5, defineComponent as defineComponent8, h as h8 } from "vue";
|
|
1807
2261
|
|
|
1808
2262
|
// src/client/turnLatency.ts
|
|
1809
2263
|
var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
|
|
@@ -1909,10 +2363,10 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
|
|
|
1909
2363
|
};
|
|
1910
2364
|
|
|
1911
2365
|
// src/client/turnLatencyWidget.ts
|
|
1912
|
-
var
|
|
1913
|
-
var
|
|
2366
|
+
var DEFAULT_TITLE7 = "Turn Latency";
|
|
2367
|
+
var DEFAULT_DESCRIPTION7 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
1914
2368
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
1915
|
-
var
|
|
2369
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1916
2370
|
var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
1917
2371
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
1918
2372
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -1926,39 +2380,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
1926
2380
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
1927
2381
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
1928
2382
|
return {
|
|
1929
|
-
description: options.description ??
|
|
2383
|
+
description: options.description ?? DEFAULT_DESCRIPTION7,
|
|
1930
2384
|
error: snapshot.error,
|
|
1931
2385
|
isLoading: snapshot.isLoading,
|
|
1932
2386
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
1933
2387
|
proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
|
|
1934
2388
|
showProofAction: Boolean(options.proofPath),
|
|
1935
2389
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1936
|
-
title: options.title ??
|
|
2390
|
+
title: options.title ?? DEFAULT_TITLE7,
|
|
1937
2391
|
turns,
|
|
1938
2392
|
updatedAt: snapshot.updatedAt
|
|
1939
2393
|
};
|
|
1940
2394
|
};
|
|
1941
2395
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
1942
2396
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
1943
|
-
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--${
|
|
2397
|
+
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--${escapeHtml8(turn.status)}">
|
|
1944
2398
|
<header>
|
|
1945
|
-
<strong>${
|
|
1946
|
-
<span>${
|
|
2399
|
+
<strong>${escapeHtml8(turn.label)}</strong>
|
|
2400
|
+
<span>${escapeHtml8(turn.status)}</span>
|
|
1947
2401
|
</header>
|
|
1948
2402
|
<dl>${turn.rows.map((row) => `<div>
|
|
1949
|
-
<dt>${
|
|
1950
|
-
<dd>${
|
|
2403
|
+
<dt>${escapeHtml8(row.label)}</dt>
|
|
2404
|
+
<dd>${escapeHtml8(row.value)}</dd>
|
|
1951
2405
|
</div>`).join("")}</dl>
|
|
1952
2406
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
1953
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
2407
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml8(model.status)}">
|
|
1954
2408
|
<header class="absolute-voice-turn-latency__header">
|
|
1955
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
1956
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
2409
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml8(model.title)}</span>
|
|
2410
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml8(model.label)}</strong>
|
|
1957
2411
|
</header>
|
|
1958
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
1959
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
2412
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml8(model.description)}</p>
|
|
2413
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml8(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
1960
2414
|
${turns}
|
|
1961
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
2415
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml8(model.error)}</p>` : ""}
|
|
1962
2416
|
</section>`;
|
|
1963
2417
|
};
|
|
1964
2418
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -2009,13 +2463,13 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
2009
2463
|
};
|
|
2010
2464
|
|
|
2011
2465
|
// src/vue/useVoiceTurnLatency.ts
|
|
2012
|
-
import { onUnmounted as
|
|
2466
|
+
import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
|
|
2013
2467
|
function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
|
|
2014
2468
|
const store = createVoiceTurnLatencyStore(path, options);
|
|
2015
|
-
const error =
|
|
2016
|
-
const isLoading =
|
|
2017
|
-
const report =
|
|
2018
|
-
const updatedAt =
|
|
2469
|
+
const error = shallowRef7(null);
|
|
2470
|
+
const isLoading = shallowRef7(false);
|
|
2471
|
+
const report = shallowRef7();
|
|
2472
|
+
const updatedAt = shallowRef7(undefined);
|
|
2019
2473
|
const sync = () => {
|
|
2020
2474
|
const snapshot = store.getSnapshot();
|
|
2021
2475
|
error.value = snapshot.error;
|
|
@@ -2026,7 +2480,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
|
|
|
2026
2480
|
const unsubscribe = store.subscribe(sync);
|
|
2027
2481
|
sync();
|
|
2028
2482
|
store.refresh().catch(() => {});
|
|
2029
|
-
|
|
2483
|
+
onUnmounted8(() => {
|
|
2030
2484
|
unsubscribe();
|
|
2031
2485
|
store.close();
|
|
2032
2486
|
});
|
|
@@ -2041,7 +2495,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
|
|
|
2041
2495
|
}
|
|
2042
2496
|
|
|
2043
2497
|
// src/vue/VoiceTurnLatency.ts
|
|
2044
|
-
var VoiceTurnLatency =
|
|
2498
|
+
var VoiceTurnLatency = defineComponent8({
|
|
2045
2499
|
name: "VoiceTurnLatency",
|
|
2046
2500
|
props: {
|
|
2047
2501
|
class: { default: "", type: String },
|
|
@@ -2067,47 +2521,47 @@ var VoiceTurnLatency = defineComponent7({
|
|
|
2067
2521
|
report: latency.report.value,
|
|
2068
2522
|
updatedAt: latency.updatedAt.value
|
|
2069
2523
|
}, options));
|
|
2070
|
-
return () =>
|
|
2524
|
+
return () => h8("section", {
|
|
2071
2525
|
class: [
|
|
2072
2526
|
"absolute-voice-turn-latency",
|
|
2073
2527
|
`absolute-voice-turn-latency--${model.value.status}`,
|
|
2074
2528
|
props.class
|
|
2075
2529
|
]
|
|
2076
2530
|
}, [
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2531
|
+
h8("header", { class: "absolute-voice-turn-latency__header" }, [
|
|
2532
|
+
h8("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
|
|
2533
|
+
h8("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
|
|
2080
2534
|
]),
|
|
2081
|
-
|
|
2082
|
-
model.value.showProofAction ?
|
|
2535
|
+
h8("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
|
|
2536
|
+
model.value.showProofAction ? h8("button", {
|
|
2083
2537
|
class: "absolute-voice-turn-latency__proof",
|
|
2084
2538
|
onClick: () => {
|
|
2085
2539
|
latency.runProof().catch(() => {});
|
|
2086
2540
|
},
|
|
2087
2541
|
type: "button"
|
|
2088
2542
|
}, model.value.proofLabel) : null,
|
|
2089
|
-
model.value.turns.length ?
|
|
2543
|
+
model.value.turns.length ? h8("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h8("article", {
|
|
2090
2544
|
class: [
|
|
2091
2545
|
"absolute-voice-turn-latency__turn",
|
|
2092
2546
|
`absolute-voice-turn-latency__turn--${turn.status}`
|
|
2093
2547
|
],
|
|
2094
2548
|
key: `${turn.sessionId}:${turn.turnId}`
|
|
2095
2549
|
}, [
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2550
|
+
h8("header", [
|
|
2551
|
+
h8("strong", turn.label),
|
|
2552
|
+
h8("span", turn.status)
|
|
2099
2553
|
]),
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2554
|
+
h8("dl", turn.rows.map((row) => h8("div", { key: row.label }, [
|
|
2555
|
+
h8("dt", row.label),
|
|
2556
|
+
h8("dd", row.value)
|
|
2103
2557
|
])))
|
|
2104
|
-
]))) :
|
|
2105
|
-
model.value.error ?
|
|
2558
|
+
]))) : h8("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
|
|
2559
|
+
model.value.error ? h8("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
|
|
2106
2560
|
]);
|
|
2107
2561
|
}
|
|
2108
2562
|
});
|
|
2109
2563
|
// src/vue/VoiceTurnQuality.ts
|
|
2110
|
-
import { computed as computed6, defineComponent as
|
|
2564
|
+
import { computed as computed6, defineComponent as defineComponent9, h as h9 } from "vue";
|
|
2111
2565
|
|
|
2112
2566
|
// src/client/turnQuality.ts
|
|
2113
2567
|
var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
|
|
@@ -2189,9 +2643,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
2189
2643
|
};
|
|
2190
2644
|
|
|
2191
2645
|
// src/client/turnQualityWidget.ts
|
|
2192
|
-
var
|
|
2193
|
-
var
|
|
2194
|
-
var
|
|
2646
|
+
var DEFAULT_TITLE8 = "Turn Quality";
|
|
2647
|
+
var DEFAULT_DESCRIPTION8 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
2648
|
+
var escapeHtml9 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2195
2649
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
2196
2650
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
2197
2651
|
var getTurnDetail = (turn) => {
|
|
@@ -2229,37 +2683,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
2229
2683
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
2230
2684
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
2231
2685
|
return {
|
|
2232
|
-
description: options.description ??
|
|
2686
|
+
description: options.description ?? DEFAULT_DESCRIPTION8,
|
|
2233
2687
|
error: snapshot.error,
|
|
2234
2688
|
isLoading: snapshot.isLoading,
|
|
2235
2689
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
2236
2690
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2237
|
-
title: options.title ??
|
|
2691
|
+
title: options.title ?? DEFAULT_TITLE8,
|
|
2238
2692
|
turns,
|
|
2239
2693
|
updatedAt: snapshot.updatedAt
|
|
2240
2694
|
};
|
|
2241
2695
|
};
|
|
2242
2696
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
2243
2697
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
2244
|
-
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--${
|
|
2698
|
+
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--${escapeHtml9(turn.status)}">
|
|
2245
2699
|
<header>
|
|
2246
|
-
<strong>${
|
|
2247
|
-
<span>${
|
|
2700
|
+
<strong>${escapeHtml9(turn.label)}</strong>
|
|
2701
|
+
<span>${escapeHtml9(turn.status)}</span>
|
|
2248
2702
|
</header>
|
|
2249
|
-
<p>${
|
|
2703
|
+
<p>${escapeHtml9(turn.detail)}</p>
|
|
2250
2704
|
<dl>${turn.rows.map((row) => `<div>
|
|
2251
|
-
<dt>${
|
|
2252
|
-
<dd>${
|
|
2705
|
+
<dt>${escapeHtml9(row.label)}</dt>
|
|
2706
|
+
<dd>${escapeHtml9(row.value)}</dd>
|
|
2253
2707
|
</div>`).join("")}</dl>
|
|
2254
2708
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
2255
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
2709
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml9(model.status)}">
|
|
2256
2710
|
<header class="absolute-voice-turn-quality__header">
|
|
2257
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
2258
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
2711
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml9(model.title)}</span>
|
|
2712
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml9(model.label)}</strong>
|
|
2259
2713
|
</header>
|
|
2260
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
2714
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml9(model.description)}</p>
|
|
2261
2715
|
${turns}
|
|
2262
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
2716
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml9(model.error)}</p>` : ""}
|
|
2263
2717
|
</section>`;
|
|
2264
2718
|
};
|
|
2265
2719
|
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}`;
|
|
@@ -2301,13 +2755,13 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
2301
2755
|
};
|
|
2302
2756
|
|
|
2303
2757
|
// src/vue/useVoiceTurnQuality.ts
|
|
2304
|
-
import { onUnmounted as
|
|
2758
|
+
import { onUnmounted as onUnmounted9, shallowRef as shallowRef8 } from "vue";
|
|
2305
2759
|
function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
|
|
2306
2760
|
const store = createVoiceTurnQualityStore(path, options);
|
|
2307
|
-
const error =
|
|
2308
|
-
const isLoading =
|
|
2309
|
-
const report =
|
|
2310
|
-
const updatedAt =
|
|
2761
|
+
const error = shallowRef8(null);
|
|
2762
|
+
const isLoading = shallowRef8(false);
|
|
2763
|
+
const report = shallowRef8();
|
|
2764
|
+
const updatedAt = shallowRef8(undefined);
|
|
2311
2765
|
const sync = () => {
|
|
2312
2766
|
const snapshot = store.getSnapshot();
|
|
2313
2767
|
error.value = snapshot.error;
|
|
@@ -2318,7 +2772,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
|
|
|
2318
2772
|
const unsubscribe = store.subscribe(sync);
|
|
2319
2773
|
sync();
|
|
2320
2774
|
store.refresh().catch(() => {});
|
|
2321
|
-
|
|
2775
|
+
onUnmounted9(() => {
|
|
2322
2776
|
unsubscribe();
|
|
2323
2777
|
store.close();
|
|
2324
2778
|
});
|
|
@@ -2326,7 +2780,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
|
|
|
2326
2780
|
}
|
|
2327
2781
|
|
|
2328
2782
|
// src/vue/VoiceTurnQuality.ts
|
|
2329
|
-
var VoiceTurnQuality =
|
|
2783
|
+
var VoiceTurnQuality = defineComponent9({
|
|
2330
2784
|
name: "VoiceTurnQuality",
|
|
2331
2785
|
props: {
|
|
2332
2786
|
class: { default: "", type: String },
|
|
@@ -2348,41 +2802,41 @@ var VoiceTurnQuality = defineComponent8({
|
|
|
2348
2802
|
report: quality.report.value,
|
|
2349
2803
|
updatedAt: quality.updatedAt.value
|
|
2350
2804
|
}, options));
|
|
2351
|
-
return () =>
|
|
2805
|
+
return () => h9("section", {
|
|
2352
2806
|
class: [
|
|
2353
2807
|
"absolute-voice-turn-quality",
|
|
2354
2808
|
`absolute-voice-turn-quality--${model.value.status}`,
|
|
2355
2809
|
props.class
|
|
2356
2810
|
]
|
|
2357
2811
|
}, [
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2812
|
+
h9("header", { class: "absolute-voice-turn-quality__header" }, [
|
|
2813
|
+
h9("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
|
|
2814
|
+
h9("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
|
|
2361
2815
|
]),
|
|
2362
|
-
|
|
2363
|
-
model.value.turns.length ?
|
|
2816
|
+
h9("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
|
|
2817
|
+
model.value.turns.length ? h9("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h9("article", {
|
|
2364
2818
|
class: [
|
|
2365
2819
|
"absolute-voice-turn-quality__turn",
|
|
2366
2820
|
`absolute-voice-turn-quality__turn--${turn.status}`
|
|
2367
2821
|
],
|
|
2368
2822
|
key: `${turn.sessionId}:${turn.turnId}`
|
|
2369
2823
|
}, [
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2824
|
+
h9("header", [
|
|
2825
|
+
h9("strong", turn.label),
|
|
2826
|
+
h9("span", turn.status)
|
|
2373
2827
|
]),
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2828
|
+
h9("p", turn.detail),
|
|
2829
|
+
h9("dl", turn.rows.map((row) => h9("div", { key: row.label }, [
|
|
2830
|
+
h9("dt", row.label),
|
|
2831
|
+
h9("dd", row.value)
|
|
2378
2832
|
])))
|
|
2379
|
-
]))) :
|
|
2380
|
-
model.value.error ?
|
|
2833
|
+
]))) : h9("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
|
|
2834
|
+
model.value.error ? h9("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
|
|
2381
2835
|
]);
|
|
2382
2836
|
}
|
|
2383
2837
|
});
|
|
2384
2838
|
// src/vue/useVoiceCampaignDialerProof.ts
|
|
2385
|
-
import { onUnmounted as
|
|
2839
|
+
import { onUnmounted as onUnmounted10, shallowRef as shallowRef9 } from "vue";
|
|
2386
2840
|
|
|
2387
2841
|
// src/client/campaignDialerProof.ts
|
|
2388
2842
|
var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
|
|
@@ -2505,11 +2959,11 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
|
|
|
2505
2959
|
// src/vue/useVoiceCampaignDialerProof.ts
|
|
2506
2960
|
function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof", options = {}) {
|
|
2507
2961
|
const store = createVoiceCampaignDialerProofStore(path, options);
|
|
2508
|
-
const error =
|
|
2509
|
-
const isLoading =
|
|
2510
|
-
const report =
|
|
2511
|
-
const status =
|
|
2512
|
-
const updatedAt =
|
|
2962
|
+
const error = shallowRef9(null);
|
|
2963
|
+
const isLoading = shallowRef9(false);
|
|
2964
|
+
const report = shallowRef9();
|
|
2965
|
+
const status = shallowRef9();
|
|
2966
|
+
const updatedAt = shallowRef9(undefined);
|
|
2513
2967
|
const sync = () => {
|
|
2514
2968
|
const snapshot = store.getSnapshot();
|
|
2515
2969
|
error.value = snapshot.error;
|
|
@@ -2523,7 +2977,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
|
|
|
2523
2977
|
if (typeof window !== "undefined") {
|
|
2524
2978
|
store.refresh().catch(() => {});
|
|
2525
2979
|
}
|
|
2526
|
-
|
|
2980
|
+
onUnmounted10(() => {
|
|
2527
2981
|
unsubscribe();
|
|
2528
2982
|
store.close();
|
|
2529
2983
|
});
|
|
@@ -2538,7 +2992,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
|
|
|
2538
2992
|
};
|
|
2539
2993
|
}
|
|
2540
2994
|
// src/vue/useVoiceStream.ts
|
|
2541
|
-
import { onUnmounted as
|
|
2995
|
+
import { onUnmounted as onUnmounted11, ref as ref7, shallowRef as shallowRef10 } from "vue";
|
|
2542
2996
|
|
|
2543
2997
|
// src/client/actions.ts
|
|
2544
2998
|
var normalizeErrorMessage = (value) => {
|
|
@@ -3183,16 +3637,16 @@ var createVoiceStream = (path, options = {}) => {
|
|
|
3183
3637
|
// src/vue/useVoiceStream.ts
|
|
3184
3638
|
function useVoiceStream(path, options = {}) {
|
|
3185
3639
|
const stream = createVoiceStream(path, options);
|
|
3186
|
-
const assistantAudio =
|
|
3187
|
-
const assistantTexts =
|
|
3188
|
-
const call =
|
|
3189
|
-
const error =
|
|
3190
|
-
const isConnected =
|
|
3191
|
-
const partial =
|
|
3192
|
-
const reconnect =
|
|
3193
|
-
const sessionId =
|
|
3194
|
-
const status =
|
|
3195
|
-
const turns =
|
|
3640
|
+
const assistantAudio = shallowRef10([]);
|
|
3641
|
+
const assistantTexts = shallowRef10([]);
|
|
3642
|
+
const call = shallowRef10(null);
|
|
3643
|
+
const error = ref7(null);
|
|
3644
|
+
const isConnected = ref7(false);
|
|
3645
|
+
const partial = ref7("");
|
|
3646
|
+
const reconnect = shallowRef10(stream.reconnect);
|
|
3647
|
+
const sessionId = ref7(stream.sessionId);
|
|
3648
|
+
const status = ref7(stream.status);
|
|
3649
|
+
const turns = shallowRef10([]);
|
|
3196
3650
|
const sync = () => {
|
|
3197
3651
|
assistantAudio.value = [...stream.assistantAudio];
|
|
3198
3652
|
assistantTexts.value = [...stream.assistantTexts];
|
|
@@ -3211,7 +3665,7 @@ function useVoiceStream(path, options = {}) {
|
|
|
3211
3665
|
unsubscribe();
|
|
3212
3666
|
stream.close();
|
|
3213
3667
|
};
|
|
3214
|
-
|
|
3668
|
+
onUnmounted11(destroy);
|
|
3215
3669
|
return {
|
|
3216
3670
|
assistantAudio,
|
|
3217
3671
|
assistantTexts,
|
|
@@ -3230,7 +3684,7 @@ function useVoiceStream(path, options = {}) {
|
|
|
3230
3684
|
};
|
|
3231
3685
|
}
|
|
3232
3686
|
// src/vue/useVoiceController.ts
|
|
3233
|
-
import { onUnmounted as
|
|
3687
|
+
import { onUnmounted as onUnmounted12, ref as ref8, shallowRef as shallowRef11 } from "vue";
|
|
3234
3688
|
|
|
3235
3689
|
// src/client/htmx.ts
|
|
3236
3690
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -3876,17 +4330,17 @@ var createVoiceController = (path, options = {}) => {
|
|
|
3876
4330
|
// src/vue/useVoiceController.ts
|
|
3877
4331
|
function useVoiceController(path, options = {}) {
|
|
3878
4332
|
const controller = createVoiceController(path, options);
|
|
3879
|
-
const assistantAudio =
|
|
3880
|
-
const assistantTexts =
|
|
3881
|
-
const error =
|
|
3882
|
-
const isConnected =
|
|
3883
|
-
const isRecording =
|
|
3884
|
-
const partial =
|
|
3885
|
-
const reconnect =
|
|
3886
|
-
const recordingError =
|
|
3887
|
-
const sessionId =
|
|
3888
|
-
const status =
|
|
3889
|
-
const turns =
|
|
4333
|
+
const assistantAudio = shallowRef11([]);
|
|
4334
|
+
const assistantTexts = shallowRef11([]);
|
|
4335
|
+
const error = ref8(null);
|
|
4336
|
+
const isConnected = ref8(false);
|
|
4337
|
+
const isRecording = ref8(false);
|
|
4338
|
+
const partial = ref8("");
|
|
4339
|
+
const reconnect = shallowRef11(controller.reconnect);
|
|
4340
|
+
const recordingError = ref8(null);
|
|
4341
|
+
const sessionId = ref8(controller.sessionId);
|
|
4342
|
+
const status = ref8(controller.status);
|
|
4343
|
+
const turns = shallowRef11([]);
|
|
3890
4344
|
const sync = () => {
|
|
3891
4345
|
assistantAudio.value = [...controller.assistantAudio];
|
|
3892
4346
|
assistantTexts.value = [...controller.assistantTexts];
|
|
@@ -3906,7 +4360,7 @@ function useVoiceController(path, options = {}) {
|
|
|
3906
4360
|
unsubscribe();
|
|
3907
4361
|
controller.close();
|
|
3908
4362
|
};
|
|
3909
|
-
|
|
4363
|
+
onUnmounted12(destroy);
|
|
3910
4364
|
return {
|
|
3911
4365
|
assistantAudio,
|
|
3912
4366
|
assistantTexts,
|
|
@@ -3929,7 +4383,7 @@ function useVoiceController(path, options = {}) {
|
|
|
3929
4383
|
};
|
|
3930
4384
|
}
|
|
3931
4385
|
// src/vue/useVoiceTraceTimeline.ts
|
|
3932
|
-
import { onUnmounted as
|
|
4386
|
+
import { onUnmounted as onUnmounted13, ref as ref9, shallowRef as shallowRef12 } from "vue";
|
|
3933
4387
|
|
|
3934
4388
|
// src/client/traceTimeline.ts
|
|
3935
4389
|
var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
|
|
@@ -4014,10 +4468,10 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
|
|
|
4014
4468
|
// src/vue/useVoiceTraceTimeline.ts
|
|
4015
4469
|
function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
|
|
4016
4470
|
const store = createVoiceTraceTimelineStore(path, options);
|
|
4017
|
-
const error =
|
|
4018
|
-
const isLoading =
|
|
4019
|
-
const report =
|
|
4020
|
-
const updatedAt =
|
|
4471
|
+
const error = ref9(null);
|
|
4472
|
+
const isLoading = ref9(false);
|
|
4473
|
+
const report = shallowRef12(null);
|
|
4474
|
+
const updatedAt = ref9(undefined);
|
|
4021
4475
|
const sync = () => {
|
|
4022
4476
|
const snapshot = store.getSnapshot();
|
|
4023
4477
|
error.value = snapshot.error;
|
|
@@ -4028,7 +4482,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
|
|
|
4028
4482
|
const unsubscribe = store.subscribe(sync);
|
|
4029
4483
|
sync();
|
|
4030
4484
|
store.refresh().catch(() => {});
|
|
4031
|
-
|
|
4485
|
+
onUnmounted13(() => {
|
|
4032
4486
|
unsubscribe();
|
|
4033
4487
|
store.close();
|
|
4034
4488
|
});
|
|
@@ -4041,7 +4495,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
|
|
|
4041
4495
|
};
|
|
4042
4496
|
}
|
|
4043
4497
|
// src/vue/useVoiceWorkflowStatus.ts
|
|
4044
|
-
import { onUnmounted as
|
|
4498
|
+
import { onUnmounted as onUnmounted14, ref as ref10, shallowRef as shallowRef13 } from "vue";
|
|
4045
4499
|
|
|
4046
4500
|
// src/client/workflowStatus.ts
|
|
4047
4501
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -4125,10 +4579,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
|
|
|
4125
4579
|
// src/vue/useVoiceWorkflowStatus.ts
|
|
4126
4580
|
function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
|
|
4127
4581
|
const store = createVoiceWorkflowStatusStore(path, options);
|
|
4128
|
-
const error =
|
|
4129
|
-
const isLoading =
|
|
4130
|
-
const report =
|
|
4131
|
-
const updatedAt =
|
|
4582
|
+
const error = ref10(null);
|
|
4583
|
+
const isLoading = ref10(false);
|
|
4584
|
+
const report = shallowRef13(undefined);
|
|
4585
|
+
const updatedAt = ref10(undefined);
|
|
4132
4586
|
const sync = () => {
|
|
4133
4587
|
const snapshot = store.getSnapshot();
|
|
4134
4588
|
error.value = snapshot.error;
|
|
@@ -4141,7 +4595,7 @@ function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
|
|
|
4141
4595
|
if (typeof window !== "undefined") {
|
|
4142
4596
|
store.refresh().catch(() => {});
|
|
4143
4597
|
}
|
|
4144
|
-
|
|
4598
|
+
onUnmounted14(() => {
|
|
4145
4599
|
unsubscribe();
|
|
4146
4600
|
store.close();
|
|
4147
4601
|
});
|
|
@@ -4164,6 +4618,7 @@ export {
|
|
|
4164
4618
|
useVoiceProviderSimulationControls,
|
|
4165
4619
|
useVoiceProviderCapabilities,
|
|
4166
4620
|
useVoiceOpsStatus,
|
|
4621
|
+
useVoiceOpsActionCenter,
|
|
4167
4622
|
useVoiceDeliveryRuntime,
|
|
4168
4623
|
useVoiceController,
|
|
4169
4624
|
useVoiceCampaignDialerProof,
|
|
@@ -4174,5 +4629,6 @@ export {
|
|
|
4174
4629
|
VoiceProviderSimulationControls,
|
|
4175
4630
|
VoiceProviderCapabilities,
|
|
4176
4631
|
VoiceOpsStatus,
|
|
4632
|
+
VoiceOpsActionCenter,
|
|
4177
4633
|
VoiceDeliveryRuntime
|
|
4178
4634
|
};
|