@absolutejs/voice 0.0.22-beta.49 → 0.0.22-beta.491
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 +4556 -603
- package/dist/agent.d.ts +67 -5
- package/dist/agentSquadContract.d.ts +98 -0
- package/dist/agentState.d.ts +12 -0
- package/dist/agentTools.d.ts +133 -0
- package/dist/aiVoiceModel.d.ts +15 -0
- package/dist/amdDetector.d.ts +25 -0
- package/dist/angular/index.d.ts +24 -4
- package/dist/angular/index.js +4147 -1164
- package/dist/angular/voice-agent-squad-status.service.d.ts +12 -0
- package/dist/angular/voice-call-debugger.service.d.ts +12 -0
- package/dist/angular/voice-campaign-dialer-proof.service.d.ts +14 -0
- package/dist/angular/voice-controller.service.d.ts +3 -1
- package/dist/angular/voice-delivery-runtime.component.d.ts +17 -0
- package/dist/angular/voice-delivery-runtime.service.d.ts +16 -0
- package/dist/angular/voice-live-ops.service.d.ts +11 -0
- package/dist/angular/voice-ops-action-center.service.d.ts +13 -0
- package/dist/angular/voice-ops-status.component.d.ts +15 -0
- package/dist/angular/voice-ops-status.service.d.ts +12 -0
- package/dist/angular/voice-platform-coverage.service.d.ts +12 -0
- package/dist/angular/voice-profile-comparison.service.d.ts +12 -0
- package/dist/angular/voice-proof-trends.service.d.ts +12 -0
- package/dist/angular/voice-provider-capabilities.service.d.ts +12 -0
- package/dist/angular/voice-provider-contracts.service.d.ts +12 -0
- package/dist/angular/voice-provider-status.service.d.ts +2 -2
- package/dist/angular/voice-readiness-failures.service.d.ts +13 -0
- package/dist/angular/voice-reconnect-profile-evidence.service.d.ts +12 -0
- package/dist/angular/voice-routing-status.service.d.ts +11 -0
- package/dist/angular/voice-session-observability.service.d.ts +12 -0
- package/dist/angular/voice-session-snapshot.service.d.ts +13 -0
- package/dist/angular/voice-stream.service.d.ts +4 -1
- package/dist/angular/voice-trace-timeline.service.d.ts +12 -0
- package/dist/angular/voice-turn-latency.service.d.ts +13 -0
- package/dist/angular/voice-turn-quality.service.d.ts +12 -0
- package/dist/angular/voice-workflow-status.service.d.ts +2 -2
- package/dist/assistant.d.ts +11 -11
- package/dist/assistantHealth.d.ts +6 -6
- package/dist/assistantMemory.d.ts +3 -3
- package/dist/assistantMode.d.ts +22 -0
- package/dist/audioConditioning.d.ts +1 -1
- package/dist/audit.d.ts +131 -0
- package/dist/auditDeliveryRoutes.d.ts +85 -0
- package/dist/auditExport.d.ts +34 -0
- package/dist/auditRoutes.d.ts +66 -0
- package/dist/auditSinks.d.ts +151 -0
- package/dist/backchannel.d.ts +18 -0
- package/dist/bargeInRoutes.d.ts +56 -0
- package/dist/browserCallProfiles.d.ts +120 -0
- package/dist/browserMediaRoutes.d.ts +62 -0
- package/dist/callDebugger.d.ts +66 -0
- package/dist/callerMemory.d.ts +37 -0
- package/dist/campaign.d.ts +794 -0
- package/dist/campaignControls.d.ts +37 -0
- package/dist/campaignDialers.d.ts +111 -0
- package/dist/client/actions.d.ts +95 -1
- package/dist/client/agentSquadStatus.d.ts +37 -0
- package/dist/client/agentSquadStatusWidget.d.ts +24 -0
- package/dist/client/audioPlayer.d.ts +2 -2
- package/dist/client/bargeInMonitor.d.ts +7 -0
- package/dist/client/browserMedia.d.ts +8 -0
- package/dist/client/callDebugger.d.ts +19 -0
- package/dist/client/callDebuggerWidget.d.ts +30 -0
- package/dist/client/campaignDialerProof.d.ts +23 -0
- package/dist/client/connection.d.ts +4 -3
- package/dist/client/controller.d.ts +1 -1
- package/dist/client/createVoiceStream.d.ts +1 -1
- package/dist/client/deliveryRuntime.d.ts +34 -0
- package/dist/client/deliveryRuntimeWidget.d.ts +37 -0
- package/dist/client/duplex.d.ts +2 -2
- package/dist/client/htmx.d.ts +1 -1
- package/dist/client/htmxBootstrap.js +967 -14
- package/dist/client/index.d.ts +104 -11
- package/dist/client/index.js +10215 -19
- package/dist/client/liveOps.d.ts +22 -0
- package/dist/client/liveOpsWidget.d.ts +23 -0
- package/dist/client/liveTurnLatency.d.ts +41 -0
- package/dist/client/microphone.d.ts +4 -4
- package/dist/client/opsActionCenter.d.ts +54 -0
- package/dist/client/opsActionCenterWidget.d.ts +29 -0
- package/dist/client/opsActionHistory.d.ts +19 -0
- package/dist/client/opsActionHistoryWidget.d.ts +11 -0
- package/dist/client/opsStatus.d.ts +19 -0
- package/dist/client/opsStatusWidget.d.ts +40 -0
- package/dist/client/platformCoverage.d.ts +19 -0
- package/dist/client/platformCoverageWidget.d.ts +37 -0
- package/dist/client/profileComparison.d.ts +19 -0
- package/dist/client/profileComparisonWidget.d.ts +41 -0
- package/dist/client/profileSwitchRecommendation.d.ts +19 -0
- package/dist/client/profileSwitchRecommendationWidget.d.ts +12 -0
- package/dist/client/proofTrends.d.ts +19 -0
- package/dist/client/proofTrendsWidget.d.ts +37 -0
- package/dist/client/providerCapabilities.d.ts +19 -0
- package/dist/client/providerCapabilitiesWidget.d.ts +32 -0
- package/dist/client/providerContracts.d.ts +19 -0
- package/dist/client/providerContractsWidget.d.ts +37 -0
- package/dist/client/providerSimulationControls.d.ts +33 -0
- package/dist/client/providerSimulationControlsWidget.d.ts +20 -0
- package/dist/client/providerStatus.d.ts +1 -1
- package/dist/client/providerStatusWidget.d.ts +32 -0
- package/dist/client/readinessFailures.d.ts +19 -0
- package/dist/client/readinessFailuresWidget.d.ts +42 -0
- package/dist/client/reconnectProfileEvidence.d.ts +19 -0
- package/dist/client/reconnectProfileEvidenceWidget.d.ts +39 -0
- package/dist/client/routingStatus.d.ts +19 -0
- package/dist/client/routingStatusWidget.d.ts +32 -0
- package/dist/client/sessionObservability.d.ts +19 -0
- package/dist/client/sessionObservabilityWidget.d.ts +31 -0
- package/dist/client/sessionSnapshot.d.ts +21 -0
- package/dist/client/sessionSnapshotWidget.d.ts +33 -0
- package/dist/client/store.d.ts +1 -1
- package/dist/client/traceTimeline.d.ts +19 -0
- package/dist/client/traceTimelineWidget.d.ts +36 -0
- package/dist/client/turnLatency.d.ts +22 -0
- package/dist/client/turnLatencyWidget.d.ts +33 -0
- package/dist/client/turnQuality.d.ts +19 -0
- package/dist/client/turnQualityWidget.d.ts +32 -0
- package/dist/client/workflowStatus.d.ts +1 -1
- package/dist/competitiveCoverage.d.ts +141 -0
- package/dist/correction.d.ts +2 -2
- package/dist/costAccounting.d.ts +76 -0
- package/dist/dataControl.d.ts +180 -0
- package/dist/deliveryRuntime.d.ts +158 -0
- package/dist/deliverySinkRoutes.d.ts +117 -0
- package/dist/demoReadyRoutes.d.ts +98 -0
- package/dist/diagnosticsRoutes.d.ts +2 -2
- package/dist/evalRoutes.d.ts +10 -4
- package/dist/fileStore.d.ts +21 -7
- package/dist/generated/htmxBootstrapBundle.d.ts +1 -0
- package/dist/guardrails.d.ts +128 -0
- package/dist/handoff.d.ts +6 -6
- package/dist/handoffHealth.d.ts +5 -5
- package/dist/htmx.d.ts +1 -1
- package/dist/incidentBundle.d.ts +119 -0
- package/dist/incidentTimeline.d.ts +260 -0
- package/dist/index.d.ts +260 -74
- package/dist/index.js +40511 -7214
- package/dist/ivrPlan.d.ts +40 -0
- package/dist/latencySlo.d.ts +56 -0
- package/dist/liveLatency.d.ts +78 -0
- package/dist/liveOps.d.ts +190 -0
- package/dist/llmJudge.d.ts +45 -0
- package/dist/logger.d.ts +1 -1
- package/dist/mediaPipelineRoutes.d.ts +171 -0
- package/dist/mediaPipelineSurfaces.d.ts +48 -0
- package/dist/memoryStore.d.ts +1 -1
- package/dist/modelAdapters.d.ts +59 -7
- package/dist/monitor.d.ts +148 -0
- package/dist/multilingualProof.d.ts +77 -0
- package/dist/observabilityExport.d.ts +501 -0
- package/dist/openaiTTS.d.ts +18 -0
- package/dist/operationalStatus.d.ts +87 -0
- package/dist/operationsRecord.d.ts +370 -0
- package/dist/ops.d.ts +12 -12
- package/dist/opsActionAuditRoutes.d.ts +99 -0
- package/dist/opsConsoleRoutes.d.ts +8 -5
- package/dist/opsPresets.d.ts +2 -2
- package/dist/opsRecovery.d.ts +137 -0
- package/dist/opsRuntime.d.ts +6 -6
- package/dist/opsSinks.d.ts +13 -13
- package/dist/opsStatus.d.ts +76 -0
- package/dist/opsStatusRoutes.d.ts +33 -0
- package/dist/opsWebhook.d.ts +6 -6
- package/dist/otelExporter.d.ts +83 -0
- package/dist/outcomeContract.d.ts +146 -0
- package/dist/outcomeRecipes.d.ts +4 -4
- package/dist/phoneAgent.d.ts +139 -0
- package/dist/phoneAgentProductionSmoke.d.ts +115 -0
- package/dist/platformCoverage.d.ts +91 -0
- package/dist/plugin.d.ts +2 -2
- package/dist/postCallAnalysis.d.ts +98 -0
- package/dist/postgresStore.d.ts +17 -6
- package/dist/presets.d.ts +3 -3
- package/dist/productionReadiness.d.ts +756 -0
- package/dist/profileSwitchRecommendation.d.ts +350 -0
- package/dist/proofAssertions.d.ts +32 -0
- package/dist/proofPack.d.ts +211 -0
- package/dist/proofRunner.d.ts +79 -0
- package/dist/proofTrends.d.ts +966 -0
- package/dist/providerAdapters.d.ts +16 -5
- package/dist/providerCapabilities.d.ts +92 -0
- package/dist/providerDecisionTraces.d.ts +130 -0
- package/dist/providerHealth.d.ts +3 -3
- package/dist/providerOrchestration.d.ts +109 -0
- package/dist/providerRouterTraces.d.ts +35 -0
- package/dist/providerRoutingContract.d.ts +71 -0
- package/dist/providerSlo.d.ts +142 -0
- package/dist/providerStackRecommendations.d.ts +187 -0
- package/dist/qualityRoutes.d.ts +4 -4
- package/dist/queue.d.ts +23 -14
- package/dist/ragTool.d.ts +47 -0
- package/dist/react/VoiceAgentSquadStatus.d.ts +5 -0
- package/dist/react/VoiceCallDebuggerLaunch.d.ts +6 -0
- package/dist/react/VoiceDeliveryRuntime.d.ts +7 -0
- package/dist/react/VoiceOpsActionCenter.d.ts +5 -0
- package/dist/react/VoiceOpsStatus.d.ts +6 -0
- package/dist/react/VoicePlatformCoverage.d.ts +6 -0
- package/dist/react/VoiceProfileComparison.d.ts +6 -0
- package/dist/react/VoiceProfileSwitchRecommendation.d.ts +6 -0
- package/dist/react/VoiceProofTrends.d.ts +6 -0
- package/dist/react/VoiceProviderCapabilities.d.ts +6 -0
- package/dist/react/VoiceProviderContracts.d.ts +6 -0
- package/dist/react/VoiceProviderSimulationControls.d.ts +5 -0
- package/dist/react/VoiceProviderStatus.d.ts +6 -0
- package/dist/react/VoiceReadinessFailures.d.ts +6 -0
- package/dist/react/VoiceReconnectProfileEvidence.d.ts +6 -0
- package/dist/react/VoiceRoutingStatus.d.ts +6 -0
- package/dist/react/VoiceSessionObservability.d.ts +6 -0
- package/dist/react/VoiceSessionSnapshot.d.ts +6 -0
- package/dist/react/VoiceTraceTimeline.d.ts +6 -0
- package/dist/react/VoiceTurnLatency.d.ts +6 -0
- package/dist/react/VoiceTurnQuality.d.ts +6 -0
- package/dist/react/index.d.ts +47 -4
- package/dist/react/index.js +11230 -116
- package/dist/react/useVoiceAgentSquadStatus.d.ts +8 -0
- package/dist/react/useVoiceCallDebugger.d.ts +8 -0
- package/dist/react/useVoiceCampaignDialerProof.d.ts +10 -0
- package/dist/react/useVoiceController.d.ts +4 -1
- package/dist/react/useVoiceDeliveryRuntime.d.ts +13 -0
- package/dist/react/useVoiceLiveOps.d.ts +9 -0
- package/dist/react/useVoiceOpsActionCenter.d.ts +11 -0
- package/dist/react/useVoiceOpsStatus.d.ts +8 -0
- package/dist/react/useVoicePlatformCoverage.d.ts +8 -0
- package/dist/react/useVoiceProfileComparison.d.ts +8 -0
- package/dist/react/useVoiceProfileSwitchRecommendation.d.ts +8 -0
- package/dist/react/useVoiceProofTrends.d.ts +8 -0
- package/dist/react/useVoiceProviderCapabilities.d.ts +8 -0
- package/dist/react/useVoiceProviderContracts.d.ts +8 -0
- package/dist/react/useVoiceProviderSimulationControls.d.ts +10 -0
- package/dist/react/useVoiceProviderStatus.d.ts +1 -1
- package/dist/react/useVoiceReadinessFailures.d.ts +8 -0
- package/dist/react/useVoiceReconnectProfileEvidence.d.ts +8 -0
- package/dist/react/useVoiceRoutingStatus.d.ts +8 -0
- package/dist/react/useVoiceSessionObservability.d.ts +8 -0
- package/dist/react/useVoiceSessionSnapshot.d.ts +9 -0
- package/dist/react/useVoiceStream.d.ts +4 -1
- package/dist/react/useVoiceTraceTimeline.d.ts +8 -0
- package/dist/react/useVoiceTurnLatency.d.ts +9 -0
- package/dist/react/useVoiceTurnQuality.d.ts +8 -0
- package/dist/react/useVoiceWorkflowStatus.d.ts +1 -1
- package/dist/readinessProfiles.d.ts +45 -0
- package/dist/realtimeChannel.d.ts +136 -0
- package/dist/realtimeProviderContracts.d.ts +133 -0
- package/dist/reconnectContract.d.ts +176 -0
- package/dist/recordingStore.d.ts +21 -0
- package/dist/redaction.d.ts +13 -0
- package/dist/resilienceRoutes.d.ts +45 -5
- package/dist/routing.d.ts +1 -1
- package/dist/runtimeOps.d.ts +3 -3
- package/dist/s3Store.d.ts +18 -3
- package/dist/semanticTurn.d.ts +27 -0
- package/dist/session.d.ts +1 -1
- package/dist/sessionObservability.d.ts +145 -0
- package/dist/sessionReplay.d.ts +19 -7
- package/dist/sessionSnapshot.d.ts +109 -0
- package/dist/simulationSuite.d.ts +143 -0
- package/dist/sloCalibration.d.ts +185 -0
- package/dist/sqliteStore.d.ts +17 -6
- package/dist/store.d.ts +1 -1
- package/dist/svelte/createVoiceAgentSquadStatus.d.ts +9 -0
- package/dist/svelte/createVoiceCallDebugger.d.ts +12 -0
- package/dist/svelte/createVoiceCampaignDialerProof.d.ts +9 -0
- package/dist/svelte/createVoiceDeliveryRuntime.d.ts +11 -0
- package/dist/svelte/createVoiceLiveOps.d.ts +13 -0
- package/dist/svelte/createVoiceOpsActionCenter.d.ts +10 -0
- package/dist/svelte/createVoiceOpsStatus.d.ts +9 -0
- package/dist/svelte/createVoicePlatformCoverage.d.ts +7 -0
- package/dist/svelte/createVoiceProfileComparison.d.ts +7 -0
- package/dist/svelte/createVoiceProofTrends.d.ts +7 -0
- package/dist/svelte/createVoiceProviderCapabilities.d.ts +10 -0
- package/dist/svelte/createVoiceProviderContracts.d.ts +10 -0
- package/dist/svelte/createVoiceProviderSimulationControls.d.ts +11 -0
- package/dist/svelte/createVoiceProviderStatus.d.ts +4 -2
- package/dist/svelte/createVoiceReadinessFailures.d.ts +7 -0
- package/dist/svelte/createVoiceReconnectProfileEvidence.d.ts +7 -0
- package/dist/svelte/createVoiceRoutingStatus.d.ts +10 -0
- package/dist/svelte/createVoiceSessionObservability.d.ts +10 -0
- package/dist/svelte/createVoiceSessionSnapshot.d.ts +13 -0
- package/dist/svelte/createVoiceStream.d.ts +1 -1
- package/dist/svelte/createVoiceTraceTimeline.d.ts +10 -0
- package/dist/svelte/createVoiceTurnLatency.d.ts +11 -0
- package/dist/svelte/createVoiceTurnQuality.d.ts +10 -0
- package/dist/svelte/createVoiceWorkflowStatus.d.ts +1 -1
- package/dist/svelte/index.d.ts +25 -4
- package/dist/svelte/index.js +5956 -462
- package/dist/telephony/contract.d.ts +61 -0
- package/dist/telephony/matrix.d.ts +97 -0
- package/dist/telephony/plivo.d.ts +303 -0
- package/dist/telephony/response.d.ts +1 -1
- package/dist/telephony/security.d.ts +182 -0
- package/dist/telephony/telnyx.d.ts +291 -0
- package/dist/telephony/twilio.d.ts +147 -13
- package/dist/telephonyMediaRoutes.d.ts +72 -0
- package/dist/telephonyOutcome.d.ts +273 -0
- package/dist/testing/accuracy.d.ts +1 -1
- package/dist/testing/benchmark.d.ts +9 -9
- package/dist/testing/corrected.d.ts +5 -5
- package/dist/testing/duplex.d.ts +3 -3
- package/dist/testing/fixtures.d.ts +3 -3
- package/dist/testing/index.d.ts +13 -13
- package/dist/testing/index.js +5199 -175
- package/dist/testing/ioProviderSimulator.d.ts +5 -5
- package/dist/testing/providerSimulator.d.ts +5 -5
- package/dist/testing/review.d.ts +4 -4
- package/dist/testing/sessionBenchmark.d.ts +3 -3
- package/dist/testing/stt.d.ts +3 -3
- package/dist/testing/telephony.d.ts +25 -0
- package/dist/testing/tts.d.ts +1 -1
- package/dist/toolContract.d.ts +161 -0
- package/dist/toolRuntime.d.ts +50 -0
- package/dist/trace.d.ts +46 -7
- package/dist/traceDeliveryRoutes.d.ts +86 -0
- package/dist/traceTimeline.d.ts +97 -0
- package/dist/turnDetection.d.ts +1 -1
- package/dist/turnLatency.d.ts +95 -0
- package/dist/turnProfiles.d.ts +2 -2
- package/dist/turnQuality.d.ts +94 -0
- package/dist/types.d.ts +277 -80
- package/dist/vapiAdapter.d.ts +160 -0
- package/dist/voiceMonitoring.d.ts +444 -0
- package/dist/vue/VoiceCallDebuggerLaunch.d.ts +68 -0
- package/dist/vue/VoiceDeliveryRuntime.d.ts +30 -0
- package/dist/vue/VoiceOpsActionCenter.d.ts +13 -0
- package/dist/vue/VoiceOpsStatus.d.ts +30 -0
- package/dist/vue/VoicePlatformCoverage.d.ts +23 -0
- package/dist/vue/VoiceProofTrends.d.ts +21 -0
- package/dist/vue/VoiceProviderCapabilities.d.ts +51 -0
- package/dist/vue/VoiceProviderContracts.d.ts +21 -0
- package/dist/vue/VoiceProviderSimulationControls.d.ts +88 -0
- package/dist/vue/VoiceProviderStatus.d.ts +51 -0
- package/dist/vue/VoiceReadinessFailures.d.ts +21 -0
- package/dist/vue/VoiceReconnectProfileEvidence.d.ts +21 -0
- package/dist/vue/VoiceRoutingStatus.d.ts +51 -0
- package/dist/vue/VoiceSessionObservability.d.ts +23 -0
- package/dist/vue/VoiceSessionSnapshot.d.ts +68 -0
- package/dist/vue/VoiceTurnLatency.d.ts +69 -0
- package/dist/vue/VoiceTurnQuality.d.ts +51 -0
- package/dist/vue/index.d.ts +42 -4
- package/dist/vue/index.js +10642 -135
- package/dist/vue/useVoiceAgentSquadStatus.d.ts +9 -0
- package/dist/vue/useVoiceCallDebugger.d.ts +10 -0
- package/dist/vue/useVoiceCampaignDialerProof.d.ts +11 -0
- package/dist/vue/useVoiceController.d.ts +4 -2
- package/dist/vue/useVoiceDeliveryRuntime.d.ts +13 -0
- package/dist/vue/useVoiceLiveOps.d.ts +9 -0
- package/dist/vue/useVoiceOpsActionCenter.d.ts +11 -0
- package/dist/vue/useVoiceOpsStatus.d.ts +9 -0
- package/dist/vue/useVoicePlatformCoverage.d.ts +9 -0
- package/dist/vue/useVoiceProfileComparison.d.ts +9 -0
- package/dist/vue/useVoiceProofTrends.d.ts +9 -0
- package/dist/vue/useVoiceProviderCapabilities.d.ts +9 -0
- package/dist/vue/useVoiceProviderContracts.d.ts +9 -0
- package/dist/vue/useVoiceProviderSimulationControls.d.ts +24 -0
- package/dist/vue/useVoiceProviderStatus.d.ts +3 -3
- package/dist/vue/useVoiceReadinessFailures.d.ts +959 -0
- package/dist/vue/useVoiceReconnectProfileEvidence.d.ts +9 -0
- package/dist/vue/useVoiceRoutingStatus.d.ts +8 -0
- package/dist/vue/useVoiceSessionObservability.d.ts +9 -0
- package/dist/vue/useVoiceSessionSnapshot.d.ts +10 -0
- package/dist/vue/useVoiceStream.d.ts +5 -2
- package/dist/vue/useVoiceTraceTimeline.d.ts +9 -0
- package/dist/vue/useVoiceTurnLatency.d.ts +10 -0
- package/dist/vue/useVoiceTurnQuality.d.ts +9 -0
- package/dist/vue/useVoiceWorkflowStatus.d.ts +3 -3
- package/dist/webhookVerification.d.ts +27 -0
- package/dist/workflowContract.d.ts +8 -8
- package/fixtures/manifest.json +356 -197
- package/package.json +265 -256
- package/dist/appKit.d.ts +0 -44
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Elysia } from "elysia";
|
|
2
|
+
import type { VoiceOpsStatusReport } from "./opsStatus";
|
|
3
|
+
import type { VoicePhoneAgentProductionSmokeReport } from "./phoneAgentProductionSmoke";
|
|
4
|
+
import type { VoicePhoneAgentSetupReport } from "./phoneAgent";
|
|
5
|
+
import type { VoiceProductionReadinessReport } from "./productionReadiness";
|
|
6
|
+
export type VoiceDemoReadyStatus = "fail" | "pass" | "warn";
|
|
7
|
+
export type VoiceDemoReadySection = {
|
|
8
|
+
description?: string;
|
|
9
|
+
href?: string;
|
|
10
|
+
label: string;
|
|
11
|
+
status: VoiceDemoReadyStatus;
|
|
12
|
+
value?: number | string;
|
|
13
|
+
};
|
|
14
|
+
export type VoiceDemoReadyReport = {
|
|
15
|
+
checkedAt: number;
|
|
16
|
+
sections: VoiceDemoReadySection[];
|
|
17
|
+
status: VoiceDemoReadyStatus;
|
|
18
|
+
summary: {
|
|
19
|
+
opsStatus?: Pick<VoiceOpsStatusReport, "failed" | "passed" | "status" | "total">;
|
|
20
|
+
phoneSetup?: {
|
|
21
|
+
carriers: number;
|
|
22
|
+
ready: boolean;
|
|
23
|
+
};
|
|
24
|
+
phoneSmoke?: {
|
|
25
|
+
issues: number;
|
|
26
|
+
pass: boolean;
|
|
27
|
+
provider?: string;
|
|
28
|
+
sessionId?: string;
|
|
29
|
+
};
|
|
30
|
+
productionReadiness?: {
|
|
31
|
+
checks: number;
|
|
32
|
+
status: VoiceProductionReadinessReport["status"];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
title: string;
|
|
36
|
+
};
|
|
37
|
+
type VoiceDemoReadyLoader<TValue> = TValue | ((input: {
|
|
38
|
+
query: Record<string, unknown>;
|
|
39
|
+
request: Request;
|
|
40
|
+
}) => Promise<TValue | undefined> | TValue | undefined);
|
|
41
|
+
export type VoiceDemoReadyRoutesOptions = {
|
|
42
|
+
opsStatus?: false | {
|
|
43
|
+
href?: string;
|
|
44
|
+
load: VoiceDemoReadyLoader<VoiceOpsStatusReport>;
|
|
45
|
+
};
|
|
46
|
+
headers?: HeadersInit;
|
|
47
|
+
htmlPath?: false | string;
|
|
48
|
+
name?: string;
|
|
49
|
+
path?: string;
|
|
50
|
+
phoneSetup?: false | {
|
|
51
|
+
href?: string;
|
|
52
|
+
load: VoiceDemoReadyLoader<VoicePhoneAgentSetupReport>;
|
|
53
|
+
};
|
|
54
|
+
phoneSmoke?: false | {
|
|
55
|
+
href?: string;
|
|
56
|
+
load: VoiceDemoReadyLoader<VoicePhoneAgentProductionSmokeReport>;
|
|
57
|
+
};
|
|
58
|
+
productionReadiness?: false | {
|
|
59
|
+
href?: string;
|
|
60
|
+
load: VoiceDemoReadyLoader<VoiceProductionReadinessReport>;
|
|
61
|
+
};
|
|
62
|
+
render?: (report: VoiceDemoReadyReport) => Promise<string> | string;
|
|
63
|
+
title?: string;
|
|
64
|
+
};
|
|
65
|
+
export declare const buildVoiceDemoReadyReport: (options: VoiceDemoReadyRoutesOptions, input?: {
|
|
66
|
+
query?: Record<string, unknown>;
|
|
67
|
+
request?: Request;
|
|
68
|
+
}) => Promise<VoiceDemoReadyReport>;
|
|
69
|
+
export declare const renderVoiceDemoReadyHTML: (report: VoiceDemoReadyReport) => string;
|
|
70
|
+
export declare const createVoiceDemoReadyRoutes: (options: VoiceDemoReadyRoutesOptions) => Elysia<"", {
|
|
71
|
+
decorator: {};
|
|
72
|
+
store: {};
|
|
73
|
+
derive: {};
|
|
74
|
+
resolve: {};
|
|
75
|
+
}, {
|
|
76
|
+
typebox: {};
|
|
77
|
+
error: {};
|
|
78
|
+
}, {
|
|
79
|
+
schema: {};
|
|
80
|
+
standaloneSchema: {};
|
|
81
|
+
macro: {};
|
|
82
|
+
macroFn: {};
|
|
83
|
+
parser: {};
|
|
84
|
+
response: {};
|
|
85
|
+
}, {}, {
|
|
86
|
+
derive: {};
|
|
87
|
+
resolve: {};
|
|
88
|
+
schema: {};
|
|
89
|
+
standaloneSchema: {};
|
|
90
|
+
response: {};
|
|
91
|
+
}, {
|
|
92
|
+
derive: {};
|
|
93
|
+
resolve: {};
|
|
94
|
+
schema: {};
|
|
95
|
+
standaloneSchema: {};
|
|
96
|
+
response: {};
|
|
97
|
+
}>;
|
|
98
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Elysia } from
|
|
2
|
-
import { evaluateVoiceTrace, type StoredVoiceTraceEvent, type VoiceTraceEventFilter, type VoiceTraceEventStore, type VoiceTraceRedactionConfig } from
|
|
1
|
+
import { Elysia } from "elysia";
|
|
2
|
+
import { evaluateVoiceTrace, type StoredVoiceTraceEvent, type VoiceTraceEventFilter, type VoiceTraceEventStore, type VoiceTraceRedactionConfig } from "./trace";
|
|
3
3
|
export type VoiceDiagnosticsRoutesOptions = {
|
|
4
4
|
evaluation?: Parameters<typeof evaluateVoiceTrace>[1];
|
|
5
5
|
headers?: HeadersInit;
|
package/dist/evalRoutes.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { Elysia } from
|
|
2
|
-
import { type VoiceQualityReport, type VoiceQualityThresholds } from
|
|
3
|
-
import { summarizeVoiceTrace, type StoredVoiceTraceEvent, type VoiceTraceEventStore } from
|
|
4
|
-
export type VoiceEvalStatus =
|
|
1
|
+
import { Elysia } from "elysia";
|
|
2
|
+
import { type VoiceQualityReport, type VoiceQualityThresholds } from "./qualityRoutes";
|
|
3
|
+
import { summarizeVoiceTrace, type StoredVoiceTraceEvent, type VoiceTraceEventStore } from "./trace";
|
|
4
|
+
export type VoiceEvalStatus = "pass" | "fail";
|
|
5
5
|
export type VoiceEvalSessionReport = {
|
|
6
6
|
endedAt?: number;
|
|
7
7
|
eventCount: number;
|
|
8
|
+
operationsRecordHref?: string;
|
|
8
9
|
quality: VoiceQualityReport;
|
|
9
10
|
scenarioId?: string;
|
|
10
11
|
sessionId: string;
|
|
@@ -81,6 +82,7 @@ export type VoiceScenarioEvalDefinition = {
|
|
|
81
82
|
export type VoiceScenarioEvalSessionResult = {
|
|
82
83
|
eventCount: number;
|
|
83
84
|
issues: string[];
|
|
85
|
+
operationsRecordHref?: string;
|
|
84
86
|
sessionId: string;
|
|
85
87
|
status: VoiceEvalStatus;
|
|
86
88
|
};
|
|
@@ -142,6 +144,7 @@ export type VoiceEvalRoutesOptions = {
|
|
|
142
144
|
links?: VoiceEvalLink[];
|
|
143
145
|
limit?: number;
|
|
144
146
|
name?: string;
|
|
147
|
+
operationsRecordHref?: false | string | ((sessionId: string) => string);
|
|
145
148
|
path?: string;
|
|
146
149
|
scenarios?: VoiceScenarioEvalDefinition[];
|
|
147
150
|
store?: VoiceTraceEventStore;
|
|
@@ -151,17 +154,20 @@ export type VoiceEvalRoutesOptions = {
|
|
|
151
154
|
export declare const runVoiceSessionEvals: (options?: {
|
|
152
155
|
events?: StoredVoiceTraceEvent[];
|
|
153
156
|
limit?: number;
|
|
157
|
+
operationsRecordHref?: false | string | ((sessionId: string) => string);
|
|
154
158
|
store?: VoiceTraceEventStore;
|
|
155
159
|
thresholds?: VoiceQualityThresholds;
|
|
156
160
|
}) => Promise<VoiceEvalReport>;
|
|
157
161
|
export declare const runVoiceScenarioEvals: (options?: {
|
|
158
162
|
events?: StoredVoiceTraceEvent[];
|
|
163
|
+
operationsRecordHref?: false | string | ((sessionId: string) => string);
|
|
159
164
|
scenarios?: VoiceScenarioEvalDefinition[];
|
|
160
165
|
store?: VoiceTraceEventStore;
|
|
161
166
|
}) => Promise<VoiceScenarioEvalReport>;
|
|
162
167
|
export declare const runVoiceScenarioFixtureEvals: (options?: {
|
|
163
168
|
fixtures?: VoiceScenarioFixture[];
|
|
164
169
|
fixtureStore?: VoiceScenarioFixtureStore;
|
|
170
|
+
operationsRecordHref?: false | string | ((sessionId: string) => string);
|
|
165
171
|
scenarios?: VoiceScenarioEvalDefinition[];
|
|
166
172
|
}) => Promise<VoiceScenarioFixtureEvalReport>;
|
|
167
173
|
export declare const compareVoiceEvalBaseline: (currentReport: VoiceEvalReport, baselineReport: VoiceEvalReport, options?: VoiceEvalBaselineComparisonOptions) => VoiceEvalBaselineComparison;
|
package/dist/fileStore.d.ts
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
4
|
-
import
|
|
5
|
-
import type {
|
|
1
|
+
import { type StoredVoiceAuditEvent, type VoiceAuditEventStore } from "./audit";
|
|
2
|
+
import type { VoiceAuditSinkDeliveryRecord, VoiceAuditSinkDeliveryStore } from "./auditSinks";
|
|
3
|
+
import type { VoiceCampaignStore } from "./campaign";
|
|
4
|
+
import { type VoiceAssistantMemoryRecord, type VoiceAssistantMemoryStore } from "./assistantMemory";
|
|
5
|
+
import type { StoredVoiceIncidentBundleArtifact, VoiceIncidentBundleStore } from "./incidentBundle";
|
|
6
|
+
import { type StoredVoiceTraceEvent, type VoiceTraceSinkDeliveryRecord, type VoiceTraceSinkDeliveryStore, type VoiceTraceEventStore } from "./trace";
|
|
7
|
+
import type { StoredVoiceIntegrationEvent, StoredVoiceExternalObjectMap, StoredVoiceOpsTask, VoiceExternalObjectMap, VoiceExternalObjectMapStore, VoiceIntegrationEvent, VoiceIntegrationEventStore, VoiceOpsTask, VoiceOpsTaskStore } from "./ops";
|
|
8
|
+
import type { StoredVoiceCallReviewArtifact, VoiceCallReviewArtifact, VoiceCallReviewStore } from "./testing/review";
|
|
9
|
+
import type { VoiceSessionRecord, VoiceSessionStore } from "./types";
|
|
10
|
+
import type { VoiceRecordingStore } from "./recordingStore";
|
|
6
11
|
export type VoiceFileStoreOptions = {
|
|
7
12
|
directory: string;
|
|
8
13
|
pretty?: boolean;
|
|
9
14
|
};
|
|
10
|
-
export type VoiceFileRuntimeStorage<TSession extends VoiceSessionRecord = VoiceSessionRecord, TReview extends StoredVoiceCallReviewArtifact = StoredVoiceCallReviewArtifact, TTask extends StoredVoiceOpsTask = StoredVoiceOpsTask, TEvent extends StoredVoiceIntegrationEvent = StoredVoiceIntegrationEvent, TMapping extends StoredVoiceExternalObjectMap = StoredVoiceExternalObjectMap, TTrace extends StoredVoiceTraceEvent = StoredVoiceTraceEvent, TTraceDelivery extends VoiceTraceSinkDeliveryRecord = VoiceTraceSinkDeliveryRecord, TMemory extends VoiceAssistantMemoryRecord = VoiceAssistantMemoryRecord> = {
|
|
15
|
+
export type VoiceFileRuntimeStorage<TSession extends VoiceSessionRecord = VoiceSessionRecord, TReview extends StoredVoiceCallReviewArtifact = StoredVoiceCallReviewArtifact, TTask extends StoredVoiceOpsTask = StoredVoiceOpsTask, TEvent extends StoredVoiceIntegrationEvent = StoredVoiceIntegrationEvent, TMapping extends StoredVoiceExternalObjectMap = StoredVoiceExternalObjectMap, TTrace extends StoredVoiceTraceEvent = StoredVoiceTraceEvent, TTraceDelivery extends VoiceTraceSinkDeliveryRecord = VoiceTraceSinkDeliveryRecord, TAudit extends StoredVoiceAuditEvent = StoredVoiceAuditEvent, TAuditDelivery extends VoiceAuditSinkDeliveryRecord = VoiceAuditSinkDeliveryRecord, TIncident extends StoredVoiceIncidentBundleArtifact = StoredVoiceIncidentBundleArtifact, TMemory extends VoiceAssistantMemoryRecord = VoiceAssistantMemoryRecord> = {
|
|
16
|
+
audit: VoiceAuditEventStore<TAudit>;
|
|
17
|
+
auditDeliveries: VoiceAuditSinkDeliveryStore<TAuditDelivery>;
|
|
18
|
+
campaigns: VoiceCampaignStore;
|
|
11
19
|
events: VoiceIntegrationEventStore<TEvent>;
|
|
12
20
|
externalObjects: VoiceExternalObjectMapStore<TMapping>;
|
|
21
|
+
incidentBundles: VoiceIncidentBundleStore<TIncident>;
|
|
13
22
|
memories: VoiceAssistantMemoryStore<TMemory>;
|
|
14
23
|
reviews: VoiceCallReviewStore<TReview>;
|
|
15
24
|
session: VoiceSessionStore<TSession>;
|
|
@@ -20,12 +29,16 @@ export type VoiceFileRuntimeStorage<TSession extends VoiceSessionRecord = VoiceS
|
|
|
20
29
|
export declare const createVoiceFileSessionStore: <TSession extends VoiceSessionRecord = VoiceSessionRecord>(options: VoiceFileStoreOptions) => VoiceSessionStore<TSession>;
|
|
21
30
|
export declare const createVoiceFileReviewStore: <TArtifact extends StoredVoiceCallReviewArtifact = StoredVoiceCallReviewArtifact>(options: VoiceFileStoreOptions) => VoiceCallReviewStore<TArtifact>;
|
|
22
31
|
export declare const createVoiceFileTaskStore: <TTask extends StoredVoiceOpsTask = StoredVoiceOpsTask>(options: VoiceFileStoreOptions) => VoiceOpsTaskStore<TTask>;
|
|
32
|
+
export declare const createVoiceFileCampaignStore: (options: VoiceFileStoreOptions) => VoiceCampaignStore;
|
|
23
33
|
export declare const createVoiceFileIntegrationEventStore: <TEvent extends StoredVoiceIntegrationEvent = StoredVoiceIntegrationEvent>(options: VoiceFileStoreOptions) => VoiceIntegrationEventStore<TEvent>;
|
|
24
34
|
export declare const createVoiceFileExternalObjectMapStore: <TMapping extends StoredVoiceExternalObjectMap = StoredVoiceExternalObjectMap>(options: VoiceFileStoreOptions) => VoiceExternalObjectMapStore<TMapping>;
|
|
25
35
|
export declare const createVoiceFileTraceEventStore: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(options: VoiceFileStoreOptions) => VoiceTraceEventStore<TEvent>;
|
|
26
36
|
export declare const createVoiceFileTraceSinkDeliveryStore: <TDelivery extends VoiceTraceSinkDeliveryRecord = VoiceTraceSinkDeliveryRecord>(options: VoiceFileStoreOptions) => VoiceTraceSinkDeliveryStore<TDelivery>;
|
|
37
|
+
export declare const createVoiceFileAuditEventStore: <TEvent extends StoredVoiceAuditEvent = StoredVoiceAuditEvent>(options: VoiceFileStoreOptions) => VoiceAuditEventStore<TEvent>;
|
|
38
|
+
export declare const createVoiceFileAuditSinkDeliveryStore: <TDelivery extends VoiceAuditSinkDeliveryRecord = VoiceAuditSinkDeliveryRecord>(options: VoiceFileStoreOptions) => VoiceAuditSinkDeliveryStore<TDelivery>;
|
|
27
39
|
export declare const createVoiceFileAssistantMemoryStore: <TRecord extends VoiceAssistantMemoryRecord = VoiceAssistantMemoryRecord>(options: VoiceFileStoreOptions) => VoiceAssistantMemoryStore<TRecord>;
|
|
28
|
-
export declare const
|
|
40
|
+
export declare const createVoiceFileIncidentBundleStore: <TArtifact extends StoredVoiceIncidentBundleArtifact = StoredVoiceIncidentBundleArtifact>(options: VoiceFileStoreOptions) => VoiceIncidentBundleStore<TArtifact>;
|
|
41
|
+
export declare const createVoiceFileRuntimeStorage: <TSession extends VoiceSessionRecord = VoiceSessionRecord, TReview extends StoredVoiceCallReviewArtifact = StoredVoiceCallReviewArtifact, TTask extends StoredVoiceOpsTask = StoredVoiceOpsTask, TEvent extends StoredVoiceIntegrationEvent = StoredVoiceIntegrationEvent, TMapping extends StoredVoiceExternalObjectMap = StoredVoiceExternalObjectMap, TTrace extends StoredVoiceTraceEvent = StoredVoiceTraceEvent, TTraceDelivery extends VoiceTraceSinkDeliveryRecord = VoiceTraceSinkDeliveryRecord, TAudit extends StoredVoiceAuditEvent = StoredVoiceAuditEvent, TAuditDelivery extends VoiceAuditSinkDeliveryRecord = VoiceAuditSinkDeliveryRecord, TIncident extends StoredVoiceIncidentBundleArtifact = StoredVoiceIncidentBundleArtifact, TMemory extends VoiceAssistantMemoryRecord = VoiceAssistantMemoryRecord>(options: VoiceFileStoreOptions) => VoiceFileRuntimeStorage<TSession, TReview, TTask, TEvent, TMapping, TTrace, TTraceDelivery, TAudit, TAuditDelivery, TIncident, TMemory>;
|
|
29
42
|
export declare const createStoredVoiceCallReviewArtifact: <TArtifact extends VoiceCallReviewArtifact = VoiceCallReviewArtifact>(id: string, artifact: TArtifact) => TArtifact & {
|
|
30
43
|
id: string;
|
|
31
44
|
};
|
|
@@ -38,3 +51,4 @@ export declare const createStoredVoiceIntegrationEvent: <TEvent extends Omit<Voi
|
|
|
38
51
|
export declare const createStoredVoiceExternalObjectMap: <TMapping extends Omit<VoiceExternalObjectMap, "id" | "createdAt" | "updatedAt"> = Omit<VoiceExternalObjectMap, "id" | "createdAt" | "updatedAt">>(mapping: TMapping & {
|
|
39
52
|
at?: number;
|
|
40
53
|
}) => VoiceExternalObjectMap;
|
|
54
|
+
export declare const createVoiceFileRecordingStore: (options: VoiceFileStoreOptions) => VoiceRecordingStore;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const HTMX_BOOTSTRAP_BUNDLE = "var Nn=(n)=>{if(typeof n!==\"string\")return n;return document.querySelector(n)},Hn=(n,e,o,c)=>{let i=e??n.getAttribute(\"hx-get\")??\"\";if(!i)return\"\";let s=new URL(i,window.location.origin);if(c)s.searchParams.set(o,c);else s.searchParams.delete(o);return`${s.pathname}${s.search}${s.hash}`},gn=(n,e)=>{if(typeof window>\"u\"||typeof document>\"u\")return()=>{};let o=Nn(e.element);if(!o)return()=>{};let c=e.eventName??\"voice-refresh\",i=e.sessionQueryParam??\"sessionId\",s=()=>{let r=window,g=Hn(o,e.route,i,n.sessionId);if(g)o.setAttribute(\"hx-get\",g);r.htmx?.process?.(o),r.htmx?.trigger?.(o,c)},t=n.subscribe(s);return s(),()=>{t()}};var Gn=(n)=>Math.max(-1,Math.min(1,n)),Bn=(n)=>{let e=new Int16Array(n.length);for(let o=0;o<n.length;o+=1){let c=Gn(n[o]??0);e[o]=c<0?c*32768:c*32767}return new Uint8Array(e.buffer)},Wn=(n)=>{let e=n instanceof Uint8Array?n:new Uint8Array(n);if(e.byteLength<2)return 0;let o=new Int16Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/2));if(o.length===0)return 0;let c=0;for(let i of o){let s=i/32768;c+=s*s}return Math.min(1,Math.max(0,Math.sqrt(c/o.length)*5.5))},$n=(n,e,o)=>{if(e===o)return n;let c=e/o,i=Math.round(n.length/c),s=new Float32Array(i),t=0,r=0;while(t<s.length){let g=Math.round((t+1)*c),y=0,d=0;for(let h=r;h<g&&h<n.length;h+=1)y+=n[h]??0,d+=1;s[t]=d>0?y/d:0,t+=1,r=g}return s},An=(n)=>{let e=null,o=null,c=null,i=null;return{start:async()=>{if(typeof navigator>\"u\"||!navigator.mediaDevices?.getUserMedia)throw Error(\"Browser microphone capture requires navigator.mediaDevices.getUserMedia.\");let r=(typeof window<\"u\"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!r)throw Error(\"Browser microphone capture requires AudioContext support.\");i=await navigator.mediaDevices.getUserMedia({audio:{channelCount:n.channelCount??1}}),e=new r,o=e.createMediaStreamSource(i),c=e.createScriptProcessor(4096,1,1),c.onaudioprocess=(g)=>{let y=g.inputBuffer.getChannelData(0),d=$n(y,e?.sampleRate??48000,n.sampleRateHz??16000),h=Bn(d);n.onLevel?.(Wn(h)),n.onAudio(h)},o.connect(c),c.connect(e.destination)},stop:()=>{c?.disconnect(),o?.disconnect(),i?.getTracks().forEach((r)=>r.stop()),e?.close(),n.onLevel?.(0),e=null,i=null,c=null,o=null}}};var nn=(n)=>{if(typeof n===\"string\"&&n.trim())return n;if(n instanceof Error&&n.message.trim())return n.message;if(n&&typeof n===\"object\"){let e=n;for(let o of[\"message\",\"reason\",\"description\"]){let c=e[o];if(typeof c===\"string\"&&c.trim())return c}if(\"error\"in e)return nn(e.error);if(\"cause\"in e)return nn(e.cause);try{return JSON.stringify(n)}catch{}}return\"Unexpected error\"},hn=(n)=>{switch(n.type){case\"audio\":return{chunk:Uint8Array.from(atob(n.chunkBase64),(e)=>e.charCodeAt(0)),format:n.format,receivedAt:n.receivedAt,turnId:n.turnId,type:\"audio\"};case\"assistant\":return{text:n.text,type:\"assistant\"};case\"complete\":return{sessionId:n.sessionId,type:\"complete\"};case\"connection\":return{reconnect:n.reconnect,type:\"connection\"};case\"call_lifecycle\":return{event:n.event,sessionId:n.sessionId,type:\"call_lifecycle\"};case\"error\":return{message:nn(n.message),type:\"error\"};case\"final\":return{transcript:n.transcript,type:\"final\"};case\"partial\":return{transcript:n.transcript,type:\"partial\"};case\"replay\":return{assistantTexts:n.assistantTexts,call:n.call,partial:n.partial,scenarioId:n.scenarioId,sessionId:n.sessionId,sessionMetadata:n.sessionMetadata,status:n.status,turns:n.turns,type:\"replay\"};case\"session\":return{sessionId:n.sessionId,sessionMetadata:n.sessionMetadata,scenarioId:n.scenarioId,status:n.status,type:\"session\"};case\"turn\":return{turn:n.turn,type:\"turn\"};default:return null}};var H=(n,e,o,c)=>{n.push({code:o,message:c,severity:e})};var qn=(n)=>n.length===0?void 0:n.reduce((e,o)=>e+o,0)/n.length,K=(n)=>n.length===0?void 0:Math.max(...n);var _=(n,e)=>{let o=n[e];return typeof o===\"number\"&&Number.isFinite(o)?o:void 0},Z=(n,e)=>{let o=n[e];return typeof o===\"boolean\"?o:void 0},O=(n,e)=>{let o=n[e];return typeof o===\"string\"?o:void 0},en=(n)=>String(n.id??O(n,\"ssrc\")??_(n,\"ssrc\")??O(n,\"trackIdentifier\")??O(n,\"mid\")??\"unknown\"),yn=(n)=>n===void 0?void 0:n*1000;var Xn=(n)=>{let e={};for(let[o,c]of Object.entries(n))if(c===null||typeof c===\"boolean\"||typeof c===\"number\"||typeof c===\"string\")e[o]=c;return e};var Cn=(n={})=>{let e=n.stats??[],o=[],c=e.filter((l)=>l.type===\"inbound-rtp\"&&O(l,\"kind\")!==\"video\"),i=e.filter((l)=>l.type===\"outbound-rtp\"&&O(l,\"kind\")!==\"video\"),s=e.filter((l)=>l.type===\"candidate-pair\"),t=e.filter((l)=>(l.type===\"track\"||l.type===\"media-source\")&&O(l,\"kind\")===\"audio\"),r=s.filter((l)=>Z(l,\"selected\")===!0||Z(l,\"nominated\")===!0||O(l,\"state\")===\"succeeded\").length,g=t.filter((l)=>O(l,\"readyState\")!==\"ended\"&&O(l,\"trackState\")!==\"ended\"&&Z(l,\"ended\")!==!0).length,y=t.filter((l)=>O(l,\"readyState\")===\"ended\"||O(l,\"trackState\")===\"ended\"||Z(l,\"ended\")===!0).length,d=c.reduce((l,S)=>l+(_(S,\"packetsReceived\")??0),0),h=i.reduce((l,S)=>l+(_(S,\"packetsSent\")??0),0),a=[...c,...i].reduce((l,S)=>l+Math.max(0,_(S,\"packetsLost\")??0),0),M=d+a,C=M===0?0:a/M,I=c.reduce((l,S)=>l+(_(S,\"bytesReceived\")??0),0),L=i.reduce((l,S)=>l+(_(S,\"bytesSent\")??0),0),b=K(s.map((l)=>yn(_(l,\"currentRoundTripTime\")??_(l,\"roundTripTime\"))).filter((l)=>l!==void 0)),w=K([...c,...i].map((l)=>yn(_(l,\"jitter\"))).filter((l)=>l!==void 0)),u=K(c.map((l)=>{let S=_(l,\"jitterBufferDelay\"),R=_(l,\"jitterBufferEmittedCount\");return S!==void 0&&R!==void 0&&R>0?S/R*1000:void 0}).filter((l)=>l!==void 0)),U=t.map((l)=>_(l,\"audioLevel\")).filter((l)=>l!==void 0);if(n.requireConnectedCandidatePair&&s.length>0&&r===0)H(o,\"error\",\"media.webrtc_candidate_pair_missing\",\"No active WebRTC candidate pair was observed.\");if(n.requireLiveAudioTrack&&g===0)H(o,\"error\",\"media.webrtc_audio_track_missing\",\"No live WebRTC audio track was observed.\");if(n.maxPacketLossRatio!==void 0&&C>n.maxPacketLossRatio)H(o,\"warning\",\"media.webrtc_packet_loss\",`Observed WebRTC packet loss ratio ${String(C)} above ${String(n.maxPacketLossRatio)}.`);if(n.maxRoundTripTimeMs!==void 0&&b!==void 0&&b>n.maxRoundTripTimeMs)H(o,\"warning\",\"media.webrtc_round_trip_time\",`Observed WebRTC RTT ${String(b)}ms above ${String(n.maxRoundTripTimeMs)}ms.`);if(n.maxJitterMs!==void 0&&w!==void 0&&w>n.maxJitterMs)H(o,\"warning\",\"media.webrtc_jitter\",`Observed WebRTC jitter ${String(w)}ms above ${String(n.maxJitterMs)}ms.`);return{activeCandidatePairs:r,audioLevelAverage:qn(U),bytesReceived:I,bytesSent:L,checkedAt:Date.now(),endedAudioTracks:y,inboundPackets:d,issues:o,jitterBufferDelayMs:u,jitterMs:w,liveAudioTracks:g,outboundPackets:h,packetLossRatio:C,packetsLost:a,roundTripTimeMs:b,status:o.some((l)=>l.severity===\"error\")?\"fail\":o.length>0?\"warn\":\"pass\",totalStats:e.length}},fn=async(n)=>{return[...(await n.peerConnection.getStats(n.selector??null)).values()].map(Xn)};var Tn=(n={})=>{let e=n.stats??[],o=n.previousStats??[],c=[],i=new Map(o.map((a)=>[en(a),a])),t=e.filter((a)=>(a.type===\"inbound-rtp\"||a.type===\"outbound-rtp\")&&O(a,\"kind\")!==\"video\"&&O(a,\"mediaType\")!==\"video\").map((a)=>{let M=a.type===\"outbound-rtp\"?\"outbound\":\"inbound\",C=M===\"outbound\"?\"packetsSent\":\"packetsReceived\",I=M===\"outbound\"?\"bytesSent\":\"bytesReceived\",L=i.get(en(a)),b=_(a,C),w=L?_(L,C):void 0,u=_(a,I),U=L?_(L,I):void 0,l=a.timestamp!==void 0&&L?.timestamp!==void 0?a.timestamp-L.timestamp:void 0;return{bytesDelta:u!==void 0&&U!==void 0?u-U:void 0,currentPackets:b,direction:M,id:en(a),packetDelta:b!==void 0&&w!==void 0?b-w:void 0,previousPackets:w,timeDeltaMs:l}}),r=t.filter((a)=>a.direction===\"inbound\"),g=t.filter((a)=>a.direction===\"outbound\"),y=K(t.map((a)=>a.timeDeltaMs).filter((a)=>a!==void 0)),d=r.filter((a)=>n.maxInboundPacketStallMs!==void 0&&a.timeDeltaMs!==void 0&&a.timeDeltaMs>=n.maxInboundPacketStallMs&&a.packetDelta!==void 0&&a.packetDelta<=0).length,h=g.filter((a)=>n.maxOutboundPacketStallMs!==void 0&&a.timeDeltaMs!==void 0&&a.timeDeltaMs>=n.maxOutboundPacketStallMs&&a.packetDelta!==void 0&&a.packetDelta<=0).length;if(n.requireInboundAudio&&r.length===0)H(c,\"error\",\"media.webrtc_inbound_audio_missing\",\"No inbound WebRTC audio RTP stream was observed.\");if(n.requireOutboundAudio&&g.length===0)H(c,\"error\",\"media.webrtc_outbound_audio_missing\",\"No outbound WebRTC audio RTP stream was observed.\");if(n.maxGapMs!==void 0&&y!==void 0&&y>n.maxGapMs)H(c,\"warning\",\"media.webrtc_stream_gap\",`Observed WebRTC stream sample gap ${String(y)}ms above ${String(n.maxGapMs)}ms.`);if(d>0)H(c,\"error\",\"media.webrtc_inbound_stalled\",`${String(d)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(h>0)H(c,\"error\",\"media.webrtc_outbound_stalled\",`${String(h)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:r.length,issues:c,maxObservedGapMs:y,outboundAudioStreams:g.length,stalledInboundStreams:d,stalledOutboundStreams:h,status:c.some((a)=>a.severity===\"error\")?\"fail\":c.length>0?\"warn\":\"pass\",streams:t,totalStats:e.length}};var zn=\"/api/voice/browser-media\",kn=5000,Yn=async(n)=>n.peerConnection??await n.getPeerConnection?.()??null,Jn=async(n,e)=>{let o=e.fetch??globalThis.fetch;if(!o)return;await o(e.path??zn,{body:JSON.stringify(n),headers:{\"Content-Type\":\"application/json\"},keepalive:!0,method:\"POST\"})},Sn=(n)=>{let e=null,o=[],c=async()=>{let t=await Yn(n);if(!t)return;let r=await fn({peerConnection:t}),g=Cn({...n,stats:r}),y=n.continuity===!1?void 0:Tn({...n.continuity,previousStats:o,stats:r}),d={at:Date.now(),continuity:y,report:g,scenarioId:n.getScenarioId?.()??null,sessionId:n.getSessionId?.()??null};return o=r,n.onReport?.(d),await Jn(d,n),d},i=()=>{c().catch((t)=>{n.onError?.(t)})},s=()=>{if(e)clearInterval(e),e=null};return{close:s,reportOnce:c,start:()=>{if(e)return;i(),e=setInterval(i,n.intervalMs??kn)},stop:s}};var B=()=>{},Qn=()=>B,Zn={callControl:B,close:B,endTurn:B,getReadyState:()=>3,getScenarioId:()=>\"\",getSessionId:()=>\"\",send:B,sendAudio:B,simulateDisconnect:B,start:()=>{},subscribe:Qn},Kn=()=>crypto.randomUUID(),jn=(n,e,o)=>{let{hostname:c,port:i,protocol:s}=window.location,t=s===\"https:\"?\"wss:\":\"ws:\",r=i?`:${i}`:\"\",g=new URL(`${t}//${c}${r}${n}`);if(g.searchParams.set(\"sessionId\",e),o)g.searchParams.set(\"scenarioId\",o);return g.toString()},mn=(n)=>{if(!n||typeof n!==\"object\"||!(\"type\"in n))return!1;switch(n.type){case\"audio\":case\"assistant\":case\"call_lifecycle\":case\"complete\":case\"connection\":case\"error\":case\"final\":case\"partial\":case\"pong\":case\"replay\":case\"session\":case\"turn\":return!0;default:return!1}},Fn=(n)=>{if(typeof n.data!==\"string\")return null;try{let e=JSON.parse(n.data);return mn(e)?e:null}catch{return null}},Mn=(n,e={})=>{if(typeof window>\"u\")return Zn;let o=new Set,c=e.reconnect!==!1,i=e.maxReconnectAttempts??10,s=e.pingInterval??30000,t={isConnected:!1,pendingMessages:[],scenarioId:e.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectTimeout:null,sessionId:e.sessionId??Kn(),ws:null},r=(l)=>{o.forEach((S)=>S(l))},g=()=>{if(t.pingInterval)clearInterval(t.pingInterval),t.pingInterval=null;if(t.reconnectTimeout)clearTimeout(t.reconnectTimeout),t.reconnectTimeout=null},y=()=>{if(t.ws?.readyState!==1)return;while(t.pendingMessages.length>0){let l=t.pendingMessages.shift();if(l!==void 0)t.ws.send(l)}},d=()=>{let l=Date.now()+500;t.reconnectAttempts+=1,r({reconnect:{attempts:t.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:i,nextAttemptAt:l,status:\"reconnecting\"},type:\"connection\"}),t.reconnectTimeout=setTimeout(()=>{if(t.reconnectAttempts>i){r({reconnect:{attempts:t.reconnectAttempts,maxAttempts:i,status:\"exhausted\"},type:\"connection\"});return}h()},500)},h=()=>{let l=new WebSocket(jn(n,t.sessionId,t.scenarioId));l.binaryType=\"arraybuffer\",l.onopen=()=>{let S=t.reconnectAttempts>0;if(t.isConnected=!0,y(),S)r({reconnect:{attempts:t.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:i,status:\"resumed\"},type:\"connection\"}),t.reconnectAttempts=0;o.forEach((R)=>R({scenarioId:t.scenarioId??void 0,sessionId:t.sessionId,status:\"active\",type:\"session\"})),t.pingInterval=setInterval(()=>{if(l.readyState===1)l.send(JSON.stringify({type:\"ping\"}))},s)},l.onmessage=(S)=>{let R=Fn(S);if(!R)return;if(R.type===\"session\")t.sessionId=R.sessionId,t.scenarioId=R.scenarioId??t.scenarioId;o.forEach((z)=>z(R))},l.onclose=(S)=>{if(t.isConnected=!1,g(),c&&S.code!==1000&&t.reconnectAttempts<i)d();else if(c&&S.code!==1000)r({reconnect:{attempts:t.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:i,status:\"exhausted\"},type:\"connection\"})},t.ws=l},a=(l)=>{if(t.ws?.readyState===1){t.ws.send(l);return}t.pendingMessages.push(l)},M=(l)=>{a(JSON.stringify(l))},C=(l={})=>{if(l.sessionId)t.sessionId=l.sessionId;if(l.scenarioId)t.scenarioId=l.scenarioId;M({type:\"start\",sessionId:t.sessionId,scenarioId:t.scenarioId??void 0})},I=(l)=>{a(l)},L=()=>{M({type:\"end_turn\"})},b=(l)=>{M({...l,type:\"call_control\"})},w=()=>{if(g(),t.ws)t.ws.close(1000),t.ws=null;t.isConnected=!1,o.clear()},u=()=>{if(t.ws?.readyState===1)t.ws.close(4000,\"absolutejs-voice-reconnect-proof\")},U=(l)=>{return o.add(l),()=>{o.delete(l)}};return h(),{callControl:b,close:w,endTurn:L,getReadyState:()=>t.ws?.readyState??3,getScenarioId:()=>t.scenarioId??\"\",getSessionId:()=>t.sessionId,send:M,sendAudio:I,simulateDisconnect:u,start:C,subscribe:U}};var vn=()=>({attempts:0,maxAttempts:0,status:\"idle\"}),pn=()=>({assistantAudio:[],assistantTexts:[],call:null,error:null,isConnected:!1,sessionMetadata:null,scenarioId:null,partial:\"\",reconnect:vn(),sessionId:null,status:\"idle\",turns:[]}),In=()=>{let n=pn(),e=new Set,o=()=>{e.forEach((i)=>i())};return{dispatch:(i)=>{switch(i.type){case\"audio\":n={...n,assistantAudio:[...n.assistantAudio,{chunk:i.chunk,format:i.format,receivedAt:i.receivedAt,turnId:i.turnId}]};break;case\"assistant\":n={...n,assistantTexts:[...n.assistantTexts,i.text]};break;case\"complete\":n={...n,sessionId:i.sessionId,status:\"completed\"};break;case\"call_lifecycle\":n={...n,call:{...n.call,disposition:i.event.type===\"end\"?i.event.disposition:n.call?.disposition,endedAt:i.event.type===\"end\"?i.event.at:n.call?.endedAt,events:[...n.call?.events??[],i.event],lastEventAt:i.event.at,startedAt:n.call?.startedAt??i.event.at},sessionId:i.sessionId};break;case\"connected\":n={...n,isConnected:!0,reconnect:n.reconnect.status===\"reconnecting\"?{...n.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:\"resumed\"}:n.reconnect};break;case\"connection\":n={...n,reconnect:i.reconnect};break;case\"disconnected\":n={...n,isConnected:!1};break;case\"error\":n={...n,error:i.message};break;case\"final\":n={...n,partial:i.transcript.text,turns:n.turns.map((s)=>s)};break;case\"partial\":n={...n,partial:i.transcript.text};break;case\"replay\":n={...n,assistantTexts:[...i.assistantTexts],call:i.call??null,error:null,isConnected:i.status===\"active\",partial:i.partial,reconnect:n.reconnect.status===\"reconnecting\"?{...n.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:\"resumed\"}:n.reconnect,scenarioId:i.scenarioId??n.scenarioId,sessionId:i.sessionId,sessionMetadata:i.sessionMetadata??n.sessionMetadata,status:i.status,turns:[...i.turns]};break;case\"session\":n={...n,error:null,scenarioId:i.scenarioId??n.scenarioId,isConnected:i.status===\"active\",sessionId:i.sessionId,sessionMetadata:i.sessionMetadata??n.sessionMetadata,status:i.status};break;case\"turn\":n={...n,partial:\"\",turns:[...n.turns,i.turn]};break}o()},getServerSnapshot:()=>n,getSnapshot:()=>n,subscribe:(i)=>{return e.add(i),()=>{e.delete(i)}}}};var Vn=(n,e={})=>{let o=Mn(n,e),c=In(),i=e.browserMedia&&typeof window<\"u\"?Sn({...e.browserMedia,getScenarioId:()=>e.browserMedia?e.browserMedia.getScenarioId?.()??o.getScenarioId():o.getScenarioId(),getSessionId:()=>e.browserMedia?e.browserMedia.getSessionId?.()??o.getSessionId():o.getSessionId()}):null,s=new Set,t=(d)=>Promise.resolve().then(()=>{if(!d?.sessionId&&!d?.scenarioId)return;o.start(d),i?.start()}),r=()=>{s.forEach((d)=>d())},g=()=>{if(!e.reconnectReportPath||typeof fetch>\"u\")return;let d=c.getSnapshot(),h=JSON.stringify({at:Date.now(),reconnect:d.reconnect,scenarioId:d.scenarioId,sessionId:o.getSessionId(),turnIds:d.turns.map((a)=>a.id)});fetch(e.reconnectReportPath,{body:h,headers:{\"Content-Type\":\"application/json\"},keepalive:!0,method:\"POST\"}).catch(()=>{})},y=o.subscribe((d)=>{let h=hn(d);if(h){if(c.dispatch(h),d.type===\"connection\")g();r()}});return{callControl(d){o.callControl(d)},close(){y(),i?.close(),o.close(),c.dispatch({type:\"disconnected\"}),r()},endTurn(){o.endTurn()},get error(){return c.getSnapshot().error},getServerSnapshot(){return c.getServerSnapshot()},getSnapshot(){return c.getSnapshot()},get isConnected(){return c.getSnapshot().isConnected},get scenarioId(){return c.getSnapshot().scenarioId},get sessionMetadata(){return c.getSnapshot().sessionMetadata},start:t,get partial(){return c.getSnapshot().partial},get reconnect(){return c.getSnapshot().reconnect},get sessionId(){return o.getSessionId()},get status(){return c.getSnapshot().status},get turns(){return c.getSnapshot().turns},get assistantTexts(){return c.getSnapshot().assistantTexts},get assistantAudio(){return c.getSnapshot().assistantAudio},get call(){return c.getSnapshot().call},sendAudio(d){o.sendAudio(d)},simulateDisconnect(){o.simulateDisconnect()},subscribe(d){return s.add(d),()=>{s.delete(d)}}}};var Ln=(n)=>{if(!n||n.enabled===!1)return;return{enabled:!0,maxGain:n.maxGain??3,noiseGateAttenuation:n.noiseGateAttenuation??0.15,noiseGateThreshold:n.noiseGateThreshold??0.006,targetLevel:n.targetLevel??0.08}};var ne={balanced:{qualityProfile:\"general\",silenceMs:1400,speechThreshold:0.012,transcriptStabilityMs:1000},fast:{qualityProfile:\"general\",silenceMs:700,speechThreshold:0.015,transcriptStabilityMs:450},\"long-form\":{qualityProfile:\"general\",silenceMs:2200,speechThreshold:0.01,transcriptStabilityMs:1500}},ee={general:{},\"accent-heavy\":{silenceMs:1200,speechThreshold:0.01,transcriptStabilityMs:1200},\"noisy-room\":{silenceMs:2000,speechThreshold:0.02,transcriptStabilityMs:1600},\"short-command\":{silenceMs:500,speechThreshold:0.016,transcriptStabilityMs:420}};var Rn=(n)=>{let e=n?.profile??\"fast\",o=n?.qualityProfile??\"general\",c=ne[e],i=ee[o];return{profile:e,qualityProfile:o,silenceMs:n?.silenceMs??i.silenceMs??c.silenceMs,speechThreshold:n?.speechThreshold??i.speechThreshold??c.speechThreshold,transcriptStabilityMs:n?.transcriptStabilityMs??i.transcriptStabilityMs??c.transcriptStabilityMs}};var ce={chat:{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:\"continuous\",turnDetection:{qualityProfile:\"short-command\",profile:\"balanced\"}},default:{capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:\"continuous\",turnDetection:{qualityProfile:\"general\",profile:\"fast\"}},dictation:{audioConditioning:{enabled:!0,maxGain:2.25,noiseGateAttenuation:0.05,noiseGateThreshold:0.003,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:\"continuous\",turnDetection:{qualityProfile:\"accent-heavy\",profile:\"long-form\"}},\"guided-intake\":{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:\"turn-scoped\",turnDetection:{qualityProfile:\"accent-heavy\",profile:\"long-form\"}},\"noisy-room\":{audioConditioning:{enabled:!0,maxGain:3,noiseGateAttenuation:0.12,noiseGateThreshold:0.006,targetLevel:0.085},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:\"continuous\",turnDetection:{qualityProfile:\"noisy-room\",profile:\"long-form\",silenceMs:2100,speechThreshold:0.02,transcriptStabilityMs:1650}},\"pstn-balanced\":{audioConditioning:{enabled:!0,maxGain:2.8,noiseGateAttenuation:0.07,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:\"continuous\",turnDetection:{qualityProfile:\"noisy-room\",profile:\"long-form\",silenceMs:660,speechThreshold:0.012,transcriptStabilityMs:300}},\"pstn-fast\":{audioConditioning:{enabled:!0,maxGain:2.75,noiseGateAttenuation:0.06,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:\"continuous\",turnDetection:{qualityProfile:\"noisy-room\",profile:\"long-form\",silenceMs:620,speechThreshold:0.012,transcriptStabilityMs:280}},reliability:{audioConditioning:{enabled:!0,maxGain:2.9,noiseGateAttenuation:0.08,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:\"continuous\",turnDetection:{qualityProfile:\"noisy-room\",profile:\"long-form\"}}},wn=(n=\"default\")=>{let e=ce[n];return{audioConditioning:Ln(e.audioConditioning),capture:{channelCount:e.capture?.channelCount??1,sampleRateHz:e.capture?.sampleRateHz??16000},connection:{...e.connection},name:n,sttLifecycle:e.sttLifecycle??\"continuous\",turnDetection:Rn(e.turnDetection)}};var oe=(n)=>({assistantAudio:[...n.assistantAudio],assistantTexts:[...n.assistantTexts],call:n.call,error:n.error,isConnected:n.isConnected,isRecording:!1,partial:n.partial,reconnect:n.reconnect,recordingError:null,sessionId:n.sessionId,sessionMetadata:n.sessionMetadata,scenarioId:n.scenarioId,status:n.status,turns:[...n.turns]}),j=(n,e={})=>{let o=wn(e.preset),c=Vn(n,{...o.connection,...e.connection}),i=null,s=oe(c),t=new Set,r=()=>{for(let C of t)C()},g=()=>{if(s={...s,assistantAudio:[...c.assistantAudio],assistantTexts:[...c.assistantTexts],call:c.call,error:c.error,isConnected:c.isConnected,partial:c.partial,reconnect:c.reconnect,sessionId:c.sessionId,sessionMetadata:c.sessionMetadata,scenarioId:c.scenarioId,status:c.status,turns:[...c.turns]},e.autoStopOnComplete!==!1&&s.status===\"completed\"&&s.isRecording)i?.stop(),i=null,s={...s,isRecording:!1};r()},y=c.subscribe(g);g();let d=()=>{if(i)return i;return i=An({channelCount:e.capture?.channelCount??o.capture.channelCount,onLevel:e.capture?.onLevel,onAudio:(C)=>{if(e.capture?.onAudio){e.capture.onAudio(C,c.sendAudio);return}c.sendAudio(C)},sampleRateHz:e.capture?.sampleRateHz??o.capture.sampleRateHz}),i},h=()=>{i?.stop(),i=null,s={...s,isRecording:!1},r()},a=async()=>{if(s.isRecording)return;try{s={...s,recordingError:null},r(),await d().start(),s={...s,isRecording:!0},r()}catch(C){throw i=null,s={...s,isRecording:!1,recordingError:C instanceof Error?C.message:String(C)},r(),C}};return{bindHTMX(C){return gn(c,C)},callControl:(C)=>c.callControl(C),close:()=>{y(),h(),c.close()},endTurn:()=>c.endTurn(),get error(){return s.error},getServerSnapshot:()=>s,getSnapshot:()=>s,get isConnected(){return s.isConnected},get isRecording(){return s.isRecording},get partial(){return s.partial},get recordingError(){return s.recordingError},get reconnect(){return s.reconnect},sendAudio:(C)=>c.sendAudio(C),simulateDisconnect:()=>c.simulateDisconnect(),get sessionId(){return s.sessionId},get sessionMetadata(){return s.sessionMetadata},get scenarioId(){return s.scenarioId},startRecording:a,get status(){return s.status},stopRecording:h,subscribe:(C)=>{return t.add(C),()=>{t.delete(C)}},toggleRecording:async()=>{if(s.isRecording){h();return}await a()},get turns(){return s.turns},get assistantTexts(){return s.assistantTexts},get assistantAudio(){return s.assistantAudio},get call(){return s.call}}};var te=()=>({activeSourceCount:0,error:null,isActive:!1,isPlaying:!1,lastInterruptLatencyMs:void 0,lastPlaybackStopLatencyMs:void 0,processedChunkCount:0,queuedChunkCount:0}),ie=()=>{if(typeof window>\"u\")return typeof AudioContext>\"u\"?void 0:AudioContext;return window.AudioContext??window.webkitAudioContext},se=(n,e)=>{let o=e.format;if(o.container!==\"raw\"||o.encoding!==\"pcm_s16le\")throw Error(`Unsupported assistant audio format: ${o.container}/${o.encoding}`);let c=e.chunk,i=Math.max(1,o.channels),s=Math.floor(c.byteLength/2),t=Math.max(1,Math.floor(s/i)),r=n.createBuffer(i,t,o.sampleRateHz),g=new DataView(c.buffer,c.byteOffset,c.byteLength);for(let y=0;y<i;y+=1){let d=r.getChannelData(y);for(let h=0;h<t;h+=1){let M=(h*i+y)*2;if(M+1>=c.byteLength){d[h]=0;continue}d[h]=g.getInt16(M,!0)/32768}}return r},m=(n,e={})=>{let o=new Set,c=new Set,i=(e.lookaheadMs??15)/1000,s=te(),t=null,r=null,g=0,y=Promise.resolve(),d=null,h=null,a=null,M=null,C=()=>{for(let A of o)A()},I=(A)=>{s={...s,...A},C()},L=()=>{if(s.error!==null)I({error:null})},b=()=>{if(M!==null)clearTimeout(M),M=null},w=(A)=>{b(),d=null,I({activeSourceCount:c.size,isPlaying:!1,lastInterruptLatencyMs:A,lastPlaybackStopLatencyMs:s.lastPlaybackStopLatencyMs??A}),a?.(),a=null,h=null},u=(A)=>{if(!A)return 0;return Math.max(0,((A.baseLatency??0)+(A.outputLatency??0))*1000)},U=(A)=>{if(!r)return;let f=1;if(r.gain.setValueAtTime){r.gain.setValueAtTime(f,A?.currentTime??0);return}r.gain.value=f},l=(A)=>{if(!r)return;let f=0;if(r.gain.setValueAtTime){r.gain.setValueAtTime(f,A?.currentTime??0);return}r.gain.value=f},S=()=>{if(d===null||c.size>0)return;w(Date.now()-d)},R=async()=>{if(t)return t;if(e.createAudioContext)t=e.createAudioContext();else{let A=ie();if(!A)throw Error(\"Assistant audio playback requires AudioContext support.\");t=new A}if(t.createGain)r=t.createGain(),r.connect?.(t.destination);return g=t.currentTime,t},z=async(A)=>{let f=await R(),P=se(f,A),V=f.createBufferSource();V.buffer=P,V.connect(r??f.destination),V.onended=()=>{c.delete(V),V.disconnect?.(),I({activeSourceCount:c.size,isPlaying:c.size>0&&s.isActive}),S()};let Y=Math.max(f.currentTime+i,g);g=Y+P.duration,c.add(V),I({activeSourceCount:c.size,isPlaying:!0}),V.start(Y)},E=(A)=>{for(let f of[...c])f.stop?.();if(g=t?t.currentTime:0,A?.forceClear){for(let f of c)f.disconnect?.();c.clear(),S()}},W=async()=>{if(!s.isActive)return;let A=n.assistantAudio.slice(s.processedChunkCount);if(A.length===0)return;try{L();for(let f of A)await z(f);I({processedChunkCount:n.assistantAudio.length,queuedChunkCount:s.queuedChunkCount+A.length})}catch(f){I({error:f instanceof Error?f.message:String(f)})}},D=()=>{return y=y.then(()=>W(),()=>W()),y},$=n.subscribe(()=>{if(e.autoStart&&!s.isActive&&n.assistantAudio.length>0){N.start();return}if(s.isActive)D()}),N={close:async()=>{if($(),E({forceClear:!0}),b(),a?.(),a=null,h=null,d=null,t&&t.state!==\"closed\")await t.close();t=null,r?.disconnect?.(),r=null,g=0,I({activeSourceCount:0,isActive:!1,isPlaying:!1})},get activeSourceCount(){return s.activeSourceCount},get error(){return s.error},getSnapshot:()=>s,get isActive(){return s.isActive},get isPlaying(){return s.isPlaying},interrupt:async()=>{let A=Date.now(),f=await R();d=A,l(f);let P=Date.now()-A+u(f);if(I({isActive:!1,isPlaying:c.size>0,lastPlaybackStopLatencyMs:P}),c.size===0){w(P);return}if(!h)h=new Promise((V)=>{a=V});b(),M=setTimeout(()=>{for(let V of c)V.disconnect?.();c.clear(),w(Date.now()-A)},250),E(),await h},get lastInterruptLatencyMs(){return s.lastInterruptLatencyMs},get lastPlaybackStopLatencyMs(){return s.lastPlaybackStopLatencyMs},pause:async()=>{if(!t){I({activeSourceCount:0,isActive:!1,isPlaying:!1});return}await t.suspend(),I({activeSourceCount:c.size,isActive:!1,isPlaying:!1})},get processedChunkCount(){return s.processedChunkCount},get queuedChunkCount(){return s.queuedChunkCount},start:async()=>{try{L();let A=await R();if(U(A),A.state===\"suspended\")await A.resume();I({activeSourceCount:c.size,isActive:!0,isPlaying:A.state===\"running\"}),await D()}catch(A){throw I({error:A instanceof Error?A.message:String(A),isActive:!1,isPlaying:!1}),A}},subscribe:(A)=>{return o.add(A),()=>{o.delete(A)}}};return N};var le=()=>`barge-in:${Date.now()}:${crypto.randomUUID?.()??Math.random().toString(36).slice(2)}`,re=(n,e)=>{let o=n.filter((t)=>t.status===\"stopped\"),c=o.map((t)=>t.latencyMs).filter((t)=>typeof t===\"number\"),i=o.filter((t)=>typeof t.latencyMs===\"number\"&&t.latencyMs>e).length,s=o.length-i;return{averageLatencyMs:c.length>0?Math.round(c.reduce((t,r)=>t+r,0)/c.length):void 0,events:[...n],failed:i,lastEvent:n.at(-1),passed:s,status:n.length===0?\"empty\":i>0?\"fail\":o.length===0?\"warn\":\"pass\",thresholdMs:e,total:o.length}},bn=(n={})=>{let e=new Set,o=n.thresholdMs??250,c=n.fetch??globalThis.fetch,i=[],s=()=>{for(let g of e)g()},t=(g)=>{if(!n.path||typeof c!==\"function\")return;c(n.path,{body:JSON.stringify(g),headers:{\"Content-Type\":\"application/json\"},method:\"POST\"}).catch(()=>{})},r=(g,y)=>{let d={at:Date.now(),id:le(),latencyMs:y.latencyMs,playbackStopLatencyMs:y.playbackStopLatencyMs,reason:y.reason,sessionId:y.sessionId,status:g,thresholdMs:o};return i.push(d),t(d),s(),d};return{getSnapshot:()=>re(i,o),recordRequested:(g)=>r(\"requested\",g),recordSkipped:(g)=>r(\"skipped\",g),recordStopped:(g)=>r(\"stopped\",g),subscribe:(g)=>{return e.add(g),()=>{e.delete(g)}}}};var ae=0.08,de=(n,e={})=>(e.enabled??!0)&&n>=(e.interruptThreshold??ae),cn=(n,e,o={})=>{let c=n.partial,i=(t)=>{if(!e.isPlaying||o.enabled===!1){o.monitor?.recordSkipped({reason:t,sessionId:n.sessionId});return}o.monitor?.recordRequested({reason:t,sessionId:n.sessionId}),e.interrupt().then(()=>{o.monitor?.recordStopped({latencyMs:e.lastInterruptLatencyMs,playbackStopLatencyMs:e.lastPlaybackStopLatencyMs,reason:t,sessionId:n.sessionId})})},s=n.subscribe(()=>{if(o.interruptOnPartial===!1){c=n.partial;return}if(!c&&n.partial)i(\"partial-transcript\");c=n.partial});return{close:()=>{s()},handleLevel:(t)=>{if(de(t,o))i(\"input-level\")},sendAudio:(t)=>{i(\"manual-audio\"),n.sendAudio(t)}}};var rn=48,ge=320,Ae=88,he=\"Guided test\",ye=\"General recording\",Ce=\"Pick a scenario to begin the demo.\",fe=\"I can walk you through a short guided voice test.\",Te=\"I can capture one freeform recording and confirm that it landed.\",Se=\"Choose a scenario to begin. Guided test asks follow-up prompts. General recording just captures what you say.\",Me=\"Click Start general recording to capture one freeform answer.\",Pn=\"Speak freely. When you pause, the recording will be captured.\",sn=\"Recording saved. Start again if you want another capture.\",Dn=\"Guided test complete. Review the saved summary below.\",On=\"All prompts are covered. You can stop the microphone or keep speaking for extra detail.\",Ie=\"Ready. Start guided test or general recording to begin.\",Ve=\"Live. Answer the prompt, then click Stop microphone when finished.\",_n=[\"Start with a quick introduction about who you are.\",\"Now describe what you are trying to do or test.\",\"Finish with any detail that feels blocked, risky, or unclear.\"],xn=(n,e,o)=>Math.min(o,Math.max(e,n)),X=(n)=>n.replaceAll(\"&\",\"&\").replaceAll(\"<\",\"<\").replaceAll(\">\",\">\").replaceAll('\"',\""\").replaceAll(\"'\",\"'\"),on=(n,e)=>{let o=n[e];if(typeof o===\"string\"&&o.trim())return o;return null},ln=(n)=>{if(typeof n===\"string\"&&n.trim())return n;if(n instanceof Error&&n.message.trim())return n.message;if(n&&typeof n===\"object\"){let e=n,o=on(e,\"message\")??on(e,\"reason\")??on(e,\"description\");if(o)return o;if(\"error\"in e)return ln(e.error);if(\"cause\"in e)return ln(e.cause);try{return JSON.stringify(n)}catch{}}return\"Unexpected error\"},Le=(n)=>{let e=[n.status];if(n.attempts>0||n.maxAttempts>0)e.push(`${n.attempts}/${n.maxAttempts} attempts`);if(n.nextAttemptAt){let o=Math.max(0,n.nextAttemptAt-Date.now());e.push(`retry in ${Math.ceil(o/100)/10}s`)}return e.join(\" \u00B7 \")},F=(n=rn)=>Array.from({length:n},()=>0),En=(n,e,o=rn)=>{let c=n.slice(-(o-1));c.push(xn(e,0,1));while(c.length<o)c.unshift(0);return c},Re=(n,e=ge,o=Ae)=>{let c=n.length>1?n:F(rn),i=e/(c.length-1),s=o/2,t=o*0.34;if(Math.max(...c,0)<=0.015)return`M 0 ${s} L ${e} ${s}`;let g=c.map((d,h)=>{let a=h*0.76,M=Math.sin(a)*0.78+Math.sin(a*0.41)*0.22,C=d*t,I=i*h,L=xn(s+M*C,8,o-8);return{x:I,y:L}});if(g.length===0)return`M 0 ${s} L ${e} ${s}`;let y=`M ${g[0]?.x??0} ${g[0]?.y??s}`;for(let d=1;d<g.length;d+=1){let h=g[d-1],a=g[d];if(!h||!a)continue;let M=(h.x+a.x)/2;y+=` Q ${M} ${h.y} ${a.x} ${a.y}`}return y},we=(n)=>{if(!n)return _n;try{let e=JSON.parse(n);if(Array.isArray(e)){let o=e.filter((c)=>typeof c===\"string\").map((c)=>c.trim()).filter(Boolean);if(o.length>0)return o}}catch{}return _n},tn=(n)=>{if(!n)return;let e=Number(n);return Number.isFinite(e)?e:void 0},be=(n,e,o)=>{if(!e)return null;let c=document.querySelector(e);return c instanceof o?c:null},x=(n,e,o,c)=>{let i=e?document.querySelector(e):null;if(i instanceof o)return i;let s=n.querySelector(`#${c}`);if(s instanceof o)return s;throw Error(`Voice HTMX bootstrap could not find the required element \"${c}\".`)},_e=(n)=>{if(!n.mode)return Ce;if(!n.hasStarted)return n.mode===\"guided\"?fe:Te;if(n.status===\"completed\")return n.mode===\"guided\"?Dn:sn;if(n.mode===\"general\")return Pn;return n.guidedPrompts[n.turnCount]??On},Ee=(n)=>{if(!n.mode)return Se;if(n.status===\"completed\")return n.mode===\"guided\"?Dn:sn;if(!n.hasStarted)return n.mode===\"guided\"?`Click Start guided test to begin. First prompt: ${n.guidedPrompts[0]??\"Answer the first prompt.\"}`:Me;if(n.mode===\"general\")return n.turnCount===0?Pn:sn;return n.guidedPrompts[n.turnCount]??On},Pe=(n)=>{let e=n.dataset.voiceGuidedPath,o=n.dataset.voiceGeneralPath;if(!e||!o)throw Error(\"Voice HTMX bootstrap requires data-voice-guided-path and data-voice-general-path.\");let c=we(n.dataset.voiceGuidedPrompts),i=n.dataset.voiceGuidedLabel??he,s=n.dataset.voiceGeneralLabel??ye,t=n.dataset.voiceReconnectReportPath,r=n.dataset.voiceBargeInPath,g=r?bn({path:r,thresholdMs:tn(n.dataset.voiceBargeInThresholdMs)}):null,y=tn(n.dataset.voiceBargeInRecentWindowMs)??4000,d=tn(n.dataset.voiceBargeInSpeechThreshold)??0.04,h=x(document,n.dataset.voiceSync,HTMLElement,\"voice-htmx-sync\"),a=x(n,n.dataset.voiceConnection,HTMLElement,\"metric-connection\"),M=x(n,n.dataset.voiceError,HTMLElement,\"status-error\"),C=x(n,n.dataset.voiceMicrophone,HTMLElement,\"status-mic\"),I=x(n,n.dataset.voicePrompt,HTMLElement,\"status-prompt\"),L=be(n,n.dataset.voiceReconnect,HTMLElement),b=x(n,n.dataset.voiceChat,HTMLElement,\"chat-list\"),w=x(n,n.dataset.voiceStartGuided,HTMLButtonElement,\"start-guided\"),u=x(n,n.dataset.voiceStartGeneral,HTMLButtonElement,\"start-general\"),U=x(n,n.dataset.voiceStop,HTMLButtonElement,\"stop-mic\"),l=x(n,n.dataset.voiceMonitor,HTMLElement,\"voice-monitor\"),S=x(n,n.dataset.voiceMonitorCopy,HTMLElement,\"voice-monitor-copy\"),R=x(n,n.dataset.voiceWaveGlow,SVGPathElement,\"voice-wave-glow\"),z=x(n,n.dataset.voiceWavePath,SVGPathElement,\"voice-wave-path\"),E=null,W={general:!1,guided:!1},D=!1,$=null,N=F(),A=null,f=null,P=j(e,{capture:{onAudio:(T,G)=>{if(A){A.sendAudio(T);return}G(T)},onLevel:(T)=>{A?.handleLevel(T),N=En(N,T),v()}},connection:{reconnectReportPath:t},preset:\"guided-intake\"}),V=j(o,{capture:{onAudio:(T,G)=>{if(f){f.sendAudio(T);return}G(T)},onLevel:(T)=>{f?.handleLevel(T),N=En(N,T),v()}},connection:{reconnectReportPath:t},preset:\"dictation\"}),Y=P.bindHTMX({element:h}),un=V.bindHTMX({element:h}),J=m(P),Q=m(V);A=cn(P,J,{interruptThreshold:d,monitor:g??void 0}),f=cn(V,Q,{interruptThreshold:d,monitor:g??void 0});let k=()=>E===\"general\"?V:P,Oe=()=>E===\"general\"?Q:J,v=()=>{let T=Re(N);R.setAttribute(\"d\",T),z.setAttribute(\"d\",T),S.innerHTML=`<span class=\"voice-live-dot\"></span>${D?\"Microphone live\":\"Microphone idle\"}`,S.classList.toggle(\"is-live\",D),l.classList.toggle(\"is-live\",D)},q=()=>{let T=k(),G=(E?W[E]:!1)||T.turns.length>0,dn=T.status;if(a.textContent=T.isConnected?\"Connected\":\"Waiting\",M.textContent=$||T.error||\"None\",L)L.textContent=Le(T.reconnect);C.textContent=D?Ve:Ie,I.textContent=Ee({guidedPrompts:c,hasStarted:G,mode:E,status:dn,turnCount:T.turns.length}),w.hidden=D,u.hidden=D,U.hidden=!D,b.innerHTML=`<article class=\"voice-chat-message assistant\">\n <div class=\"voice-chat-role\">${X(E===\"general\"?s:E===\"guided\"?i:\"Voice demo\")}</div>\n <p class=\"voice-turn-text\">${X(_e({generalLabel:s,guidedLabel:i,guidedPrompts:c,hasStarted:G,mode:E,status:dn,turnCount:T.turns.length}))}</p>\n</article>${T.turns.map((p)=>`<div class=\"voice-chat-stack\">\n <article class=\"voice-chat-message user\">\n <div class=\"voice-chat-role\">You</div>\n <p class=\"voice-turn-text\">${X(p.text)}</p>\n </article>\n ${p.assistantText?`<article class=\"voice-chat-message assistant\">\n <div class=\"voice-chat-role\">${X(E===\"general\"?s:E===\"guided\"?i:\"Guide\")}</div>\n <p class=\"voice-turn-text\">${X(p.assistantText)}</p>\n </article>`:\"\"}\n</div>`).join(\"\")}${T.partial?`<article class=\"voice-chat-message user pending\">\n <div class=\"voice-chat-role\">Speaking</div>\n <p class=\"voice-turn-text\">${X(T.partial)}</p>\n</article>`:\"\"}`,v()},Un=()=>{k().stopRecording(),D=!1,$=null,N=F(),q()},an=async(T)=>{E=T,W={...W,[T]:!0};try{await k().startRecording(),$=null,D=!0,q()}catch(G){k().stopRecording(),D=!1,N=F(),$=ln(G),q()}};P.subscribe(()=>{if(P.assistantAudio.length>0)J.start().catch(()=>{});q()}),V.subscribe(()=>{if(V.assistantAudio.length>0)Q.start().catch(()=>{});q()}),w.addEventListener(\"click\",()=>{an(\"guided\")}),u.addEventListener(\"click\",()=>{an(\"general\")}),U.addEventListener(\"click\",()=>{Un()}),n.addEventListener(\"absolute-voice-simulate-disconnect\",()=>{k().simulateDisconnect()}),window.addEventListener(\"beforeunload\",()=>{P.stopRecording(),V.stopRecording(),A?.close(),f?.close(),J.close(),Q.close(),Y(),un(),P.close(),V.close()}),q()},De=()=>{if(typeof window>\"u\"||typeof document>\"u\")return;let n=Array.from(document.querySelectorAll(\"[data-voice-htmx]\"));for(let e of n)if(e instanceof HTMLElement)Pe(e)};De();export{De as initVoiceHTMX};\n";
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Elysia } from "elysia";
|
|
2
|
+
import type { VoiceAgentTool } from "./agent";
|
|
3
|
+
import type { VoiceTraceEventStore } from "./trace";
|
|
4
|
+
import type { VoiceOnTurnObjectHandler, VoiceRouteResult, VoiceSessionRecord } from "./types";
|
|
5
|
+
import type { VoiceAssistantGuardrails } from "./assistant";
|
|
6
|
+
export type VoiceGuardrailStage = "assistant-output" | "handoff" | "model-input" | "tool-input" | "tool-output" | "transcript";
|
|
7
|
+
export type VoiceGuardrailSeverity = "block" | "warn";
|
|
8
|
+
export type VoiceGuardrailStatus = "blocked" | "pass" | "warn";
|
|
9
|
+
export type VoiceGuardrailRule = {
|
|
10
|
+
action?: VoiceGuardrailSeverity;
|
|
11
|
+
description?: string;
|
|
12
|
+
id: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
match: RegExp | string | ((input: VoiceGuardrailEvaluationInput) => boolean | Promise<boolean>);
|
|
15
|
+
redactWith?: string;
|
|
16
|
+
stages?: VoiceGuardrailStage[];
|
|
17
|
+
};
|
|
18
|
+
export type VoiceGuardrailEvaluationInput = {
|
|
19
|
+
content?: unknown;
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
stage: VoiceGuardrailStage;
|
|
23
|
+
turnId?: string;
|
|
24
|
+
};
|
|
25
|
+
export type VoiceGuardrailFinding = {
|
|
26
|
+
action: VoiceGuardrailSeverity;
|
|
27
|
+
description?: string;
|
|
28
|
+
label: string;
|
|
29
|
+
ruleId: string;
|
|
30
|
+
stage: VoiceGuardrailStage;
|
|
31
|
+
};
|
|
32
|
+
export type VoiceGuardrailDecision = {
|
|
33
|
+
allowed: boolean;
|
|
34
|
+
checkedAt: number;
|
|
35
|
+
content?: unknown;
|
|
36
|
+
findings: VoiceGuardrailFinding[];
|
|
37
|
+
redactedContent?: unknown;
|
|
38
|
+
sessionId?: string;
|
|
39
|
+
stage: VoiceGuardrailStage;
|
|
40
|
+
status: VoiceGuardrailStatus;
|
|
41
|
+
turnId?: string;
|
|
42
|
+
};
|
|
43
|
+
export type VoiceGuardrailPolicy = {
|
|
44
|
+
defaultAction?: VoiceGuardrailSeverity;
|
|
45
|
+
id: string;
|
|
46
|
+
label?: string;
|
|
47
|
+
rules: VoiceGuardrailRule[];
|
|
48
|
+
};
|
|
49
|
+
export type VoiceGuardrailReport = {
|
|
50
|
+
checkedAt: number;
|
|
51
|
+
decisions: VoiceGuardrailDecision[];
|
|
52
|
+
failed: number;
|
|
53
|
+
policies: Array<{
|
|
54
|
+
id: string;
|
|
55
|
+
label?: string;
|
|
56
|
+
rules: number;
|
|
57
|
+
}>;
|
|
58
|
+
status: "fail" | "pass" | "warn";
|
|
59
|
+
summary: {
|
|
60
|
+
blocked: number;
|
|
61
|
+
passed: number;
|
|
62
|
+
warned: number;
|
|
63
|
+
};
|
|
64
|
+
total: number;
|
|
65
|
+
};
|
|
66
|
+
export type VoiceGuardrailRoutesOptions = {
|
|
67
|
+
headers?: HeadersInit;
|
|
68
|
+
name?: string;
|
|
69
|
+
path?: string;
|
|
70
|
+
policies?: VoiceGuardrailPolicy[];
|
|
71
|
+
source?: ((input: VoiceGuardrailEvaluationInput) => Promise<VoiceGuardrailDecision | VoiceGuardrailReport> | VoiceGuardrailDecision | VoiceGuardrailReport) | VoiceGuardrailDecision | VoiceGuardrailReport;
|
|
72
|
+
trace?: VoiceTraceEventStore;
|
|
73
|
+
};
|
|
74
|
+
export type VoiceGuardrailRuntimeBlockInput<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = Parameters<VoiceOnTurnObjectHandler<TContext, TSession, TResult>>[0] & {
|
|
75
|
+
decision: VoiceGuardrailDecision;
|
|
76
|
+
stage: VoiceGuardrailStage;
|
|
77
|
+
};
|
|
78
|
+
export type VoiceGuardrailRuntimeOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
79
|
+
blockResult?: (input: VoiceGuardrailRuntimeBlockInput<TContext, TSession, TResult>) => Promise<VoiceRouteResult<TResult>> | VoiceRouteResult<TResult>;
|
|
80
|
+
name?: string;
|
|
81
|
+
policies: VoiceGuardrailPolicy[];
|
|
82
|
+
trace?: VoiceTraceEventStore;
|
|
83
|
+
};
|
|
84
|
+
export type VoiceGuardrailRuntime<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
85
|
+
assistantGuardrails: VoiceAssistantGuardrails<TContext, TSession, TResult>;
|
|
86
|
+
evaluate: (input: VoiceGuardrailEvaluationInput) => Promise<VoiceGuardrailDecision>;
|
|
87
|
+
wrapTool: <TArgs extends Record<string, unknown>, TToolResult>(tool: VoiceAgentTool<TContext, TSession, TArgs, TToolResult, TResult>) => VoiceAgentTool<TContext, TSession, TArgs, TToolResult, TResult>;
|
|
88
|
+
wrapTools: (tools: Array<VoiceAgentTool<TContext, TSession, Record<string, unknown>, unknown, TResult>>) => Array<VoiceAgentTool<TContext, TSession, Record<string, unknown>, unknown, TResult>>;
|
|
89
|
+
};
|
|
90
|
+
export declare const evaluateVoiceGuardrailPolicy: (policy: VoiceGuardrailPolicy, input: VoiceGuardrailEvaluationInput) => Promise<VoiceGuardrailDecision>;
|
|
91
|
+
export declare const buildVoiceGuardrailReport: (input?: {
|
|
92
|
+
decisions: VoiceGuardrailDecision[];
|
|
93
|
+
policies?: VoiceGuardrailPolicy[];
|
|
94
|
+
}) => VoiceGuardrailReport;
|
|
95
|
+
export declare const createVoiceGuardrailPolicy: (policy: VoiceGuardrailPolicy) => VoiceGuardrailPolicy;
|
|
96
|
+
export declare const createVoiceGuardrailRuntime: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoiceGuardrailRuntimeOptions<TContext, TSession, TResult>) => VoiceGuardrailRuntime<TContext, TSession, TResult>;
|
|
97
|
+
export declare const voiceGuardrailPolicyPresets: {
|
|
98
|
+
supportSafeDefaults: VoiceGuardrailPolicy;
|
|
99
|
+
};
|
|
100
|
+
export declare const renderVoiceGuardrailMarkdown: (report: VoiceGuardrailReport) => string;
|
|
101
|
+
export declare const createVoiceGuardrailRoutes: (options?: VoiceGuardrailRoutesOptions) => Elysia<"", {
|
|
102
|
+
decorator: {};
|
|
103
|
+
store: {};
|
|
104
|
+
derive: {};
|
|
105
|
+
resolve: {};
|
|
106
|
+
}, {
|
|
107
|
+
typebox: {};
|
|
108
|
+
error: {};
|
|
109
|
+
}, {
|
|
110
|
+
schema: {};
|
|
111
|
+
standaloneSchema: {};
|
|
112
|
+
macro: {};
|
|
113
|
+
macroFn: {};
|
|
114
|
+
parser: {};
|
|
115
|
+
response: {};
|
|
116
|
+
}, {}, {
|
|
117
|
+
derive: {};
|
|
118
|
+
resolve: {};
|
|
119
|
+
schema: {};
|
|
120
|
+
standaloneSchema: {};
|
|
121
|
+
response: {};
|
|
122
|
+
}, {
|
|
123
|
+
derive: {};
|
|
124
|
+
resolve: {};
|
|
125
|
+
schema: {};
|
|
126
|
+
standaloneSchema: {};
|
|
127
|
+
response: {};
|
|
128
|
+
}>;
|
package/dist/handoff.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VoiceHandoffAction, VoiceHandoffAdapter, VoiceHandoffConfig, VoiceHandoffDeliveryStore, VoiceHandoffInput, VoiceHandoffResult, VoiceSessionRecord, StoredVoiceHandoffDelivery } from
|
|
1
|
+
import type { VoiceHandoffAction, VoiceHandoffAdapter, VoiceHandoffConfig, VoiceHandoffDeliveryStore, VoiceHandoffInput, VoiceHandoffResult, VoiceSessionRecord, StoredVoiceHandoffDelivery } from "./types";
|
|
2
2
|
type MaybePromise<T> = T | Promise<T>;
|
|
3
3
|
export type VoiceHandoffDelivery = VoiceHandoffResult & {
|
|
4
4
|
adapterId: string;
|
|
@@ -8,16 +8,16 @@ export type VoiceHandoffDeliveryRecord<TContext = unknown, TSession extends Voic
|
|
|
8
8
|
export type VoiceHandoffFanoutResult = {
|
|
9
9
|
action: VoiceHandoffAction;
|
|
10
10
|
deliveries: Record<string, VoiceHandoffDelivery>;
|
|
11
|
-
status: VoiceHandoffResult[
|
|
11
|
+
status: VoiceHandoffResult["status"];
|
|
12
12
|
};
|
|
13
|
-
export type VoiceHandoffDeliveryRecordInput<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = Omit<VoiceHandoffInput<TContext, TSession, TResult>,
|
|
13
|
+
export type VoiceHandoffDeliveryRecordInput<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = Omit<VoiceHandoffInput<TContext, TSession, TResult>, "api"> & {
|
|
14
14
|
id?: string;
|
|
15
15
|
};
|
|
16
16
|
export type VoiceQueuedHandoffDeliveryOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
17
17
|
adapters: VoiceHandoffAdapter<TContext, TSession, TResult>[];
|
|
18
|
-
api: VoiceHandoffInput<TContext, TSession, TResult>[
|
|
18
|
+
api: VoiceHandoffInput<TContext, TSession, TResult>["api"];
|
|
19
19
|
delivery: VoiceHandoffDeliveryRecord<TContext, TSession, TResult>;
|
|
20
|
-
failMode?: VoiceHandoffConfig<TContext, TSession, TResult>[
|
|
20
|
+
failMode?: VoiceHandoffConfig<TContext, TSession, TResult>["failMode"];
|
|
21
21
|
};
|
|
22
22
|
export type VoiceWebhookHandoffAdapterOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
23
23
|
actions?: VoiceHandoffAction[];
|
|
@@ -26,7 +26,7 @@ export type VoiceWebhookHandoffAdapterOptions<TContext = unknown, TSession exten
|
|
|
26
26
|
headers?: Record<string, string>;
|
|
27
27
|
id: string;
|
|
28
28
|
kind?: string;
|
|
29
|
-
method?:
|
|
29
|
+
method?: "POST" | "PUT" | "PATCH";
|
|
30
30
|
signingSecret?: string;
|
|
31
31
|
timeoutMs?: number;
|
|
32
32
|
url: string;
|
package/dist/handoffHealth.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Elysia } from
|
|
2
|
-
import type { StoredVoiceTraceEvent, VoiceTraceEventStore } from
|
|
3
|
-
export type VoiceHandoffHealthStatus =
|
|
1
|
+
import { Elysia } from "elysia";
|
|
2
|
+
import type { StoredVoiceTraceEvent, VoiceTraceEventStore } from "./trace";
|
|
3
|
+
export type VoiceHandoffHealthStatus = "delivered" | "failed" | "skipped";
|
|
4
4
|
export type VoiceHandoffHealthDelivery = {
|
|
5
5
|
adapterId: string;
|
|
6
6
|
adapterKind?: string;
|
|
@@ -31,8 +31,8 @@ export type VoiceHandoffHealthSummaryOptions = {
|
|
|
31
31
|
events?: StoredVoiceTraceEvent[];
|
|
32
32
|
limit?: number;
|
|
33
33
|
q?: string;
|
|
34
|
-
replayHref?: false | string | ((event: Omit<VoiceHandoffHealthEvent,
|
|
35
|
-
status?: VoiceHandoffHealthStatus |
|
|
34
|
+
replayHref?: false | string | ((event: Omit<VoiceHandoffHealthEvent, "replayHref">) => string);
|
|
35
|
+
status?: VoiceHandoffHealthStatus | "all";
|
|
36
36
|
store?: VoiceTraceEventStore;
|
|
37
37
|
};
|
|
38
38
|
export type VoiceHandoffHealthHTMLHandlerOptions = VoiceHandoffHealthSummaryOptions & {
|
package/dist/htmx.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VoiceHTMXConfig, VoiceHTMXRenderConfig, VoiceHTMXRenderInput, VoiceHTMXTargets, VoiceSessionRecord } from
|
|
1
|
+
import type { VoiceHTMXConfig, VoiceHTMXRenderConfig, VoiceHTMXRenderInput, VoiceHTMXTargets, VoiceSessionRecord } from "./types";
|
|
2
2
|
type ResolvedVoiceHTMXRenderConfig<TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = Required<VoiceHTMXRenderConfig<TSession, TResult>>;
|
|
3
3
|
export declare const resolveVoiceHTMXTargets: (custom?: Partial<VoiceHTMXTargets>) => VoiceHTMXTargets;
|
|
4
4
|
export declare const resolveVoiceHTMXRenderers: <TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(custom?: VoiceHTMXConfig<TSession, TResult>) => ResolvedVoiceHTMXRenderConfig<TSession, TResult>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Elysia } from "elysia";
|
|
2
|
+
import { type VoiceOperationsRecord, type VoiceOperationsRecordOptions } from "./operationsRecord";
|
|
3
|
+
import type { VoiceIncidentRecoveryOutcomeReport } from "./incidentTimeline";
|
|
4
|
+
import { type VoiceTraceRedactionConfig } from "./trace";
|
|
5
|
+
export type VoiceIncidentBundleFormat = "json" | "markdown";
|
|
6
|
+
export type VoiceIncidentBundle = {
|
|
7
|
+
auditMarkdown?: string;
|
|
8
|
+
exportedAt: number;
|
|
9
|
+
formatVersion: 1;
|
|
10
|
+
markdown: string;
|
|
11
|
+
record: VoiceOperationsRecord;
|
|
12
|
+
recoveryOutcomes?: VoiceIncidentRecoveryOutcomeReport;
|
|
13
|
+
redacted: boolean;
|
|
14
|
+
sessionId: string;
|
|
15
|
+
summary: VoiceIncidentBundleSummary;
|
|
16
|
+
traceMarkdown: string;
|
|
17
|
+
};
|
|
18
|
+
export type StoredVoiceIncidentBundleArtifact = {
|
|
19
|
+
bundle: VoiceIncidentBundle;
|
|
20
|
+
createdAt: number;
|
|
21
|
+
expiresAt?: number;
|
|
22
|
+
id: string;
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
redacted: boolean;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
};
|
|
27
|
+
export type VoiceIncidentBundleStoreFilter = {
|
|
28
|
+
expiredAt?: number;
|
|
29
|
+
sessionId?: string;
|
|
30
|
+
};
|
|
31
|
+
export type VoiceIncidentBundleStore<TArtifact extends StoredVoiceIncidentBundleArtifact = StoredVoiceIncidentBundleArtifact> = {
|
|
32
|
+
get: (id: string) => Promise<TArtifact | undefined> | TArtifact | undefined;
|
|
33
|
+
list: (filter?: VoiceIncidentBundleStoreFilter) => Promise<TArtifact[]> | TArtifact[];
|
|
34
|
+
remove: (id: string) => Promise<void> | void;
|
|
35
|
+
set: (id: string, artifact: TArtifact) => Promise<void> | void;
|
|
36
|
+
};
|
|
37
|
+
export type VoiceIncidentBundleSummary = {
|
|
38
|
+
auditEvents: number;
|
|
39
|
+
durationMs?: number;
|
|
40
|
+
errors: number;
|
|
41
|
+
handoffs: number;
|
|
42
|
+
providers: string[];
|
|
43
|
+
sessionId: string;
|
|
44
|
+
status: VoiceOperationsRecord["status"];
|
|
45
|
+
tools: number;
|
|
46
|
+
traceEvents: number;
|
|
47
|
+
turns: number;
|
|
48
|
+
};
|
|
49
|
+
export type VoiceIncidentBundleOptions = VoiceOperationsRecordOptions & {
|
|
50
|
+
redact?: VoiceTraceRedactionConfig;
|
|
51
|
+
recoveryOutcomes?: VoiceIncidentRecoveryOutcomeReport;
|
|
52
|
+
title?: string;
|
|
53
|
+
};
|
|
54
|
+
export type VoiceIncidentBundleRoutesOptions = Omit<VoiceIncidentBundleOptions, "sessionId"> & {
|
|
55
|
+
headers?: HeadersInit;
|
|
56
|
+
markdownPath?: false | string;
|
|
57
|
+
name?: string;
|
|
58
|
+
path?: string;
|
|
59
|
+
};
|
|
60
|
+
export type VoiceIncidentBundleArtifactOptions = {
|
|
61
|
+
createdAt?: number;
|
|
62
|
+
expiresAt?: number;
|
|
63
|
+
id?: string;
|
|
64
|
+
metadata?: Record<string, unknown>;
|
|
65
|
+
ttlMs?: number;
|
|
66
|
+
};
|
|
67
|
+
export type VoiceIncidentBundleRetentionOptions = {
|
|
68
|
+
before?: number;
|
|
69
|
+
beforeOrAt?: number;
|
|
70
|
+
dryRun?: boolean;
|
|
71
|
+
expiredAt?: number;
|
|
72
|
+
keepNewest?: number;
|
|
73
|
+
limit?: number;
|
|
74
|
+
store: VoiceIncidentBundleStore;
|
|
75
|
+
};
|
|
76
|
+
export type VoiceIncidentBundleRetentionReport = {
|
|
77
|
+
deleted: StoredVoiceIncidentBundleArtifact[];
|
|
78
|
+
deletedCount: number;
|
|
79
|
+
deletedIds: string[];
|
|
80
|
+
dryRun: boolean;
|
|
81
|
+
scannedCount: number;
|
|
82
|
+
};
|
|
83
|
+
export declare const createVoiceMemoryIncidentBundleStore: <TArtifact extends StoredVoiceIncidentBundleArtifact = StoredVoiceIncidentBundleArtifact>() => VoiceIncidentBundleStore<TArtifact>;
|
|
84
|
+
export declare const createStoredVoiceIncidentBundleArtifact: (bundle: VoiceIncidentBundle, options?: VoiceIncidentBundleArtifactOptions) => StoredVoiceIncidentBundleArtifact;
|
|
85
|
+
export declare const saveVoiceIncidentBundleArtifact: (input: {
|
|
86
|
+
bundle: VoiceIncidentBundle;
|
|
87
|
+
options?: VoiceIncidentBundleArtifactOptions;
|
|
88
|
+
store: VoiceIncidentBundleStore;
|
|
89
|
+
}) => Promise<StoredVoiceIncidentBundleArtifact>;
|
|
90
|
+
export declare const pruneVoiceIncidentBundleArtifacts: (options: VoiceIncidentBundleRetentionOptions) => Promise<VoiceIncidentBundleRetentionReport>;
|
|
91
|
+
export declare const buildVoiceIncidentBundle: (options: VoiceIncidentBundleOptions) => Promise<VoiceIncidentBundle>;
|
|
92
|
+
export declare const createVoiceIncidentBundleRoutes: (options: VoiceIncidentBundleRoutesOptions) => Elysia<"", {
|
|
93
|
+
decorator: {};
|
|
94
|
+
store: {};
|
|
95
|
+
derive: {};
|
|
96
|
+
resolve: {};
|
|
97
|
+
}, {
|
|
98
|
+
typebox: {};
|
|
99
|
+
error: {};
|
|
100
|
+
}, {
|
|
101
|
+
schema: {};
|
|
102
|
+
standaloneSchema: {};
|
|
103
|
+
macro: {};
|
|
104
|
+
macroFn: {};
|
|
105
|
+
parser: {};
|
|
106
|
+
response: {};
|
|
107
|
+
}, {}, {
|
|
108
|
+
derive: {};
|
|
109
|
+
resolve: {};
|
|
110
|
+
schema: {};
|
|
111
|
+
standaloneSchema: {};
|
|
112
|
+
response: {};
|
|
113
|
+
}, {
|
|
114
|
+
derive: {};
|
|
115
|
+
resolve: {};
|
|
116
|
+
schema: {};
|
|
117
|
+
standaloneSchema: {};
|
|
118
|
+
response: {};
|
|
119
|
+
}>;
|