@absolutejs/voice 0.0.22-beta.60 → 0.0.22-beta.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +2 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +192 -12
- package/dist/client/providerSimulationControls.d.ts +33 -0
- package/dist/client/providerSimulationControlsWidget.d.ts +20 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +228 -8
- package/dist/react/VoiceProviderSimulationControls.d.ts +5 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +341 -70
- package/dist/react/useVoiceProviderSimulationControls.d.ts +10 -0
- package/dist/svelte/createVoiceProviderSimulationControls.d.ts +11 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +207 -20
- package/dist/toolRuntime.d.ts +50 -0
- package/dist/vue/VoiceProviderSimulationControls.d.ts +88 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.js +374 -82
- package/dist/vue/useVoiceProviderSimulationControls.d.ts +24 -0
- package/package.json +1 -1
package/dist/vue/index.js
CHANGED
|
@@ -374,9 +374,299 @@ var VoiceOpsStatus = defineComponent({
|
|
|
374
374
|
};
|
|
375
375
|
}
|
|
376
376
|
});
|
|
377
|
-
// src/vue/
|
|
377
|
+
// src/vue/VoiceProviderSimulationControls.ts
|
|
378
378
|
import { computed, defineComponent as defineComponent2, h as h2 } from "vue";
|
|
379
379
|
|
|
380
|
+
// src/client/providerSimulationControls.ts
|
|
381
|
+
var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
|
|
382
|
+
const response = await fetchImpl(`${pathPrefix}/${mode}?provider=${encodeURIComponent(provider)}`, { method: "POST" });
|
|
383
|
+
const body = await response.json().catch(() => null);
|
|
384
|
+
if (!response.ok) {
|
|
385
|
+
const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice provider simulation failed: HTTP ${response.status}`;
|
|
386
|
+
throw new Error(message);
|
|
387
|
+
}
|
|
388
|
+
return body;
|
|
389
|
+
};
|
|
390
|
+
var createVoiceProviderSimulationControlsStore = (options) => {
|
|
391
|
+
const listeners = new Set;
|
|
392
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
393
|
+
const pathPrefix = options.pathPrefix ?? `/api/${options.kind ?? "stt"}-simulate`;
|
|
394
|
+
let closed = false;
|
|
395
|
+
let snapshot = {
|
|
396
|
+
error: null,
|
|
397
|
+
isRunning: false,
|
|
398
|
+
lastResult: null,
|
|
399
|
+
mode: null,
|
|
400
|
+
provider: null
|
|
401
|
+
};
|
|
402
|
+
const emit = () => {
|
|
403
|
+
for (const listener of listeners) {
|
|
404
|
+
listener();
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
const run = async (provider, mode) => {
|
|
408
|
+
if (closed) {
|
|
409
|
+
return snapshot.lastResult;
|
|
410
|
+
}
|
|
411
|
+
snapshot = {
|
|
412
|
+
...snapshot,
|
|
413
|
+
error: null,
|
|
414
|
+
isRunning: true,
|
|
415
|
+
mode,
|
|
416
|
+
provider
|
|
417
|
+
};
|
|
418
|
+
emit();
|
|
419
|
+
try {
|
|
420
|
+
const result = await postSimulation(pathPrefix, mode, provider, fetchImpl);
|
|
421
|
+
snapshot = {
|
|
422
|
+
error: null,
|
|
423
|
+
isRunning: false,
|
|
424
|
+
lastResult: result,
|
|
425
|
+
mode,
|
|
426
|
+
provider,
|
|
427
|
+
updatedAt: Date.now()
|
|
428
|
+
};
|
|
429
|
+
emit();
|
|
430
|
+
return result;
|
|
431
|
+
} catch (error) {
|
|
432
|
+
snapshot = {
|
|
433
|
+
...snapshot,
|
|
434
|
+
error: error instanceof Error ? error.message : String(error),
|
|
435
|
+
isRunning: false
|
|
436
|
+
};
|
|
437
|
+
emit();
|
|
438
|
+
throw error;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
const close = () => {
|
|
442
|
+
closed = true;
|
|
443
|
+
listeners.clear();
|
|
444
|
+
};
|
|
445
|
+
return {
|
|
446
|
+
close,
|
|
447
|
+
getServerSnapshot: () => snapshot,
|
|
448
|
+
getSnapshot: () => snapshot,
|
|
449
|
+
run,
|
|
450
|
+
subscribe: (listener) => {
|
|
451
|
+
listeners.add(listener);
|
|
452
|
+
return () => {
|
|
453
|
+
listeners.delete(listener);
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
// src/client/providerSimulationControlsWidget.ts
|
|
460
|
+
var escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
461
|
+
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
462
|
+
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
463
|
+
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
464
|
+
const fallbackReady = !options.fallbackRequiredProvider || configuredProviders.some((entry) => entry.provider === options.fallbackRequiredProvider);
|
|
465
|
+
const failureProviders = (options.failureProviders ? options.failureProviders.map((provider) => ({ provider })) : configuredProviders).filter((provider) => configuredProviders.some((entry) => entry.provider === provider.provider));
|
|
466
|
+
return {
|
|
467
|
+
canSimulateFailure: configuredProviders.length > 0 && fallbackReady,
|
|
468
|
+
description: options.failureMessage ?? `Simulate ${formatKind(options.kind)} provider failure and recovery without changing credentials.`,
|
|
469
|
+
error: snapshot.error,
|
|
470
|
+
failureProviders,
|
|
471
|
+
isRunning: snapshot.isRunning,
|
|
472
|
+
label: snapshot.isRunning ? `Running ${snapshot.mode ?? "simulation"}` : snapshot.lastResult ? `${snapshot.lastResult.provider} ${snapshot.lastResult.mode} simulated` : configuredProviders.length ? `${configuredProviders.length} configured` : "No configured providers",
|
|
473
|
+
providers: configuredProviders,
|
|
474
|
+
resultText: snapshot.lastResult ? JSON.stringify(snapshot.lastResult, null, 2) : null,
|
|
475
|
+
title: options.title ?? `${formatKind(options.kind)} Failure Simulation`
|
|
476
|
+
};
|
|
477
|
+
};
|
|
478
|
+
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
479
|
+
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
480
|
+
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml2(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml2(provider.provider)} ${escapeHtml2(formatKind(options.kind))} failure</button>`).join("");
|
|
481
|
+
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml2(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml2(provider.provider)} recovered</button>`).join("");
|
|
482
|
+
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
483
|
+
<header class="absolute-voice-provider-simulation__header">
|
|
484
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml2(model.title)}</span>
|
|
485
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml2(model.label)}</strong>
|
|
486
|
+
</header>
|
|
487
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml2(model.description)}</p>
|
|
488
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml2(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
489
|
+
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
490
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml2(snapshot.error)}</p>` : ""}
|
|
491
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml2(model.resultText)}</pre>` : ""}
|
|
492
|
+
</section>`;
|
|
493
|
+
};
|
|
494
|
+
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
495
|
+
const onClick = (event) => {
|
|
496
|
+
const target = event.target;
|
|
497
|
+
if (!(target instanceof HTMLElement)) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const failProvider = target.getAttribute("data-voice-provider-fail");
|
|
501
|
+
const recoverProvider = target.getAttribute("data-voice-provider-recover");
|
|
502
|
+
if (failProvider) {
|
|
503
|
+
store.run(failProvider, "failure").catch(() => {});
|
|
504
|
+
}
|
|
505
|
+
if (recoverProvider) {
|
|
506
|
+
store.run(recoverProvider, "recovery").catch(() => {});
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
element.addEventListener("click", onClick);
|
|
510
|
+
return () => element.removeEventListener("click", onClick);
|
|
511
|
+
};
|
|
512
|
+
var mountVoiceProviderSimulationControls = (element, options) => {
|
|
513
|
+
const store = createVoiceProviderSimulationControlsStore(options);
|
|
514
|
+
const render = () => {
|
|
515
|
+
element.innerHTML = renderVoiceProviderSimulationControlsHTML(store.getSnapshot(), options);
|
|
516
|
+
};
|
|
517
|
+
const unsubscribeStore = store.subscribe(render);
|
|
518
|
+
const unsubscribeDom = bindVoiceProviderSimulationControls(element, store);
|
|
519
|
+
render();
|
|
520
|
+
return {
|
|
521
|
+
close: () => {
|
|
522
|
+
unsubscribeDom();
|
|
523
|
+
unsubscribeStore();
|
|
524
|
+
store.close();
|
|
525
|
+
},
|
|
526
|
+
run: store.run
|
|
527
|
+
};
|
|
528
|
+
};
|
|
529
|
+
var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-provider-simulation") => {
|
|
530
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
customElements.define(tagName, class AbsoluteVoiceProviderSimulationElement extends HTMLElement {
|
|
534
|
+
mounted;
|
|
535
|
+
connectedCallback() {
|
|
536
|
+
const providers = (this.getAttribute("providers") ?? "").split(",").map((provider) => provider.trim()).filter(Boolean).map((provider) => ({ provider }));
|
|
537
|
+
const failureProviders = (this.getAttribute("failure-providers") ?? "").split(",").map((provider) => provider.trim()).filter(Boolean);
|
|
538
|
+
this.mounted = mountVoiceProviderSimulationControls(this, {
|
|
539
|
+
failureProviders: failureProviders.length ? failureProviders : undefined,
|
|
540
|
+
fallbackRequiredMessage: this.getAttribute("fallback-required-message") ?? undefined,
|
|
541
|
+
fallbackRequiredProvider: this.getAttribute("fallback-required-provider") ?? undefined,
|
|
542
|
+
failureMessage: this.getAttribute("failure-message") ?? undefined,
|
|
543
|
+
kind: this.getAttribute("kind") ?? "stt",
|
|
544
|
+
pathPrefix: this.getAttribute("path-prefix") ?? undefined,
|
|
545
|
+
providers,
|
|
546
|
+
title: this.getAttribute("title") ?? undefined
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
disconnectedCallback() {
|
|
550
|
+
this.mounted?.close();
|
|
551
|
+
this.mounted = undefined;
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// src/vue/useVoiceProviderSimulationControls.ts
|
|
557
|
+
import { onUnmounted as onUnmounted2, ref as ref2 } from "vue";
|
|
558
|
+
var useVoiceProviderSimulationControls = (options) => {
|
|
559
|
+
const store = createVoiceProviderSimulationControlsStore(options);
|
|
560
|
+
const error = ref2(null);
|
|
561
|
+
const isRunning = ref2(false);
|
|
562
|
+
const lastResult = ref2(null);
|
|
563
|
+
const mode = ref2(null);
|
|
564
|
+
const provider = ref2(null);
|
|
565
|
+
const updatedAt = ref2(undefined);
|
|
566
|
+
const sync = () => {
|
|
567
|
+
const snapshot = store.getSnapshot();
|
|
568
|
+
error.value = snapshot.error;
|
|
569
|
+
isRunning.value = snapshot.isRunning;
|
|
570
|
+
lastResult.value = snapshot.lastResult;
|
|
571
|
+
mode.value = snapshot.mode;
|
|
572
|
+
provider.value = snapshot.provider;
|
|
573
|
+
updatedAt.value = snapshot.updatedAt;
|
|
574
|
+
};
|
|
575
|
+
const unsubscribe = store.subscribe(sync);
|
|
576
|
+
sync();
|
|
577
|
+
onUnmounted2(() => {
|
|
578
|
+
unsubscribe();
|
|
579
|
+
store.close();
|
|
580
|
+
});
|
|
581
|
+
return {
|
|
582
|
+
error,
|
|
583
|
+
isRunning,
|
|
584
|
+
lastResult,
|
|
585
|
+
mode,
|
|
586
|
+
provider,
|
|
587
|
+
run: store.run,
|
|
588
|
+
updatedAt
|
|
589
|
+
};
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
// src/vue/VoiceProviderSimulationControls.ts
|
|
593
|
+
var VoiceProviderSimulationControls = defineComponent2({
|
|
594
|
+
name: "VoiceProviderSimulationControls",
|
|
595
|
+
props: {
|
|
596
|
+
class: { default: "", type: String },
|
|
597
|
+
fallbackRequiredMessage: { default: undefined, type: String },
|
|
598
|
+
fallbackRequiredProvider: { default: undefined, type: String },
|
|
599
|
+
failureMessage: { default: undefined, type: String },
|
|
600
|
+
failureProviders: {
|
|
601
|
+
default: undefined,
|
|
602
|
+
type: Array
|
|
603
|
+
},
|
|
604
|
+
kind: { default: "stt", type: String },
|
|
605
|
+
pathPrefix: { default: undefined, type: String },
|
|
606
|
+
providers: {
|
|
607
|
+
required: true,
|
|
608
|
+
type: Array
|
|
609
|
+
},
|
|
610
|
+
title: { default: undefined, type: String }
|
|
611
|
+
},
|
|
612
|
+
setup(props) {
|
|
613
|
+
const options = {
|
|
614
|
+
fallbackRequiredMessage: props.fallbackRequiredMessage,
|
|
615
|
+
fallbackRequiredProvider: props.fallbackRequiredProvider,
|
|
616
|
+
failureMessage: props.failureMessage,
|
|
617
|
+
failureProviders: props.failureProviders,
|
|
618
|
+
kind: props.kind,
|
|
619
|
+
pathPrefix: props.pathPrefix,
|
|
620
|
+
providers: props.providers,
|
|
621
|
+
title: props.title
|
|
622
|
+
};
|
|
623
|
+
const controls = useVoiceProviderSimulationControls(options);
|
|
624
|
+
const model = computed(() => createVoiceProviderSimulationControlsViewModel({
|
|
625
|
+
error: controls.error.value,
|
|
626
|
+
isRunning: controls.isRunning.value,
|
|
627
|
+
lastResult: controls.lastResult.value,
|
|
628
|
+
mode: controls.mode.value,
|
|
629
|
+
provider: controls.provider.value,
|
|
630
|
+
updatedAt: controls.updatedAt.value
|
|
631
|
+
}, options));
|
|
632
|
+
const run = (provider, mode) => {
|
|
633
|
+
controls.run(provider, mode).catch(() => {});
|
|
634
|
+
};
|
|
635
|
+
return () => h2("section", {
|
|
636
|
+
class: [
|
|
637
|
+
"absolute-voice-provider-simulation",
|
|
638
|
+
`absolute-voice-provider-simulation--${controls.error.value ? "error" : controls.isRunning.value ? "running" : "ready"}`,
|
|
639
|
+
props.class
|
|
640
|
+
]
|
|
641
|
+
}, [
|
|
642
|
+
h2("header", { class: "absolute-voice-provider-simulation__header" }, [
|
|
643
|
+
h2("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
|
|
644
|
+
h2("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
|
|
645
|
+
]),
|
|
646
|
+
h2("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
|
|
647
|
+
model.value.canSimulateFailure ? null : h2("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
|
|
648
|
+
h2("div", { class: "absolute-voice-provider-simulation__actions" }, [
|
|
649
|
+
...model.value.failureProviders.map((provider) => h2("button", {
|
|
650
|
+
disabled: !model.value.canSimulateFailure || controls.isRunning.value,
|
|
651
|
+
key: `fail-${provider.provider}`,
|
|
652
|
+
onClick: () => run(provider.provider, "failure"),
|
|
653
|
+
type: "button"
|
|
654
|
+
}, `Simulate ${provider.provider} ${props.kind.toUpperCase()} failure`)),
|
|
655
|
+
...model.value.providers.map((provider) => h2("button", {
|
|
656
|
+
disabled: controls.isRunning.value,
|
|
657
|
+
key: `recover-${provider.provider}`,
|
|
658
|
+
onClick: () => run(provider.provider, "recovery"),
|
|
659
|
+
type: "button"
|
|
660
|
+
}, `Mark ${provider.provider} recovered`))
|
|
661
|
+
]),
|
|
662
|
+
controls.error.value ? h2("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
|
|
663
|
+
model.value.resultText ? h2("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
|
|
664
|
+
]);
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
// src/vue/VoiceProviderStatus.ts
|
|
668
|
+
import { computed as computed2, defineComponent as defineComponent3, h as h3 } from "vue";
|
|
669
|
+
|
|
380
670
|
// src/client/providerStatus.ts
|
|
381
671
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
382
672
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -460,7 +750,7 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
460
750
|
// src/client/providerStatusWidget.ts
|
|
461
751
|
var DEFAULT_TITLE2 = "Voice Providers";
|
|
462
752
|
var DEFAULT_DESCRIPTION2 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
463
|
-
var
|
|
753
|
+
var escapeHtml3 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
464
754
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
465
755
|
var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
466
756
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -516,25 +806,25 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
516
806
|
};
|
|
517
807
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
518
808
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
519
|
-
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--${
|
|
809
|
+
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--${escapeHtml3(provider.status)}">
|
|
520
810
|
<header>
|
|
521
|
-
<strong>${
|
|
522
|
-
<span>${
|
|
811
|
+
<strong>${escapeHtml3(provider.label)}</strong>
|
|
812
|
+
<span>${escapeHtml3(formatStatus(provider.status))}</span>
|
|
523
813
|
</header>
|
|
524
|
-
<p>${
|
|
814
|
+
<p>${escapeHtml3(provider.detail)}</p>
|
|
525
815
|
<dl>${provider.rows.map((row) => `<div>
|
|
526
|
-
<dt>${
|
|
527
|
-
<dd>${
|
|
816
|
+
<dt>${escapeHtml3(row.label)}</dt>
|
|
817
|
+
<dd>${escapeHtml3(row.value)}</dd>
|
|
528
818
|
</div>`).join("")}</dl>
|
|
529
819
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
530
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
820
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml3(model.status)}">
|
|
531
821
|
<header class="absolute-voice-provider-status__header">
|
|
532
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
533
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
822
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml3(model.title)}</span>
|
|
823
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml3(model.label)}</strong>
|
|
534
824
|
</header>
|
|
535
|
-
<p class="absolute-voice-provider-status__description">${
|
|
825
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml3(model.description)}</p>
|
|
536
826
|
${providers}
|
|
537
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
827
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml3(model.error)}</p>` : ""}
|
|
538
828
|
</section>`;
|
|
539
829
|
};
|
|
540
830
|
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}`;
|
|
@@ -576,13 +866,13 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
576
866
|
};
|
|
577
867
|
|
|
578
868
|
// src/vue/useVoiceProviderStatus.ts
|
|
579
|
-
import { onUnmounted as
|
|
869
|
+
import { onUnmounted as onUnmounted3, ref as ref3, shallowRef as shallowRef2 } from "vue";
|
|
580
870
|
var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
581
871
|
const store = createVoiceProviderStatusStore(path, options);
|
|
582
|
-
const error =
|
|
583
|
-
const isLoading =
|
|
872
|
+
const error = ref3(null);
|
|
873
|
+
const isLoading = ref3(false);
|
|
584
874
|
const providers = shallowRef2([]);
|
|
585
|
-
const updatedAt =
|
|
875
|
+
const updatedAt = ref3(undefined);
|
|
586
876
|
const sync = () => {
|
|
587
877
|
const snapshot = store.getSnapshot();
|
|
588
878
|
error.value = snapshot.error;
|
|
@@ -593,7 +883,7 @@ var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
|
593
883
|
const unsubscribe = store.subscribe(sync);
|
|
594
884
|
sync();
|
|
595
885
|
store.refresh().catch(() => {});
|
|
596
|
-
|
|
886
|
+
onUnmounted3(() => {
|
|
597
887
|
unsubscribe();
|
|
598
888
|
store.close();
|
|
599
889
|
});
|
|
@@ -607,7 +897,7 @@ var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
|
607
897
|
};
|
|
608
898
|
|
|
609
899
|
// src/vue/VoiceProviderStatus.ts
|
|
610
|
-
var VoiceProviderStatus =
|
|
900
|
+
var VoiceProviderStatus = defineComponent3({
|
|
611
901
|
name: "VoiceProviderStatus",
|
|
612
902
|
props: {
|
|
613
903
|
class: {
|
|
@@ -638,47 +928,47 @@ var VoiceProviderStatus = defineComponent2({
|
|
|
638
928
|
title: props.title
|
|
639
929
|
};
|
|
640
930
|
const status = useVoiceProviderStatus(props.path, options);
|
|
641
|
-
const model =
|
|
931
|
+
const model = computed2(() => createVoiceProviderStatusViewModel({
|
|
642
932
|
error: status.error.value,
|
|
643
933
|
isLoading: status.isLoading.value,
|
|
644
934
|
providers: status.providers.value,
|
|
645
935
|
updatedAt: status.updatedAt.value
|
|
646
936
|
}, options));
|
|
647
|
-
return () =>
|
|
937
|
+
return () => h3("section", {
|
|
648
938
|
class: [
|
|
649
939
|
"absolute-voice-provider-status",
|
|
650
940
|
`absolute-voice-provider-status--${model.value.status}`,
|
|
651
941
|
props.class
|
|
652
942
|
]
|
|
653
943
|
}, [
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
944
|
+
h3("header", { class: "absolute-voice-provider-status__header" }, [
|
|
945
|
+
h3("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
|
|
946
|
+
h3("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
|
|
657
947
|
]),
|
|
658
|
-
|
|
659
|
-
model.value.providers.length ?
|
|
948
|
+
h3("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
|
|
949
|
+
model.value.providers.length ? h3("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h3("article", {
|
|
660
950
|
class: [
|
|
661
951
|
"absolute-voice-provider-status__provider",
|
|
662
952
|
`absolute-voice-provider-status__provider--${provider.status}`
|
|
663
953
|
],
|
|
664
954
|
key: provider.provider
|
|
665
955
|
}, [
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
956
|
+
h3("header", [
|
|
957
|
+
h3("strong", provider.label),
|
|
958
|
+
h3("span", provider.status)
|
|
669
959
|
]),
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
960
|
+
h3("p", provider.detail),
|
|
961
|
+
h3("dl", provider.rows.map((row) => h3("div", { key: row.label }, [
|
|
962
|
+
h3("dt", row.label),
|
|
963
|
+
h3("dd", row.value)
|
|
674
964
|
])))
|
|
675
|
-
]))) :
|
|
676
|
-
model.value.error ?
|
|
965
|
+
]))) : h3("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
|
|
966
|
+
model.value.error ? h3("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
|
|
677
967
|
]);
|
|
678
968
|
}
|
|
679
969
|
});
|
|
680
970
|
// src/vue/VoiceRoutingStatus.ts
|
|
681
|
-
import { computed as
|
|
971
|
+
import { computed as computed3, defineComponent as defineComponent4, h as h4 } from "vue";
|
|
682
972
|
|
|
683
973
|
// src/client/routingStatus.ts
|
|
684
974
|
var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
|
|
@@ -763,7 +1053,7 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
763
1053
|
// src/client/routingStatusWidget.ts
|
|
764
1054
|
var DEFAULT_TITLE3 = "Voice Routing";
|
|
765
1055
|
var DEFAULT_DESCRIPTION3 = "Latest provider routing decision from the self-hosted trace store.";
|
|
766
|
-
var
|
|
1056
|
+
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
767
1057
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
768
1058
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
769
1059
|
const decision = snapshot.decision;
|
|
@@ -800,17 +1090,17 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
800
1090
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
801
1091
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
802
1092
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
803
|
-
<span>${
|
|
804
|
-
<strong>${
|
|
1093
|
+
<span>${escapeHtml4(row.label)}</span>
|
|
1094
|
+
<strong>${escapeHtml4(row.value)}</strong>
|
|
805
1095
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
806
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
1096
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml4(model.status)}">
|
|
807
1097
|
<header class="absolute-voice-routing-status__header">
|
|
808
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
809
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
1098
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml4(model.title)}</span>
|
|
1099
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml4(model.label)}</strong>
|
|
810
1100
|
</header>
|
|
811
|
-
<p class="absolute-voice-routing-status__description">${
|
|
1101
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml4(model.description)}</p>
|
|
812
1102
|
${rows}
|
|
813
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
1103
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml4(model.error)}</p>` : ""}
|
|
814
1104
|
</section>`;
|
|
815
1105
|
};
|
|
816
1106
|
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}`;
|
|
@@ -852,13 +1142,13 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
|
|
|
852
1142
|
};
|
|
853
1143
|
|
|
854
1144
|
// src/vue/useVoiceRoutingStatus.ts
|
|
855
|
-
import { onUnmounted as
|
|
1145
|
+
import { onUnmounted as onUnmounted4, ref as ref4, shallowRef as shallowRef3 } from "vue";
|
|
856
1146
|
var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
857
1147
|
const store = createVoiceRoutingStatusStore(path, options);
|
|
858
1148
|
const decision = shallowRef3(null);
|
|
859
|
-
const error =
|
|
860
|
-
const isLoading =
|
|
861
|
-
const updatedAt =
|
|
1149
|
+
const error = ref4(null);
|
|
1150
|
+
const isLoading = ref4(false);
|
|
1151
|
+
const updatedAt = ref4(undefined);
|
|
862
1152
|
const sync = () => {
|
|
863
1153
|
const snapshot = store.getSnapshot();
|
|
864
1154
|
decision.value = snapshot.decision;
|
|
@@ -869,7 +1159,7 @@ var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
|
869
1159
|
const unsubscribe = store.subscribe(sync);
|
|
870
1160
|
sync();
|
|
871
1161
|
store.refresh().catch(() => {});
|
|
872
|
-
|
|
1162
|
+
onUnmounted4(() => {
|
|
873
1163
|
unsubscribe();
|
|
874
1164
|
store.close();
|
|
875
1165
|
});
|
|
@@ -883,7 +1173,7 @@ var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
|
883
1173
|
};
|
|
884
1174
|
|
|
885
1175
|
// src/vue/VoiceRoutingStatus.ts
|
|
886
|
-
var VoiceRoutingStatus =
|
|
1176
|
+
var VoiceRoutingStatus = defineComponent4({
|
|
887
1177
|
name: "VoiceRoutingStatus",
|
|
888
1178
|
props: {
|
|
889
1179
|
class: {
|
|
@@ -914,34 +1204,34 @@ var VoiceRoutingStatus = defineComponent3({
|
|
|
914
1204
|
title: props.title
|
|
915
1205
|
};
|
|
916
1206
|
const status = useVoiceRoutingStatus(props.path, options);
|
|
917
|
-
const model =
|
|
1207
|
+
const model = computed3(() => createVoiceRoutingStatusViewModel({
|
|
918
1208
|
decision: status.decision.value,
|
|
919
1209
|
error: status.error.value,
|
|
920
1210
|
isLoading: status.isLoading.value,
|
|
921
1211
|
updatedAt: status.updatedAt.value
|
|
922
1212
|
}, options));
|
|
923
|
-
return () =>
|
|
1213
|
+
return () => h4("section", {
|
|
924
1214
|
class: [
|
|
925
1215
|
"absolute-voice-routing-status",
|
|
926
1216
|
`absolute-voice-routing-status--${model.value.status}`,
|
|
927
1217
|
props.class
|
|
928
1218
|
]
|
|
929
1219
|
}, [
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1220
|
+
h4("header", { class: "absolute-voice-routing-status__header" }, [
|
|
1221
|
+
h4("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
|
|
1222
|
+
h4("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
|
|
933
1223
|
]),
|
|
934
|
-
|
|
935
|
-
model.value.rows.length ?
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
]))) :
|
|
939
|
-
model.value.error ?
|
|
1224
|
+
h4("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
|
|
1225
|
+
model.value.rows.length ? h4("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h4("div", { key: row.label }, [
|
|
1226
|
+
h4("span", row.label),
|
|
1227
|
+
h4("strong", row.value)
|
|
1228
|
+
]))) : h4("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
|
|
1229
|
+
model.value.error ? h4("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
|
|
940
1230
|
]);
|
|
941
1231
|
}
|
|
942
1232
|
});
|
|
943
1233
|
// src/vue/useVoiceStream.ts
|
|
944
|
-
import { onUnmounted as
|
|
1234
|
+
import { onUnmounted as onUnmounted5, ref as ref5, shallowRef as shallowRef4 } from "vue";
|
|
945
1235
|
|
|
946
1236
|
// src/client/actions.ts
|
|
947
1237
|
var normalizeErrorMessage = (value) => {
|
|
@@ -1462,11 +1752,11 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
1462
1752
|
const assistantAudio = shallowRef4([]);
|
|
1463
1753
|
const assistantTexts = shallowRef4([]);
|
|
1464
1754
|
const call = shallowRef4(null);
|
|
1465
|
-
const error =
|
|
1466
|
-
const isConnected =
|
|
1467
|
-
const partial =
|
|
1468
|
-
const sessionId =
|
|
1469
|
-
const status =
|
|
1755
|
+
const error = ref5(null);
|
|
1756
|
+
const isConnected = ref5(false);
|
|
1757
|
+
const partial = ref5("");
|
|
1758
|
+
const sessionId = ref5(stream.sessionId);
|
|
1759
|
+
const status = ref5(stream.status);
|
|
1470
1760
|
const turns = shallowRef4([]);
|
|
1471
1761
|
const sync = () => {
|
|
1472
1762
|
assistantAudio.value = [...stream.assistantAudio];
|
|
@@ -1485,7 +1775,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
1485
1775
|
unsubscribe();
|
|
1486
1776
|
stream.close();
|
|
1487
1777
|
};
|
|
1488
|
-
|
|
1778
|
+
onUnmounted5(destroy);
|
|
1489
1779
|
return {
|
|
1490
1780
|
assistantAudio,
|
|
1491
1781
|
assistantTexts,
|
|
@@ -1503,7 +1793,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
1503
1793
|
};
|
|
1504
1794
|
};
|
|
1505
1795
|
// src/vue/useVoiceController.ts
|
|
1506
|
-
import { onUnmounted as
|
|
1796
|
+
import { onUnmounted as onUnmounted6, ref as ref6, shallowRef as shallowRef5 } from "vue";
|
|
1507
1797
|
|
|
1508
1798
|
// src/client/htmx.ts
|
|
1509
1799
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -2140,13 +2430,13 @@ var useVoiceController = (path, options = {}) => {
|
|
|
2140
2430
|
const controller = createVoiceController(path, options);
|
|
2141
2431
|
const assistantAudio = shallowRef5([]);
|
|
2142
2432
|
const assistantTexts = shallowRef5([]);
|
|
2143
|
-
const error =
|
|
2144
|
-
const isConnected =
|
|
2145
|
-
const isRecording =
|
|
2146
|
-
const partial =
|
|
2147
|
-
const recordingError =
|
|
2148
|
-
const sessionId =
|
|
2149
|
-
const status =
|
|
2433
|
+
const error = ref6(null);
|
|
2434
|
+
const isConnected = ref6(false);
|
|
2435
|
+
const isRecording = ref6(false);
|
|
2436
|
+
const partial = ref6("");
|
|
2437
|
+
const recordingError = ref6(null);
|
|
2438
|
+
const sessionId = ref6(controller.sessionId);
|
|
2439
|
+
const status = ref6(controller.status);
|
|
2150
2440
|
const turns = shallowRef5([]);
|
|
2151
2441
|
const sync = () => {
|
|
2152
2442
|
assistantAudio.value = [...controller.assistantAudio];
|
|
@@ -2166,7 +2456,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
2166
2456
|
unsubscribe();
|
|
2167
2457
|
controller.close();
|
|
2168
2458
|
};
|
|
2169
|
-
|
|
2459
|
+
onUnmounted6(destroy);
|
|
2170
2460
|
return {
|
|
2171
2461
|
assistantAudio,
|
|
2172
2462
|
assistantTexts,
|
|
@@ -2188,7 +2478,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
2188
2478
|
};
|
|
2189
2479
|
};
|
|
2190
2480
|
// src/vue/useVoiceWorkflowStatus.ts
|
|
2191
|
-
import { onUnmounted as
|
|
2481
|
+
import { onUnmounted as onUnmounted7, ref as ref7, shallowRef as shallowRef6 } from "vue";
|
|
2192
2482
|
|
|
2193
2483
|
// src/client/workflowStatus.ts
|
|
2194
2484
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -2272,10 +2562,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
|
|
|
2272
2562
|
// src/vue/useVoiceWorkflowStatus.ts
|
|
2273
2563
|
var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
2274
2564
|
const store = createVoiceWorkflowStatusStore(path, options);
|
|
2275
|
-
const error =
|
|
2276
|
-
const isLoading =
|
|
2565
|
+
const error = ref7(null);
|
|
2566
|
+
const isLoading = ref7(false);
|
|
2277
2567
|
const report = shallowRef6(undefined);
|
|
2278
|
-
const updatedAt =
|
|
2568
|
+
const updatedAt = ref7(undefined);
|
|
2279
2569
|
const sync = () => {
|
|
2280
2570
|
const snapshot = store.getSnapshot();
|
|
2281
2571
|
error.value = snapshot.error;
|
|
@@ -2288,7 +2578,7 @@ var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
|
2288
2578
|
if (typeof window !== "undefined") {
|
|
2289
2579
|
store.refresh().catch(() => {});
|
|
2290
2580
|
}
|
|
2291
|
-
|
|
2581
|
+
onUnmounted7(() => {
|
|
2292
2582
|
unsubscribe();
|
|
2293
2583
|
store.close();
|
|
2294
2584
|
});
|
|
@@ -2305,9 +2595,11 @@ export {
|
|
|
2305
2595
|
useVoiceStream,
|
|
2306
2596
|
useVoiceRoutingStatus,
|
|
2307
2597
|
useVoiceProviderStatus,
|
|
2598
|
+
useVoiceProviderSimulationControls,
|
|
2308
2599
|
useVoiceController,
|
|
2309
2600
|
useVoiceAppKitStatus,
|
|
2310
2601
|
VoiceRoutingStatus,
|
|
2311
2602
|
VoiceProviderStatus,
|
|
2603
|
+
VoiceProviderSimulationControls,
|
|
2312
2604
|
VoiceOpsStatus
|
|
2313
2605
|
};
|