@absolutejs/voice 0.0.22-beta.5 → 0.0.22-beta.500

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.
Files changed (385) hide show
  1. package/README.md +4556 -603
  2. package/dist/agent.d.ts +79 -5
  3. package/dist/agentSquadContract.d.ts +98 -0
  4. package/dist/agentState.d.ts +12 -0
  5. package/dist/agentTools.d.ts +133 -0
  6. package/dist/aiVoiceModel.d.ts +15 -0
  7. package/dist/amdDetector.d.ts +25 -0
  8. package/dist/angular/index.d.ts +26 -2
  9. package/dist/angular/index.js +3703 -246
  10. package/dist/angular/voice-agent-squad-status.service.d.ts +12 -0
  11. package/dist/angular/voice-call-debugger.service.d.ts +12 -0
  12. package/dist/angular/voice-campaign-dialer-proof.service.d.ts +14 -0
  13. package/dist/angular/voice-controller.service.d.ts +3 -1
  14. package/dist/angular/voice-delivery-runtime.component.d.ts +17 -0
  15. package/dist/angular/voice-delivery-runtime.service.d.ts +16 -0
  16. package/dist/angular/voice-live-ops.service.d.ts +11 -0
  17. package/dist/angular/voice-ops-action-center.service.d.ts +13 -0
  18. package/dist/angular/voice-ops-status.component.d.ts +15 -0
  19. package/dist/angular/voice-ops-status.service.d.ts +12 -0
  20. package/dist/angular/voice-platform-coverage.service.d.ts +12 -0
  21. package/dist/angular/voice-profile-comparison.service.d.ts +12 -0
  22. package/dist/angular/voice-proof-trends.service.d.ts +12 -0
  23. package/dist/angular/voice-provider-capabilities.service.d.ts +12 -0
  24. package/dist/angular/voice-provider-contracts.service.d.ts +12 -0
  25. package/dist/angular/voice-provider-status.service.d.ts +12 -0
  26. package/dist/angular/voice-readiness-failures.service.d.ts +13 -0
  27. package/dist/angular/voice-reconnect-profile-evidence.service.d.ts +12 -0
  28. package/dist/angular/voice-routing-status.service.d.ts +11 -0
  29. package/dist/angular/voice-session-observability.service.d.ts +12 -0
  30. package/dist/angular/voice-session-snapshot.service.d.ts +13 -0
  31. package/dist/angular/voice-stream.service.d.ts +6 -1
  32. package/dist/angular/voice-trace-timeline.service.d.ts +12 -0
  33. package/dist/angular/voice-turn-latency.service.d.ts +13 -0
  34. package/dist/angular/voice-turn-quality.service.d.ts +12 -0
  35. package/dist/angular/voice-widget.service.d.ts +18 -0
  36. package/dist/angular/voice-workflow-status.service.d.ts +12 -0
  37. package/dist/assistant.d.ts +12 -13
  38. package/dist/assistantHealth.d.ts +81 -0
  39. package/dist/assistantMemory.d.ts +3 -3
  40. package/dist/assistantMode.d.ts +22 -0
  41. package/dist/audioConditioning.d.ts +1 -1
  42. package/dist/audit.d.ts +131 -0
  43. package/dist/auditDeliveryRoutes.d.ts +85 -0
  44. package/dist/auditExport.d.ts +34 -0
  45. package/dist/auditRoutes.d.ts +66 -0
  46. package/dist/auditSinks.d.ts +151 -0
  47. package/dist/backchannel.d.ts +18 -0
  48. package/dist/bargeInRoutes.d.ts +56 -0
  49. package/dist/browserCallProfiles.d.ts +120 -0
  50. package/dist/browserMediaRoutes.d.ts +62 -0
  51. package/dist/callDebugger.d.ts +66 -0
  52. package/dist/callQuota.d.ts +54 -0
  53. package/dist/callerMemory.d.ts +37 -0
  54. package/dist/campaign.d.ts +794 -0
  55. package/dist/campaignControls.d.ts +37 -0
  56. package/dist/campaignDialers.d.ts +111 -0
  57. package/dist/client/actions.d.ts +117 -1
  58. package/dist/client/agentSquadStatus.d.ts +37 -0
  59. package/dist/client/agentSquadStatusWidget.d.ts +24 -0
  60. package/dist/client/audioPlayer.d.ts +2 -2
  61. package/dist/client/bargeInMonitor.d.ts +7 -0
  62. package/dist/client/browserMedia.d.ts +8 -0
  63. package/dist/client/callDebugger.d.ts +19 -0
  64. package/dist/client/callDebuggerWidget.d.ts +30 -0
  65. package/dist/client/campaignDialerProof.d.ts +23 -0
  66. package/dist/client/connection.d.ts +5 -1
  67. package/dist/client/controller.d.ts +1 -1
  68. package/dist/client/costDashboard.d.ts +27 -0
  69. package/dist/client/createVoiceStream.d.ts +1 -1
  70. package/dist/client/deliveryRuntime.d.ts +34 -0
  71. package/dist/client/deliveryRuntimeWidget.d.ts +37 -0
  72. package/dist/client/duplex.d.ts +2 -2
  73. package/dist/client/htmx.d.ts +1 -1
  74. package/dist/client/htmxBootstrap.js +1011 -16
  75. package/dist/client/index.d.ts +104 -7
  76. package/dist/client/index.js +10409 -10
  77. package/dist/client/liveCallViewer.d.ts +42 -0
  78. package/dist/client/liveOps.d.ts +22 -0
  79. package/dist/client/liveOpsWidget.d.ts +23 -0
  80. package/dist/client/liveTurnLatency.d.ts +41 -0
  81. package/dist/client/microphone.d.ts +4 -4
  82. package/dist/client/opsActionCenter.d.ts +54 -0
  83. package/dist/client/opsActionCenterWidget.d.ts +29 -0
  84. package/dist/client/opsActionHistory.d.ts +19 -0
  85. package/dist/client/opsActionHistoryWidget.d.ts +11 -0
  86. package/dist/client/opsStatus.d.ts +19 -0
  87. package/dist/client/opsStatusWidget.d.ts +40 -0
  88. package/dist/client/platformCoverage.d.ts +19 -0
  89. package/dist/client/platformCoverageWidget.d.ts +37 -0
  90. package/dist/client/profileComparison.d.ts +19 -0
  91. package/dist/client/profileComparisonWidget.d.ts +41 -0
  92. package/dist/client/profileSwitchRecommendation.d.ts +19 -0
  93. package/dist/client/profileSwitchRecommendationWidget.d.ts +12 -0
  94. package/dist/client/proofTrends.d.ts +19 -0
  95. package/dist/client/proofTrendsWidget.d.ts +37 -0
  96. package/dist/client/providerCapabilities.d.ts +19 -0
  97. package/dist/client/providerCapabilitiesWidget.d.ts +32 -0
  98. package/dist/client/providerContracts.d.ts +19 -0
  99. package/dist/client/providerContractsWidget.d.ts +37 -0
  100. package/dist/client/providerSimulationControls.d.ts +33 -0
  101. package/dist/client/providerSimulationControlsWidget.d.ts +20 -0
  102. package/dist/client/providerStatus.d.ts +19 -0
  103. package/dist/client/providerStatusWidget.d.ts +32 -0
  104. package/dist/client/readinessFailures.d.ts +19 -0
  105. package/dist/client/readinessFailuresWidget.d.ts +42 -0
  106. package/dist/client/reconnectProfileEvidence.d.ts +19 -0
  107. package/dist/client/reconnectProfileEvidenceWidget.d.ts +39 -0
  108. package/dist/client/replayTimeline.d.ts +26 -0
  109. package/dist/client/routingStatus.d.ts +19 -0
  110. package/dist/client/routingStatusWidget.d.ts +32 -0
  111. package/dist/client/sessionObservability.d.ts +19 -0
  112. package/dist/client/sessionObservabilityWidget.d.ts +31 -0
  113. package/dist/client/sessionSnapshot.d.ts +21 -0
  114. package/dist/client/sessionSnapshotWidget.d.ts +33 -0
  115. package/dist/client/store.d.ts +1 -1
  116. package/dist/client/traceTimeline.d.ts +19 -0
  117. package/dist/client/traceTimelineWidget.d.ts +36 -0
  118. package/dist/client/turnLatency.d.ts +22 -0
  119. package/dist/client/turnLatencyWidget.d.ts +33 -0
  120. package/dist/client/turnQuality.d.ts +19 -0
  121. package/dist/client/turnQualityWidget.d.ts +32 -0
  122. package/dist/client/voiceWidgetView.d.ts +50 -0
  123. package/dist/client/workflowStatus.d.ts +19 -0
  124. package/dist/competitiveCoverage.d.ts +141 -0
  125. package/dist/correction.d.ts +2 -2
  126. package/dist/costAccounting.d.ts +76 -0
  127. package/dist/dataControl.d.ts +180 -0
  128. package/dist/defineVoiceAssistant.d.ts +68 -0
  129. package/dist/deliveryRuntime.d.ts +158 -0
  130. package/dist/deliverySinkRoutes.d.ts +117 -0
  131. package/dist/demoReadyRoutes.d.ts +98 -0
  132. package/dist/diagnosticsRoutes.d.ts +44 -0
  133. package/dist/evalRoutes.d.ts +219 -0
  134. package/dist/fileStore.d.ts +21 -7
  135. package/dist/generated/htmxBootstrapBundle.d.ts +1 -0
  136. package/dist/guardrails.d.ts +128 -0
  137. package/dist/handoff.d.ts +54 -0
  138. package/dist/handoffHealth.d.ts +94 -0
  139. package/dist/htmx.d.ts +1 -1
  140. package/dist/incidentBundle.d.ts +119 -0
  141. package/dist/incidentTimeline.d.ts +260 -0
  142. package/dist/index.d.ts +278 -46
  143. package/dist/index.js +42417 -4242
  144. package/dist/ivrPlan.d.ts +40 -0
  145. package/dist/latencySlo.d.ts +56 -0
  146. package/dist/liveLatency.d.ts +78 -0
  147. package/dist/liveOps.d.ts +190 -0
  148. package/dist/llmJudge.d.ts +45 -0
  149. package/dist/logger.d.ts +1 -1
  150. package/dist/mediaPipelineRoutes.d.ts +171 -0
  151. package/dist/mediaPipelineSurfaces.d.ts +48 -0
  152. package/dist/memoryStore.d.ts +1 -1
  153. package/dist/midCallSummary.d.ts +27 -0
  154. package/dist/modelAdapters.d.ts +135 -2
  155. package/dist/monitor.d.ts +148 -0
  156. package/dist/multilingualProof.d.ts +77 -0
  157. package/dist/oauth2TokenSource.d.ts +21 -0
  158. package/dist/observabilityExport.d.ts +501 -0
  159. package/dist/openaiTTS.d.ts +18 -0
  160. package/dist/operationalStatus.d.ts +87 -0
  161. package/dist/operationsRecord.d.ts +370 -0
  162. package/dist/ops.d.ts +12 -12
  163. package/dist/opsActionAuditRoutes.d.ts +99 -0
  164. package/dist/opsConsoleRoutes.d.ts +80 -0
  165. package/dist/opsPresets.d.ts +2 -2
  166. package/dist/opsRecovery.d.ts +137 -0
  167. package/dist/opsRuntime.d.ts +6 -6
  168. package/dist/opsSinks.d.ts +13 -13
  169. package/dist/opsStatus.d.ts +76 -0
  170. package/dist/opsStatusRoutes.d.ts +33 -0
  171. package/dist/opsWebhook.d.ts +126 -0
  172. package/dist/otelExporter.d.ts +83 -0
  173. package/dist/outcomeContract.d.ts +146 -0
  174. package/dist/outcomeRecipes.d.ts +4 -4
  175. package/dist/phoneAgent.d.ts +139 -0
  176. package/dist/phoneAgentProductionSmoke.d.ts +115 -0
  177. package/dist/platformCoverage.d.ts +91 -0
  178. package/dist/plugin.d.ts +2 -2
  179. package/dist/postCallAnalysis.d.ts +98 -0
  180. package/dist/postgresStore.d.ts +17 -6
  181. package/dist/presets.d.ts +3 -3
  182. package/dist/productionReadiness.d.ts +756 -0
  183. package/dist/profileSwitchRecommendation.d.ts +350 -0
  184. package/dist/proofAssertions.d.ts +32 -0
  185. package/dist/proofPack.d.ts +211 -0
  186. package/dist/proofRunner.d.ts +79 -0
  187. package/dist/proofTrends.d.ts +966 -0
  188. package/dist/providerAdapters.d.ts +48 -0
  189. package/dist/providerCapabilities.d.ts +92 -0
  190. package/dist/providerDecisionTraces.d.ts +130 -0
  191. package/dist/providerHealth.d.ts +79 -0
  192. package/dist/providerOrchestration.d.ts +109 -0
  193. package/dist/providerRouterTraces.d.ts +35 -0
  194. package/dist/providerRoutingContract.d.ts +71 -0
  195. package/dist/providerSlo.d.ts +142 -0
  196. package/dist/providerStackRecommendations.d.ts +187 -0
  197. package/dist/qualityRoutes.d.ts +76 -0
  198. package/dist/queue.d.ts +72 -11
  199. package/dist/ragTool.d.ts +57 -0
  200. package/dist/react/VoiceAgentSquadStatus.d.ts +5 -0
  201. package/dist/react/VoiceCallDebuggerLaunch.d.ts +6 -0
  202. package/dist/react/VoiceCostDashboard.d.ts +10 -0
  203. package/dist/react/VoiceDeliveryRuntime.d.ts +7 -0
  204. package/dist/react/VoiceLiveCallViewer.d.ts +9 -0
  205. package/dist/react/VoiceOpsActionCenter.d.ts +5 -0
  206. package/dist/react/VoiceOpsStatus.d.ts +6 -0
  207. package/dist/react/VoicePlatformCoverage.d.ts +6 -0
  208. package/dist/react/VoiceProfileComparison.d.ts +6 -0
  209. package/dist/react/VoiceProfileSwitchRecommendation.d.ts +6 -0
  210. package/dist/react/VoiceProofTrends.d.ts +6 -0
  211. package/dist/react/VoiceProviderCapabilities.d.ts +6 -0
  212. package/dist/react/VoiceProviderContracts.d.ts +6 -0
  213. package/dist/react/VoiceProviderSimulationControls.d.ts +5 -0
  214. package/dist/react/VoiceProviderStatus.d.ts +6 -0
  215. package/dist/react/VoiceReadinessFailures.d.ts +6 -0
  216. package/dist/react/VoiceReconnectProfileEvidence.d.ts +6 -0
  217. package/dist/react/VoiceReplayTimeline.d.ts +6 -0
  218. package/dist/react/VoiceRoutingStatus.d.ts +6 -0
  219. package/dist/react/VoiceSessionObservability.d.ts +6 -0
  220. package/dist/react/VoiceSessionSnapshot.d.ts +6 -0
  221. package/dist/react/VoiceTraceTimeline.d.ts +6 -0
  222. package/dist/react/VoiceTurnLatency.d.ts +6 -0
  223. package/dist/react/VoiceTurnQuality.d.ts +6 -0
  224. package/dist/react/VoiceWidget.d.ts +13 -0
  225. package/dist/react/index.d.ts +55 -2
  226. package/dist/react/index.js +12290 -15
  227. package/dist/react/useVoiceAgentSquadStatus.d.ts +8 -0
  228. package/dist/react/useVoiceCallDebugger.d.ts +8 -0
  229. package/dist/react/useVoiceCampaignDialerProof.d.ts +10 -0
  230. package/dist/react/useVoiceController.d.ts +6 -1
  231. package/dist/react/useVoiceDeliveryRuntime.d.ts +13 -0
  232. package/dist/react/useVoiceLiveOps.d.ts +9 -0
  233. package/dist/react/useVoiceOpsActionCenter.d.ts +11 -0
  234. package/dist/react/useVoiceOpsStatus.d.ts +8 -0
  235. package/dist/react/useVoicePlatformCoverage.d.ts +8 -0
  236. package/dist/react/useVoiceProfileComparison.d.ts +8 -0
  237. package/dist/react/useVoiceProfileSwitchRecommendation.d.ts +8 -0
  238. package/dist/react/useVoiceProofTrends.d.ts +8 -0
  239. package/dist/react/useVoiceProviderCapabilities.d.ts +8 -0
  240. package/dist/react/useVoiceProviderContracts.d.ts +8 -0
  241. package/dist/react/useVoiceProviderSimulationControls.d.ts +10 -0
  242. package/dist/react/useVoiceProviderStatus.d.ts +8 -0
  243. package/dist/react/useVoiceReadinessFailures.d.ts +8 -0
  244. package/dist/react/useVoiceReconnectProfileEvidence.d.ts +8 -0
  245. package/dist/react/useVoiceRoutingStatus.d.ts +8 -0
  246. package/dist/react/useVoiceSessionObservability.d.ts +8 -0
  247. package/dist/react/useVoiceSessionSnapshot.d.ts +9 -0
  248. package/dist/react/useVoiceStream.d.ts +6 -1
  249. package/dist/react/useVoiceTraceTimeline.d.ts +8 -0
  250. package/dist/react/useVoiceTurnLatency.d.ts +9 -0
  251. package/dist/react/useVoiceTurnQuality.d.ts +8 -0
  252. package/dist/react/useVoiceWorkflowStatus.d.ts +8 -0
  253. package/dist/readinessProfiles.d.ts +45 -0
  254. package/dist/realtimeChannel.d.ts +136 -0
  255. package/dist/realtimeProviderContracts.d.ts +133 -0
  256. package/dist/reconnectContract.d.ts +176 -0
  257. package/dist/recordingRedaction.d.ts +18 -0
  258. package/dist/recordingStore.d.ts +60 -0
  259. package/dist/redaction.d.ts +13 -0
  260. package/dist/resilienceRoutes.d.ts +146 -0
  261. package/dist/retention.d.ts +37 -0
  262. package/dist/routeAuth.d.ts +58 -0
  263. package/dist/routing.d.ts +1 -1
  264. package/dist/runtimeOps.d.ts +3 -3
  265. package/dist/s3Store.d.ts +18 -3
  266. package/dist/semanticTurn.d.ts +27 -0
  267. package/dist/session.d.ts +1 -1
  268. package/dist/sessionObservability.d.ts +145 -0
  269. package/dist/sessionReplay.d.ts +187 -0
  270. package/dist/sessionSnapshot.d.ts +109 -0
  271. package/dist/simulationSuite.d.ts +143 -0
  272. package/dist/sloCalibration.d.ts +185 -0
  273. package/dist/sqliteStore.d.ts +17 -6
  274. package/dist/store.d.ts +1 -1
  275. package/dist/svelte/createVoiceAgentSquadStatus.d.ts +9 -0
  276. package/dist/svelte/createVoiceCallDebugger.d.ts +12 -0
  277. package/dist/svelte/createVoiceCampaignDialerProof.d.ts +9 -0
  278. package/dist/svelte/createVoiceDeliveryRuntime.d.ts +11 -0
  279. package/dist/svelte/createVoiceLiveOps.d.ts +13 -0
  280. package/dist/svelte/createVoiceOpsActionCenter.d.ts +10 -0
  281. package/dist/svelte/createVoiceOpsStatus.d.ts +9 -0
  282. package/dist/svelte/createVoicePlatformCoverage.d.ts +7 -0
  283. package/dist/svelte/createVoiceProfileComparison.d.ts +7 -0
  284. package/dist/svelte/createVoiceProofTrends.d.ts +7 -0
  285. package/dist/svelte/createVoiceProviderCapabilities.d.ts +10 -0
  286. package/dist/svelte/createVoiceProviderContracts.d.ts +10 -0
  287. package/dist/svelte/createVoiceProviderSimulationControls.d.ts +11 -0
  288. package/dist/svelte/createVoiceProviderStatus.d.ts +10 -0
  289. package/dist/svelte/createVoiceReadinessFailures.d.ts +7 -0
  290. package/dist/svelte/createVoiceReconnectProfileEvidence.d.ts +7 -0
  291. package/dist/svelte/createVoiceRoutingStatus.d.ts +10 -0
  292. package/dist/svelte/createVoiceSessionObservability.d.ts +10 -0
  293. package/dist/svelte/createVoiceSessionSnapshot.d.ts +13 -0
  294. package/dist/svelte/createVoiceStream.d.ts +1 -1
  295. package/dist/svelte/createVoiceTraceTimeline.d.ts +10 -0
  296. package/dist/svelte/createVoiceTurnLatency.d.ts +11 -0
  297. package/dist/svelte/createVoiceTurnQuality.d.ts +10 -0
  298. package/dist/svelte/createVoiceWidget.d.ts +19 -0
  299. package/dist/svelte/createVoiceWorkflowStatus.d.ts +8 -0
  300. package/dist/svelte/index.d.ts +27 -2
  301. package/dist/svelte/index.js +6010 -150
  302. package/dist/telephony/contract.d.ts +61 -0
  303. package/dist/telephony/matrix.d.ts +97 -0
  304. package/dist/telephony/plivo.d.ts +303 -0
  305. package/dist/telephony/response.d.ts +1 -1
  306. package/dist/telephony/security.d.ts +182 -0
  307. package/dist/telephony/telnyx.d.ts +291 -0
  308. package/dist/telephony/twilio.d.ts +147 -13
  309. package/dist/telephonyMediaRoutes.d.ts +72 -0
  310. package/dist/telephonyOutcome.d.ts +273 -0
  311. package/dist/testing/accuracy.d.ts +1 -1
  312. package/dist/testing/benchmark.d.ts +9 -9
  313. package/dist/testing/corrected.d.ts +5 -5
  314. package/dist/testing/duplex.d.ts +3 -3
  315. package/dist/testing/fixtures.d.ts +3 -3
  316. package/dist/testing/index.d.ts +13 -11
  317. package/dist/testing/index.js +9117 -2592
  318. package/dist/testing/ioProviderSimulator.d.ts +41 -0
  319. package/dist/testing/providerSimulator.d.ts +44 -0
  320. package/dist/testing/review.d.ts +4 -4
  321. package/dist/testing/sessionBenchmark.d.ts +3 -3
  322. package/dist/testing/stt.d.ts +3 -3
  323. package/dist/testing/telephony.d.ts +25 -0
  324. package/dist/testing/tts.d.ts +1 -1
  325. package/dist/toolContract.d.ts +161 -0
  326. package/dist/toolRuntime.d.ts +50 -0
  327. package/dist/trace.d.ts +46 -7
  328. package/dist/traceDeliveryRoutes.d.ts +86 -0
  329. package/dist/traceTimeline.d.ts +97 -0
  330. package/dist/turnDetection.d.ts +1 -1
  331. package/dist/turnLatency.d.ts +95 -0
  332. package/dist/turnProfiles.d.ts +2 -2
  333. package/dist/turnQuality.d.ts +94 -0
  334. package/dist/types.d.ts +366 -71
  335. package/dist/vapiAdapter.d.ts +160 -0
  336. package/dist/voiceMonitoring.d.ts +444 -0
  337. package/dist/vue/VoiceCallDebuggerLaunch.d.ts +68 -0
  338. package/dist/vue/VoiceDeliveryRuntime.d.ts +30 -0
  339. package/dist/vue/VoiceOpsActionCenter.d.ts +13 -0
  340. package/dist/vue/VoiceOpsStatus.d.ts +30 -0
  341. package/dist/vue/VoicePlatformCoverage.d.ts +23 -0
  342. package/dist/vue/VoiceProofTrends.d.ts +21 -0
  343. package/dist/vue/VoiceProviderCapabilities.d.ts +51 -0
  344. package/dist/vue/VoiceProviderContracts.d.ts +21 -0
  345. package/dist/vue/VoiceProviderSimulationControls.d.ts +88 -0
  346. package/dist/vue/VoiceProviderStatus.d.ts +51 -0
  347. package/dist/vue/VoiceReadinessFailures.d.ts +21 -0
  348. package/dist/vue/VoiceReconnectProfileEvidence.d.ts +21 -0
  349. package/dist/vue/VoiceRoutingStatus.d.ts +51 -0
  350. package/dist/vue/VoiceSessionObservability.d.ts +23 -0
  351. package/dist/vue/VoiceSessionSnapshot.d.ts +68 -0
  352. package/dist/vue/VoiceTurnLatency.d.ts +69 -0
  353. package/dist/vue/VoiceTurnQuality.d.ts +51 -0
  354. package/dist/vue/VoiceWidget.d.ts +77 -0
  355. package/dist/vue/index.d.ts +44 -2
  356. package/dist/vue/index.js +11027 -31
  357. package/dist/vue/useVoiceAgentSquadStatus.d.ts +9 -0
  358. package/dist/vue/useVoiceCallDebugger.d.ts +10 -0
  359. package/dist/vue/useVoiceCampaignDialerProof.d.ts +11 -0
  360. package/dist/vue/useVoiceController.d.ts +4 -2
  361. package/dist/vue/useVoiceDeliveryRuntime.d.ts +13 -0
  362. package/dist/vue/useVoiceLiveOps.d.ts +9 -0
  363. package/dist/vue/useVoiceOpsActionCenter.d.ts +11 -0
  364. package/dist/vue/useVoiceOpsStatus.d.ts +9 -0
  365. package/dist/vue/useVoicePlatformCoverage.d.ts +9 -0
  366. package/dist/vue/useVoiceProfileComparison.d.ts +9 -0
  367. package/dist/vue/useVoiceProofTrends.d.ts +9 -0
  368. package/dist/vue/useVoiceProviderCapabilities.d.ts +9 -0
  369. package/dist/vue/useVoiceProviderContracts.d.ts +9 -0
  370. package/dist/vue/useVoiceProviderSimulationControls.d.ts +24 -0
  371. package/dist/vue/useVoiceProviderStatus.d.ts +9 -0
  372. package/dist/vue/useVoiceReadinessFailures.d.ts +959 -0
  373. package/dist/vue/useVoiceReconnectProfileEvidence.d.ts +9 -0
  374. package/dist/vue/useVoiceRoutingStatus.d.ts +8 -0
  375. package/dist/vue/useVoiceSessionObservability.d.ts +9 -0
  376. package/dist/vue/useVoiceSessionSnapshot.d.ts +10 -0
  377. package/dist/vue/useVoiceStream.d.ts +7 -2
  378. package/dist/vue/useVoiceTraceTimeline.d.ts +9 -0
  379. package/dist/vue/useVoiceTurnLatency.d.ts +10 -0
  380. package/dist/vue/useVoiceTurnQuality.d.ts +9 -0
  381. package/dist/vue/useVoiceWorkflowStatus.d.ts +9 -0
  382. package/dist/webhookVerification.d.ts +27 -0
  383. package/dist/workflowContract.d.ts +91 -0
  384. package/fixtures/manifest.json +356 -197
  385. package/package.json +265 -256
@@ -68,10 +68,277 @@ var __decorateElement = (array, flags, name, decorators, target, extra) => {
68
68
  }
69
69
  return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
70
70
  };
71
+ var __require = import.meta.require;
71
72
 
72
- // src/angular/voice-stream.service.ts
73
+ // src/angular/voice-ops-status.service.ts
73
74
  import { computed, Injectable, signal } from "@angular/core";
74
75
 
76
+ // src/client/opsStatus.ts
77
+ var fetchVoiceOpsStatus = async (path = "/api/voice/ops-status", options = {}) => {
78
+ const fetchImpl = options.fetch ?? globalThis.fetch;
79
+ const response = await fetchImpl(path);
80
+ if (!response.ok) {
81
+ throw new Error(`Voice ops status failed: HTTP ${response.status}`);
82
+ }
83
+ return await response.json();
84
+ };
85
+ var createVoiceOpsStatusStore = (path = "/api/voice/ops-status", options = {}) => {
86
+ const listeners = new Set;
87
+ let closed = false;
88
+ let timer;
89
+ let snapshot = {
90
+ error: null,
91
+ isLoading: false
92
+ };
93
+ const emit = () => {
94
+ for (const listener of listeners) {
95
+ listener();
96
+ }
97
+ };
98
+ const refresh = async () => {
99
+ if (closed) {
100
+ return snapshot.report;
101
+ }
102
+ snapshot = {
103
+ ...snapshot,
104
+ error: null,
105
+ isLoading: true
106
+ };
107
+ emit();
108
+ try {
109
+ const report = await fetchVoiceOpsStatus(path, options);
110
+ snapshot = {
111
+ error: null,
112
+ isLoading: false,
113
+ report,
114
+ updatedAt: Date.now()
115
+ };
116
+ emit();
117
+ return report;
118
+ } catch (error) {
119
+ snapshot = {
120
+ ...snapshot,
121
+ error: error instanceof Error ? error.message : String(error),
122
+ isLoading: false
123
+ };
124
+ emit();
125
+ throw error;
126
+ }
127
+ };
128
+ const close = () => {
129
+ closed = true;
130
+ if (timer) {
131
+ clearInterval(timer);
132
+ timer = undefined;
133
+ }
134
+ listeners.clear();
135
+ };
136
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
137
+ timer = setInterval(() => {
138
+ refresh().catch(() => {});
139
+ }, options.intervalMs);
140
+ }
141
+ return {
142
+ close,
143
+ getServerSnapshot: () => snapshot,
144
+ getSnapshot: () => snapshot,
145
+ refresh,
146
+ subscribe: (listener) => {
147
+ listeners.add(listener);
148
+ return () => {
149
+ listeners.delete(listener);
150
+ };
151
+ }
152
+ };
153
+ };
154
+
155
+ // src/angular/voice-ops-status.service.ts
156
+ var _dec = [
157
+ Injectable({ providedIn: "root" })
158
+ ];
159
+ var _init = __decoratorStart(undefined);
160
+
161
+ class VoiceOpsStatusService {
162
+ connect(path = "/api/voice/ops-status", options = {}) {
163
+ const store = createVoiceOpsStatusStore(path, options);
164
+ const errorSignal = signal(null);
165
+ const isLoadingSignal = signal(false);
166
+ const reportSignal = signal(undefined);
167
+ const updatedAtSignal = signal(undefined);
168
+ const sync = () => {
169
+ const snapshot = store.getSnapshot();
170
+ errorSignal.set(snapshot.error);
171
+ isLoadingSignal.set(snapshot.isLoading);
172
+ reportSignal.set(snapshot.report);
173
+ updatedAtSignal.set(snapshot.updatedAt);
174
+ };
175
+ const unsubscribe = store.subscribe(sync);
176
+ sync();
177
+ if (typeof window !== "undefined") {
178
+ store.refresh().catch(() => {});
179
+ }
180
+ return {
181
+ close: () => {
182
+ unsubscribe();
183
+ store.close();
184
+ },
185
+ error: computed(() => errorSignal()),
186
+ isLoading: computed(() => isLoadingSignal()),
187
+ refresh: store.refresh,
188
+ report: computed(() => reportSignal()),
189
+ updatedAt: computed(() => updatedAtSignal())
190
+ };
191
+ }
192
+ }
193
+ VoiceOpsStatusService = __decorateElement(_init, 0, "VoiceOpsStatusService", _dec, VoiceOpsStatusService);
194
+ __runInitializers(_init, 1, VoiceOpsStatusService);
195
+ __decoratorMetadata(_init, VoiceOpsStatusService);
196
+ let _VoiceOpsStatusService = VoiceOpsStatusService;
197
+ // src/angular/voice-widget.service.ts
198
+ import { computed as computed2, Injectable as Injectable2, signal as signal2 } from "@angular/core";
199
+
200
+ // src/client/htmx.ts
201
+ var DEFAULT_EVENT_NAME = "voice-refresh";
202
+ var DEFAULT_QUERY_PARAM = "sessionId";
203
+ var resolveElement = (input) => {
204
+ if (typeof input !== "string") {
205
+ return input;
206
+ }
207
+ return document.querySelector(input);
208
+ };
209
+ var buildRoute = (element, route, queryParam, sessionId) => {
210
+ const baseRoute = route ?? element.getAttribute("hx-get") ?? "";
211
+ if (!baseRoute) {
212
+ return "";
213
+ }
214
+ const url = new URL(baseRoute, window.location.origin);
215
+ if (sessionId) {
216
+ url.searchParams.set(queryParam, sessionId);
217
+ } else {
218
+ url.searchParams.delete(queryParam);
219
+ }
220
+ return `${url.pathname}${url.search}${url.hash}`;
221
+ };
222
+ var bindVoiceHTMX = (stream, options) => {
223
+ if (typeof window === "undefined" || typeof document === "undefined") {
224
+ return () => {};
225
+ }
226
+ const element = resolveElement(options.element);
227
+ if (!element) {
228
+ return () => {};
229
+ }
230
+ const eventName = options.eventName ?? DEFAULT_EVENT_NAME;
231
+ const queryParam = options.sessionQueryParam ?? DEFAULT_QUERY_PARAM;
232
+ const sync = () => {
233
+ const htmxWindow = window;
234
+ const nextRoute = buildRoute(element, options.route, queryParam, stream.sessionId);
235
+ if (nextRoute) {
236
+ element.setAttribute("hx-get", nextRoute);
237
+ }
238
+ htmxWindow.htmx?.process?.(element);
239
+ htmxWindow.htmx?.trigger?.(element, eventName);
240
+ };
241
+ const unsubscribe = stream.subscribe(sync);
242
+ sync();
243
+ return () => {
244
+ unsubscribe();
245
+ };
246
+ };
247
+
248
+ // src/client/microphone.ts
249
+ var clampSample = (value) => Math.max(-1, Math.min(1, value));
250
+ var floatTo16BitPCM = (input) => {
251
+ const output = new Int16Array(input.length);
252
+ for (let index = 0;index < input.length; index += 1) {
253
+ const sample = clampSample(input[index] ?? 0);
254
+ output[index] = sample < 0 ? sample * 32768 : sample * 32767;
255
+ }
256
+ return new Uint8Array(output.buffer);
257
+ };
258
+ var getPcmLevel = (audio) => {
259
+ const bytes = audio instanceof Uint8Array ? audio : new Uint8Array(audio);
260
+ if (bytes.byteLength < 2) {
261
+ return 0;
262
+ }
263
+ const samples = new Int16Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 2));
264
+ if (samples.length === 0) {
265
+ return 0;
266
+ }
267
+ let sumSquares = 0;
268
+ for (const sample of samples) {
269
+ const normalized = sample / 32768;
270
+ sumSquares += normalized * normalized;
271
+ }
272
+ return Math.min(1, Math.max(0, Math.sqrt(sumSquares / samples.length) * 5.5));
273
+ };
274
+ var downsampleBuffer = (input, sourceRate, targetRate) => {
275
+ if (sourceRate === targetRate) {
276
+ return input;
277
+ }
278
+ const ratio = sourceRate / targetRate;
279
+ const length = Math.round(input.length / ratio);
280
+ const output = new Float32Array(length);
281
+ let offsetResult = 0;
282
+ let offsetBuffer = 0;
283
+ while (offsetResult < output.length) {
284
+ const nextOffsetBuffer = Math.round((offsetResult + 1) * ratio);
285
+ let accum = 0;
286
+ let count = 0;
287
+ for (let index = offsetBuffer;index < nextOffsetBuffer && index < input.length; index += 1) {
288
+ accum += input[index] ?? 0;
289
+ count += 1;
290
+ }
291
+ output[offsetResult] = count > 0 ? accum / count : 0;
292
+ offsetResult += 1;
293
+ offsetBuffer = nextOffsetBuffer;
294
+ }
295
+ return output;
296
+ };
297
+ var createMicrophoneCapture = (options) => {
298
+ let audioContext = null;
299
+ let sourceNode = null;
300
+ let processorNode = null;
301
+ let mediaStream = null;
302
+ const start = async () => {
303
+ if (typeof navigator === "undefined" || !navigator.mediaDevices?.getUserMedia) {
304
+ throw new Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");
305
+ }
306
+ const AudioContextCtor = (typeof window !== "undefined" ? window.AudioContext ?? window.webkitAudioContext : undefined) ?? AudioContext;
307
+ if (!AudioContextCtor) {
308
+ throw new Error("Browser microphone capture requires AudioContext support.");
309
+ }
310
+ mediaStream = await navigator.mediaDevices.getUserMedia({
311
+ audio: {
312
+ channelCount: options.channelCount ?? 1
313
+ }
314
+ });
315
+ audioContext = new AudioContextCtor;
316
+ sourceNode = audioContext.createMediaStreamSource(mediaStream);
317
+ processorNode = audioContext.createScriptProcessor(4096, 1, 1);
318
+ processorNode.onaudioprocess = (event) => {
319
+ const channel = event.inputBuffer.getChannelData(0);
320
+ const downsampled = downsampleBuffer(channel, audioContext?.sampleRate ?? 48000, options.sampleRateHz ?? 16000);
321
+ const pcm = floatTo16BitPCM(downsampled);
322
+ options.onLevel?.(getPcmLevel(pcm));
323
+ options.onAudio(pcm);
324
+ };
325
+ sourceNode.connect(processorNode);
326
+ processorNode.connect(audioContext.destination);
327
+ };
328
+ const stop = () => {
329
+ processorNode?.disconnect();
330
+ sourceNode?.disconnect();
331
+ mediaStream?.getTracks().forEach((track) => track.stop());
332
+ audioContext?.close();
333
+ options.onLevel?.(0);
334
+ audioContext = null;
335
+ mediaStream = null;
336
+ processorNode = null;
337
+ sourceNode = null;
338
+ };
339
+ return { start, stop };
340
+ };
341
+
75
342
  // src/client/actions.ts
76
343
  var normalizeErrorMessage = (value) => {
77
344
  if (typeof value === "string" && value.trim()) {
@@ -120,6 +387,17 @@ var serverMessageToAction = (message) => {
120
387
  sessionId: message.sessionId,
121
388
  type: "complete"
122
389
  };
390
+ case "connection":
391
+ return {
392
+ reconnect: message.reconnect,
393
+ type: "connection"
394
+ };
395
+ case "call_lifecycle":
396
+ return {
397
+ event: message.event,
398
+ sessionId: message.sessionId,
399
+ type: "call_lifecycle"
400
+ };
123
401
  case "error":
124
402
  return {
125
403
  message: normalizeErrorMessage(message.message),
@@ -135,9 +413,22 @@ var serverMessageToAction = (message) => {
135
413
  transcript: message.transcript,
136
414
  type: "partial"
137
415
  };
416
+ case "replay":
417
+ return {
418
+ assistantTexts: message.assistantTexts,
419
+ call: message.call,
420
+ partial: message.partial,
421
+ scenarioId: message.scenarioId,
422
+ sessionId: message.sessionId,
423
+ sessionMetadata: message.sessionMetadata,
424
+ status: message.status,
425
+ turns: message.turns,
426
+ type: "replay"
427
+ };
138
428
  case "session":
139
429
  return {
140
430
  sessionId: message.sessionId,
431
+ sessionMetadata: message.sessionMetadata,
141
432
  scenarioId: message.scenarioId,
142
433
  status: message.status,
143
434
  type: "session"
@@ -152,6 +443,84 @@ var serverMessageToAction = (message) => {
152
443
  }
153
444
  };
154
445
 
446
+ // src/client/browserMedia.ts
447
+ import {
448
+ buildMediaWebRTCStatsReport,
449
+ buildMediaWebRTCStreamContinuityReport,
450
+ collectMediaWebRTCStats
451
+ } from "@absolutejs/media";
452
+ var DEFAULT_BROWSER_MEDIA_PATH = "/api/voice/browser-media";
453
+ var DEFAULT_BROWSER_MEDIA_INTERVAL_MS = 5000;
454
+ var resolvePeerConnection = async (options) => options.peerConnection ?? await options.getPeerConnection?.() ?? null;
455
+ var postBrowserMediaReport = async (payload, options) => {
456
+ const requestFetch = options.fetch ?? globalThis.fetch;
457
+ if (!requestFetch) {
458
+ return;
459
+ }
460
+ await requestFetch(options.path ?? DEFAULT_BROWSER_MEDIA_PATH, {
461
+ body: JSON.stringify(payload),
462
+ headers: {
463
+ "Content-Type": "application/json"
464
+ },
465
+ keepalive: true,
466
+ method: "POST"
467
+ });
468
+ };
469
+ var createVoiceBrowserMediaReporter = (options) => {
470
+ let interval = null;
471
+ let previousStats = [];
472
+ const reportOnce = async () => {
473
+ const peerConnection = await resolvePeerConnection(options);
474
+ if (!peerConnection) {
475
+ return;
476
+ }
477
+ const stats = await collectMediaWebRTCStats({ peerConnection });
478
+ const report = buildMediaWebRTCStatsReport({
479
+ ...options,
480
+ stats
481
+ });
482
+ const continuity = options.continuity === false ? undefined : buildMediaWebRTCStreamContinuityReport({
483
+ ...options.continuity,
484
+ previousStats,
485
+ stats
486
+ });
487
+ const payload = {
488
+ at: Date.now(),
489
+ continuity,
490
+ report,
491
+ scenarioId: options.getScenarioId?.() ?? null,
492
+ sessionId: options.getSessionId?.() ?? null
493
+ };
494
+ previousStats = stats;
495
+ options.onReport?.(payload);
496
+ await postBrowserMediaReport(payload, options);
497
+ return payload;
498
+ };
499
+ const run = () => {
500
+ reportOnce().catch((error) => {
501
+ options.onError?.(error);
502
+ });
503
+ };
504
+ const stop = () => {
505
+ if (interval) {
506
+ clearInterval(interval);
507
+ interval = null;
508
+ }
509
+ };
510
+ return {
511
+ close: stop,
512
+ reportOnce,
513
+ start: () => {
514
+ if (interval) {
515
+ return;
516
+ }
517
+ run();
518
+ interval = setInterval(run, options.intervalMs ?? DEFAULT_BROWSER_MEDIA_INTERVAL_MS);
519
+ },
520
+ stop
521
+ };
522
+ };
523
+
155
524
  // src/client/connection.ts
156
525
  var WS_OPEN = 1;
157
526
  var WS_CLOSED = 3;
@@ -163,7 +532,7 @@ var DEFAULT_SCENARIO_QUERY_PARAM = "scenarioId";
163
532
  var noop = () => {};
164
533
  var noopUnsubscribe = () => noop;
165
534
  var NOOP_CONNECTION = {
166
- start: () => {},
535
+ callControl: noop,
167
536
  close: noop,
168
537
  endTurn: noop,
169
538
  getReadyState: () => WS_CLOSED,
@@ -171,6 +540,8 @@ var NOOP_CONNECTION = {
171
540
  getSessionId: () => "",
172
541
  send: noop,
173
542
  sendAudio: noop,
543
+ simulateDisconnect: noop,
544
+ start: () => {},
174
545
  subscribe: noopUnsubscribe
175
546
  };
176
547
  var createSessionId = () => crypto.randomUUID();
@@ -192,11 +563,14 @@ var isVoiceServerMessage = (value) => {
192
563
  switch (value.type) {
193
564
  case "audio":
194
565
  case "assistant":
566
+ case "call_lifecycle":
195
567
  case "complete":
568
+ case "connection":
196
569
  case "error":
197
570
  case "final":
198
571
  case "partial":
199
572
  case "pong":
573
+ case "replay":
200
574
  case "session":
201
575
  case "turn":
202
576
  return true;
@@ -233,6 +607,9 @@ var createVoiceConnection = (path, options = {}) => {
233
607
  sessionId: options.sessionId ?? createSessionId(),
234
608
  ws: null
235
609
  };
610
+ const emitConnection = (reconnect) => {
611
+ listeners.forEach((listener) => listener(reconnect));
612
+ };
236
613
  const clearTimers = () => {
237
614
  if (state.pingInterval) {
238
615
  clearInterval(state.pingInterval);
@@ -255,9 +632,28 @@ var createVoiceConnection = (path, options = {}) => {
255
632
  }
256
633
  };
257
634
  const scheduleReconnect = () => {
635
+ const nextAttemptAt = Date.now() + RECONNECT_DELAY_MS;
258
636
  state.reconnectAttempts += 1;
637
+ emitConnection({
638
+ reconnect: {
639
+ attempts: state.reconnectAttempts,
640
+ lastDisconnectAt: Date.now(),
641
+ maxAttempts: maxReconnectAttempts,
642
+ nextAttemptAt,
643
+ status: "reconnecting"
644
+ },
645
+ type: "connection"
646
+ });
259
647
  state.reconnectTimeout = setTimeout(() => {
260
648
  if (state.reconnectAttempts > maxReconnectAttempts) {
649
+ emitConnection({
650
+ reconnect: {
651
+ attempts: state.reconnectAttempts,
652
+ maxAttempts: maxReconnectAttempts,
653
+ status: "exhausted"
654
+ },
655
+ type: "connection"
656
+ });
261
657
  return;
262
658
  }
263
659
  connect();
@@ -267,9 +663,21 @@ var createVoiceConnection = (path, options = {}) => {
267
663
  const ws = new WebSocket(buildWsUrl(path, state.sessionId, state.scenarioId));
268
664
  ws.binaryType = "arraybuffer";
269
665
  ws.onopen = () => {
666
+ const wasReconnecting = state.reconnectAttempts > 0;
270
667
  state.isConnected = true;
271
- state.reconnectAttempts = 0;
272
668
  flushPendingMessages();
669
+ if (wasReconnecting) {
670
+ emitConnection({
671
+ reconnect: {
672
+ attempts: state.reconnectAttempts,
673
+ lastResumedAt: Date.now(),
674
+ maxAttempts: maxReconnectAttempts,
675
+ status: "resumed"
676
+ },
677
+ type: "connection"
678
+ });
679
+ state.reconnectAttempts = 0;
680
+ }
273
681
  listeners.forEach((listener) => listener({
274
682
  scenarioId: state.scenarioId ?? undefined,
275
683
  sessionId: state.sessionId,
@@ -299,6 +707,16 @@ var createVoiceConnection = (path, options = {}) => {
299
707
  const reconnectable = shouldReconnect && event.code !== WS_NORMAL_CLOSURE && state.reconnectAttempts < maxReconnectAttempts;
300
708
  if (reconnectable) {
301
709
  scheduleReconnect();
710
+ } else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
711
+ emitConnection({
712
+ reconnect: {
713
+ attempts: state.reconnectAttempts,
714
+ lastDisconnectAt: Date.now(),
715
+ maxAttempts: maxReconnectAttempts,
716
+ status: "exhausted"
717
+ },
718
+ type: "connection"
719
+ });
302
720
  }
303
721
  };
304
722
  state.ws = ws;
@@ -332,6 +750,12 @@ var createVoiceConnection = (path, options = {}) => {
332
750
  const endTurn = () => {
333
751
  send({ type: "end_turn" });
334
752
  };
753
+ const callControl = (message) => {
754
+ send({
755
+ ...message,
756
+ type: "call_control"
757
+ });
758
+ };
335
759
  const close = () => {
336
760
  clearTimers();
337
761
  if (state.ws) {
@@ -341,6 +765,11 @@ var createVoiceConnection = (path, options = {}) => {
341
765
  state.isConnected = false;
342
766
  listeners.clear();
343
767
  };
768
+ const simulateDisconnect = () => {
769
+ if (state.ws?.readyState === WS_OPEN) {
770
+ state.ws.close(4000, "absolutejs-voice-reconnect-proof");
771
+ }
772
+ };
344
773
  const subscribe = (callback) => {
345
774
  listeners.add(callback);
346
775
  return () => {
@@ -349,7 +778,7 @@ var createVoiceConnection = (path, options = {}) => {
349
778
  };
350
779
  connect();
351
780
  return {
352
- start,
781
+ callControl,
353
782
  close,
354
783
  endTurn,
355
784
  getReadyState: () => state.ws?.readyState ?? WS_CLOSED,
@@ -357,18 +786,28 @@ var createVoiceConnection = (path, options = {}) => {
357
786
  getSessionId: () => state.sessionId,
358
787
  send,
359
788
  sendAudio,
789
+ simulateDisconnect,
790
+ start,
360
791
  subscribe
361
792
  };
362
793
  };
363
794
 
364
795
  // src/client/store.ts
796
+ var createInitialReconnectState = () => ({
797
+ attempts: 0,
798
+ maxAttempts: 0,
799
+ status: "idle"
800
+ });
365
801
  var createInitialState = () => ({
366
802
  assistantAudio: [],
367
803
  assistantTexts: [],
804
+ call: null,
368
805
  error: null,
369
806
  isConnected: false,
807
+ sessionMetadata: null,
370
808
  scenarioId: null,
371
809
  partial: "",
810
+ reconnect: createInitialReconnectState(),
372
811
  sessionId: null,
373
812
  status: "idle",
374
813
  turns: []
@@ -408,10 +847,36 @@ var createVoiceStreamStore = () => {
408
847
  status: "completed"
409
848
  };
410
849
  break;
850
+ case "call_lifecycle":
851
+ state = {
852
+ ...state,
853
+ call: {
854
+ ...state.call,
855
+ disposition: action.event.type === "end" ? action.event.disposition : state.call?.disposition,
856
+ endedAt: action.event.type === "end" ? action.event.at : state.call?.endedAt,
857
+ events: [...state.call?.events ?? [], action.event],
858
+ lastEventAt: action.event.at,
859
+ startedAt: state.call?.startedAt ?? action.event.at
860
+ },
861
+ sessionId: action.sessionId
862
+ };
863
+ break;
411
864
  case "connected":
412
865
  state = {
413
866
  ...state,
414
- isConnected: true
867
+ isConnected: true,
868
+ reconnect: state.reconnect.status === "reconnecting" ? {
869
+ ...state.reconnect,
870
+ lastResumedAt: Date.now(),
871
+ nextAttemptAt: undefined,
872
+ status: "resumed"
873
+ } : state.reconnect
874
+ };
875
+ break;
876
+ case "connection":
877
+ state = {
878
+ ...state,
879
+ reconnect: action.reconnect
415
880
  };
416
881
  break;
417
882
  case "disconnected":
@@ -439,6 +904,27 @@ var createVoiceStreamStore = () => {
439
904
  partial: action.transcript.text
440
905
  };
441
906
  break;
907
+ case "replay":
908
+ state = {
909
+ ...state,
910
+ assistantTexts: [...action.assistantTexts],
911
+ call: action.call ?? null,
912
+ error: null,
913
+ isConnected: action.status === "active",
914
+ partial: action.partial,
915
+ reconnect: state.reconnect.status === "reconnecting" ? {
916
+ ...state.reconnect,
917
+ lastResumedAt: Date.now(),
918
+ nextAttemptAt: undefined,
919
+ status: "resumed"
920
+ } : state.reconnect,
921
+ scenarioId: action.scenarioId ?? state.scenarioId,
922
+ sessionId: action.sessionId,
923
+ sessionMetadata: action.sessionMetadata ?? state.sessionMetadata,
924
+ status: action.status,
925
+ turns: [...action.turns]
926
+ };
927
+ break;
442
928
  case "session":
443
929
  state = {
444
930
  ...state,
@@ -446,6 +932,7 @@ var createVoiceStreamStore = () => {
446
932
  scenarioId: action.scenarioId ?? state.scenarioId,
447
933
  isConnected: action.status === "active",
448
934
  sessionId: action.sessionId,
935
+ sessionMetadata: action.sessionMetadata ?? state.sessionMetadata,
449
936
  status: action.status
450
937
  };
451
938
  break;
@@ -476,26 +963,60 @@ var createVoiceStreamStore = () => {
476
963
  var createVoiceStream = (path, options = {}) => {
477
964
  const connection = createVoiceConnection(path, options);
478
965
  const store = createVoiceStreamStore();
966
+ const browserMediaReporter = options.browserMedia && typeof window !== "undefined" ? createVoiceBrowserMediaReporter({
967
+ ...options.browserMedia,
968
+ getScenarioId: () => options.browserMedia ? options.browserMedia.getScenarioId?.() ?? connection.getScenarioId() : connection.getScenarioId(),
969
+ getSessionId: () => options.browserMedia ? options.browserMedia.getSessionId?.() ?? connection.getSessionId() : connection.getSessionId()
970
+ }) : null;
479
971
  const subscribers = new Set;
480
972
  const start = (input) => Promise.resolve().then(() => {
481
973
  if (!input?.sessionId && !input?.scenarioId) {
482
974
  return;
483
975
  }
484
976
  connection.start(input);
977
+ browserMediaReporter?.start();
485
978
  });
486
979
  const notify = () => {
487
980
  subscribers.forEach((subscriber) => subscriber());
488
981
  };
489
- const unsubscribeConnection = connection.subscribe((message) => {
982
+ const reportReconnect = () => {
983
+ if (!options.reconnectReportPath || typeof fetch === "undefined") {
984
+ return;
985
+ }
986
+ const snapshot = store.getSnapshot();
987
+ const body = JSON.stringify({
988
+ at: Date.now(),
989
+ reconnect: snapshot.reconnect,
990
+ scenarioId: snapshot.scenarioId,
991
+ sessionId: connection.getSessionId(),
992
+ turnIds: snapshot.turns.map((turn) => turn.id)
993
+ });
994
+ fetch(options.reconnectReportPath, {
995
+ body,
996
+ headers: {
997
+ "Content-Type": "application/json"
998
+ },
999
+ keepalive: true,
1000
+ method: "POST"
1001
+ }).catch(() => {});
1002
+ };
1003
+ const unsubscribeConnection = connection.subscribe((message) => {
490
1004
  const action = serverMessageToAction(message);
491
1005
  if (action) {
492
1006
  store.dispatch(action);
1007
+ if (message.type === "connection") {
1008
+ reportReconnect();
1009
+ }
493
1010
  notify();
494
1011
  }
495
1012
  });
496
1013
  return {
1014
+ callControl(message) {
1015
+ connection.callControl(message);
1016
+ },
497
1017
  close() {
498
1018
  unsubscribeConnection();
1019
+ browserMediaReporter?.close();
499
1020
  connection.close();
500
1021
  store.dispatch({ type: "disconnected" });
501
1022
  notify();
@@ -518,10 +1039,16 @@ var createVoiceStream = (path, options = {}) => {
518
1039
  get scenarioId() {
519
1040
  return store.getSnapshot().scenarioId;
520
1041
  },
1042
+ get sessionMetadata() {
1043
+ return store.getSnapshot().sessionMetadata;
1044
+ },
521
1045
  start,
522
1046
  get partial() {
523
1047
  return store.getSnapshot().partial;
524
1048
  },
1049
+ get reconnect() {
1050
+ return store.getSnapshot().reconnect;
1051
+ },
525
1052
  get sessionId() {
526
1053
  return connection.getSessionId();
527
1054
  },
@@ -537,9 +1064,15 @@ var createVoiceStream = (path, options = {}) => {
537
1064
  get assistantAudio() {
538
1065
  return store.getSnapshot().assistantAudio;
539
1066
  },
1067
+ get call() {
1068
+ return store.getSnapshot().call;
1069
+ },
540
1070
  sendAudio(audio) {
541
1071
  connection.sendAudio(audio);
542
1072
  },
1073
+ simulateDisconnect() {
1074
+ connection.simulateDisconnect();
1075
+ },
543
1076
  subscribe(subscriber) {
544
1077
  subscribers.add(subscriber);
545
1078
  return () => {
@@ -549,202 +1082,6 @@ var createVoiceStream = (path, options = {}) => {
549
1082
  };
550
1083
  };
551
1084
 
552
- // src/angular/voice-stream.service.ts
553
- var _dec = [
554
- Injectable({ providedIn: "root" })
555
- ];
556
- var _init = __decoratorStart(undefined);
557
-
558
- class VoiceStreamService {
559
- connect(path, options = {}) {
560
- const stream = createVoiceStream(path, options);
561
- const assistantAudioSignal = signal([]);
562
- const assistantTextsSignal = signal([]);
563
- const errorSignal = signal(null);
564
- const isConnectedSignal = signal(false);
565
- const partialSignal = signal("");
566
- const sessionIdSignal = signal(stream.sessionId);
567
- const statusSignal = signal(stream.status);
568
- const turnsSignal = signal([]);
569
- const sync = () => {
570
- assistantAudioSignal.set([...stream.assistantAudio]);
571
- assistantTextsSignal.set([...stream.assistantTexts]);
572
- errorSignal.set(stream.error);
573
- isConnectedSignal.set(stream.isConnected);
574
- partialSignal.set(stream.partial);
575
- sessionIdSignal.set(stream.sessionId);
576
- statusSignal.set(stream.status);
577
- turnsSignal.set([...stream.turns]);
578
- };
579
- const unsubscribe = stream.subscribe(sync);
580
- sync();
581
- return {
582
- assistantAudio: computed(() => assistantAudioSignal()),
583
- assistantTexts: computed(() => assistantTextsSignal()),
584
- close: () => {
585
- unsubscribe();
586
- stream.close();
587
- },
588
- endTurn: () => stream.endTurn(),
589
- error: computed(() => errorSignal()),
590
- isConnected: computed(() => isConnectedSignal()),
591
- partial: computed(() => partialSignal()),
592
- sendAudio: (audio) => stream.sendAudio(audio),
593
- sessionId: computed(() => sessionIdSignal()),
594
- status: computed(() => statusSignal()),
595
- turns: computed(() => turnsSignal())
596
- };
597
- }
598
- }
599
- VoiceStreamService = __decorateElement(_init, 0, "VoiceStreamService", _dec, VoiceStreamService);
600
- __runInitializers(_init, 1, VoiceStreamService);
601
- __decoratorMetadata(_init, VoiceStreamService);
602
- let _VoiceStreamService = VoiceStreamService;
603
- // src/angular/voice-controller.service.ts
604
- import { computed as computed2, Injectable as Injectable2, signal as signal2 } from "@angular/core";
605
-
606
- // src/client/htmx.ts
607
- var DEFAULT_EVENT_NAME = "voice-refresh";
608
- var DEFAULT_QUERY_PARAM = "sessionId";
609
- var resolveElement = (input) => {
610
- if (typeof input !== "string") {
611
- return input;
612
- }
613
- return document.querySelector(input);
614
- };
615
- var buildRoute = (element, route, queryParam, sessionId) => {
616
- const baseRoute = route ?? element.getAttribute("hx-get") ?? "";
617
- if (!baseRoute) {
618
- return "";
619
- }
620
- const url = new URL(baseRoute, window.location.origin);
621
- if (sessionId) {
622
- url.searchParams.set(queryParam, sessionId);
623
- } else {
624
- url.searchParams.delete(queryParam);
625
- }
626
- return `${url.pathname}${url.search}${url.hash}`;
627
- };
628
- var bindVoiceHTMX = (stream, options) => {
629
- if (typeof window === "undefined" || typeof document === "undefined") {
630
- return () => {};
631
- }
632
- const element = resolveElement(options.element);
633
- if (!element) {
634
- return () => {};
635
- }
636
- const eventName = options.eventName ?? DEFAULT_EVENT_NAME;
637
- const queryParam = options.sessionQueryParam ?? DEFAULT_QUERY_PARAM;
638
- const sync = () => {
639
- const htmxWindow = window;
640
- const nextRoute = buildRoute(element, options.route, queryParam, stream.sessionId);
641
- if (nextRoute) {
642
- element.setAttribute("hx-get", nextRoute);
643
- }
644
- htmxWindow.htmx?.process?.(element);
645
- htmxWindow.htmx?.trigger?.(element, eventName);
646
- };
647
- const unsubscribe = stream.subscribe(sync);
648
- sync();
649
- return () => {
650
- unsubscribe();
651
- };
652
- };
653
-
654
- // src/client/microphone.ts
655
- var clampSample = (value) => Math.max(-1, Math.min(1, value));
656
- var floatTo16BitPCM = (input) => {
657
- const output = new Int16Array(input.length);
658
- for (let index = 0;index < input.length; index += 1) {
659
- const sample = clampSample(input[index] ?? 0);
660
- output[index] = sample < 0 ? sample * 32768 : sample * 32767;
661
- }
662
- return new Uint8Array(output.buffer);
663
- };
664
- var getPcmLevel = (audio) => {
665
- const bytes = audio instanceof Uint8Array ? audio : new Uint8Array(audio);
666
- if (bytes.byteLength < 2) {
667
- return 0;
668
- }
669
- const samples = new Int16Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 2));
670
- if (samples.length === 0) {
671
- return 0;
672
- }
673
- let sumSquares = 0;
674
- for (const sample of samples) {
675
- const normalized = sample / 32768;
676
- sumSquares += normalized * normalized;
677
- }
678
- return Math.min(1, Math.max(0, Math.sqrt(sumSquares / samples.length) * 5.5));
679
- };
680
- var downsampleBuffer = (input, sourceRate, targetRate) => {
681
- if (sourceRate === targetRate) {
682
- return input;
683
- }
684
- const ratio = sourceRate / targetRate;
685
- const length = Math.round(input.length / ratio);
686
- const output = new Float32Array(length);
687
- let offsetResult = 0;
688
- let offsetBuffer = 0;
689
- while (offsetResult < output.length) {
690
- const nextOffsetBuffer = Math.round((offsetResult + 1) * ratio);
691
- let accum = 0;
692
- let count = 0;
693
- for (let index = offsetBuffer;index < nextOffsetBuffer && index < input.length; index += 1) {
694
- accum += input[index] ?? 0;
695
- count += 1;
696
- }
697
- output[offsetResult] = count > 0 ? accum / count : 0;
698
- offsetResult += 1;
699
- offsetBuffer = nextOffsetBuffer;
700
- }
701
- return output;
702
- };
703
- var createMicrophoneCapture = (options) => {
704
- let audioContext = null;
705
- let sourceNode = null;
706
- let processorNode = null;
707
- let mediaStream = null;
708
- const start = async () => {
709
- if (typeof navigator === "undefined" || !navigator.mediaDevices?.getUserMedia) {
710
- throw new Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");
711
- }
712
- const AudioContextCtor = (typeof window !== "undefined" ? window.AudioContext ?? window.webkitAudioContext : undefined) ?? AudioContext;
713
- if (!AudioContextCtor) {
714
- throw new Error("Browser microphone capture requires AudioContext support.");
715
- }
716
- mediaStream = await navigator.mediaDevices.getUserMedia({
717
- audio: {
718
- channelCount: options.channelCount ?? 1
719
- }
720
- });
721
- audioContext = new AudioContextCtor;
722
- sourceNode = audioContext.createMediaStreamSource(mediaStream);
723
- processorNode = audioContext.createScriptProcessor(4096, 1, 1);
724
- processorNode.onaudioprocess = (event) => {
725
- const channel = event.inputBuffer.getChannelData(0);
726
- const downsampled = downsampleBuffer(channel, audioContext?.sampleRate ?? 48000, options.sampleRateHz ?? 16000);
727
- const pcm = floatTo16BitPCM(downsampled);
728
- options.onLevel?.(getPcmLevel(pcm));
729
- options.onAudio(pcm);
730
- };
731
- sourceNode.connect(processorNode);
732
- processorNode.connect(audioContext.destination);
733
- };
734
- const stop = () => {
735
- processorNode?.disconnect();
736
- sourceNode?.disconnect();
737
- mediaStream?.getTracks().forEach((track) => track.stop());
738
- audioContext?.close();
739
- options.onLevel?.(0);
740
- audioContext = null;
741
- mediaStream = null;
742
- processorNode = null;
743
- sourceNode = null;
744
- };
745
- return { start, stop };
746
- };
747
-
748
1085
  // src/audioConditioning.ts
749
1086
  var DEFAULT_TARGET_LEVEL = 0.08;
750
1087
  var DEFAULT_MAX_GAIN = 3;
@@ -1065,12 +1402,15 @@ var resolveVoiceRuntimePreset = (name = "default") => {
1065
1402
  var createInitialState2 = (stream) => ({
1066
1403
  assistantAudio: [...stream.assistantAudio],
1067
1404
  assistantTexts: [...stream.assistantTexts],
1405
+ call: stream.call,
1068
1406
  error: stream.error,
1069
1407
  isConnected: stream.isConnected,
1070
1408
  isRecording: false,
1071
1409
  partial: stream.partial,
1410
+ reconnect: stream.reconnect,
1072
1411
  recordingError: null,
1073
1412
  sessionId: stream.sessionId,
1413
+ sessionMetadata: stream.sessionMetadata,
1074
1414
  scenarioId: stream.scenarioId,
1075
1415
  status: stream.status,
1076
1416
  turns: [...stream.turns]
@@ -1094,10 +1434,13 @@ var createVoiceController = (path, options = {}) => {
1094
1434
  ...state,
1095
1435
  assistantAudio: [...stream.assistantAudio],
1096
1436
  assistantTexts: [...stream.assistantTexts],
1437
+ call: stream.call,
1097
1438
  error: stream.error,
1098
1439
  isConnected: stream.isConnected,
1099
1440
  partial: stream.partial,
1441
+ reconnect: stream.reconnect,
1100
1442
  sessionId: stream.sessionId,
1443
+ sessionMetadata: stream.sessionMetadata,
1101
1444
  scenarioId: stream.scenarioId,
1102
1445
  status: stream.status,
1103
1446
  turns: [...stream.turns]
@@ -1121,7 +1464,13 @@ var createVoiceController = (path, options = {}) => {
1121
1464
  capture = createMicrophoneCapture({
1122
1465
  channelCount: options.capture?.channelCount ?? preset.capture.channelCount,
1123
1466
  onLevel: options.capture?.onLevel,
1124
- onAudio: (audio) => stream.sendAudio(audio),
1467
+ onAudio: (audio) => {
1468
+ if (options.capture?.onAudio) {
1469
+ options.capture.onAudio(audio, stream.sendAudio);
1470
+ return;
1471
+ }
1472
+ stream.sendAudio(audio);
1473
+ },
1125
1474
  sampleRateHz: options.capture?.sampleRateHz ?? preset.capture.sampleRateHz
1126
1475
  });
1127
1476
  return capture;
@@ -1171,6 +1520,7 @@ var createVoiceController = (path, options = {}) => {
1171
1520
  bindHTMX(bindingOptions) {
1172
1521
  return bindVoiceHTMX(stream, bindingOptions);
1173
1522
  },
1523
+ callControl: (message) => stream.callControl(message),
1174
1524
  close,
1175
1525
  endTurn: () => stream.endTurn(),
1176
1526
  get error() {
@@ -1190,10 +1540,17 @@ var createVoiceController = (path, options = {}) => {
1190
1540
  get recordingError() {
1191
1541
  return state.recordingError;
1192
1542
  },
1543
+ get reconnect() {
1544
+ return state.reconnect;
1545
+ },
1193
1546
  sendAudio: (audio) => stream.sendAudio(audio),
1547
+ simulateDisconnect: () => stream.simulateDisconnect(),
1194
1548
  get sessionId() {
1195
1549
  return state.sessionId;
1196
1550
  },
1551
+ get sessionMetadata() {
1552
+ return state.sessionMetadata;
1553
+ },
1197
1554
  get scenarioId() {
1198
1555
  return state.scenarioId;
1199
1556
  },
@@ -1223,72 +1580,3172 @@ var createVoiceController = (path, options = {}) => {
1223
1580
  },
1224
1581
  get assistantAudio() {
1225
1582
  return state.assistantAudio;
1583
+ },
1584
+ get call() {
1585
+ return state.call;
1226
1586
  }
1227
1587
  };
1228
1588
  };
1229
1589
 
1230
- // src/angular/voice-controller.service.ts
1590
+ // src/agentState.ts
1591
+ var deriveVoiceAgentUIState = (input) => {
1592
+ if (!input.isConnected) {
1593
+ return "idle";
1594
+ }
1595
+ if (input.isPlaying) {
1596
+ return "speaking";
1597
+ }
1598
+ if (input.isRecording && input.hasActivePartial) {
1599
+ return "listening";
1600
+ }
1601
+ if (input.isRecording) {
1602
+ return "listening";
1603
+ }
1604
+ if (input.lastTranscriptAt && !input.lastAssistantAt) {
1605
+ return "thinking";
1606
+ }
1607
+ if (input.lastTranscriptAt && input.lastAssistantAt && input.lastTranscriptAt > input.lastAssistantAt) {
1608
+ return "thinking";
1609
+ }
1610
+ return "idle";
1611
+ };
1612
+ var describeVoiceAgentUIState = (state) => {
1613
+ switch (state) {
1614
+ case "idle":
1615
+ return "Idle";
1616
+ case "listening":
1617
+ return "Listening";
1618
+ case "speaking":
1619
+ return "Speaking";
1620
+ case "thinking":
1621
+ return "Thinking";
1622
+ }
1623
+ };
1624
+ var voiceAgentUIStateOrder = [
1625
+ "idle",
1626
+ "listening",
1627
+ "thinking",
1628
+ "speaking"
1629
+ ];
1630
+
1631
+ // src/client/voiceWidgetView.ts
1632
+ var DEFAULT_VOICE_WIDGET_THEME = {
1633
+ accent: "#3b82f6",
1634
+ background: "#0f172a",
1635
+ errorAccent: "#ef4444",
1636
+ fontFamily: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
1637
+ foreground: "#f8fafc",
1638
+ radius: 16
1639
+ };
1640
+ var DEFAULT_VOICE_WIDGET_LABELS = {
1641
+ callEnded: "Call ended",
1642
+ connecting: "Connecting\u2026",
1643
+ endCall: "End call",
1644
+ idle: "Idle",
1645
+ listening: "Listening",
1646
+ mute: "Mute",
1647
+ speaking: "Speaking",
1648
+ startCall: "Start call",
1649
+ thinking: "Thinking",
1650
+ unmute: "Unmute"
1651
+ };
1652
+ var stateLabel = (state, labels) => {
1653
+ switch (state) {
1654
+ case "listening":
1655
+ return labels.listening;
1656
+ case "speaking":
1657
+ return labels.speaking;
1658
+ case "thinking":
1659
+ return labels.thinking;
1660
+ case "idle":
1661
+ return labels.idle;
1662
+ }
1663
+ };
1664
+ var createVoiceWidgetViewModel = (input) => {
1665
+ const theme = { ...DEFAULT_VOICE_WIDGET_THEME, ...input.theme };
1666
+ const labels = { ...DEFAULT_VOICE_WIDGET_LABELS, ...input.labels };
1667
+ const lastAssistantAt = input.state.assistantAudio.at(-1)?.receivedAt;
1668
+ const lastTranscriptAt = input.state.turns.at(-1)?.committedAt;
1669
+ const agentState = deriveVoiceAgentUIState({
1670
+ hasActivePartial: input.state.partial.length > 0,
1671
+ isConnected: input.state.isConnected,
1672
+ isPlaying: false,
1673
+ isRecording: input.state.isRecording,
1674
+ lastAssistantAt,
1675
+ lastTranscriptAt
1676
+ });
1677
+ const connecting = !input.state.isConnected && input.state.status !== "idle" && !input.state.error;
1678
+ const statusLabel = input.state.error ? "Error" : connecting ? labels.connecting : input.state.status === "completed" ? labels.callEnded : stateLabel(agentState, labels);
1679
+ return {
1680
+ agentState,
1681
+ classes: {
1682
+ container: `absolute-voice-widget absolute-voice-widget--${agentState}`,
1683
+ dot: `absolute-voice-widget__dot${input.state.error ? " absolute-voice-widget__dot--error" : ""}`
1684
+ },
1685
+ controls: {
1686
+ canEnd: input.state.isConnected,
1687
+ canMute: input.state.isRecording,
1688
+ canStart: !input.state.isRecording && input.state.status !== "completed"
1689
+ },
1690
+ errorMessage: input.state.error ?? undefined,
1691
+ labels,
1692
+ partial: input.state.partial || undefined,
1693
+ statusLabel,
1694
+ theme,
1695
+ title: input.title ?? "Voice"
1696
+ };
1697
+ };
1698
+ var escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1699
+ var resolveRadius = (radius) => typeof radius === "number" ? `${radius}px` : radius;
1700
+ var renderVoiceWidgetHTML = (model) => {
1701
+ const t = model.theme;
1702
+ const containerStyle = `background:${t.background};border-radius:${resolveRadius(t.radius)};color:${t.foreground};font-family:${t.fontFamily};min-width:240px;padding:20px 22px;`;
1703
+ const dotStyle = `background:${model.errorMessage ? t.errorAccent : model.agentState === "idle" ? "rgba(148,163,184,0.6)" : t.accent};border-radius:50%;height:10px;width:10px;`;
1704
+ const buttons = [];
1705
+ if (model.controls.canStart) {
1706
+ buttons.push(`<button type="button" data-action="start" style="background:${t.accent};border:none;border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${escapeHtml(model.labels.startCall)}</button>`);
1707
+ }
1708
+ if (model.controls.canMute) {
1709
+ buttons.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${escapeHtml(model.labels.mute)}</button>`);
1710
+ }
1711
+ if (model.controls.canEnd) {
1712
+ buttons.push(`<button type="button" data-action="end" style="background:${t.errorAccent};border:none;border-radius:12px;color:${t.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${escapeHtml(model.labels.endCall)}</button>`);
1713
+ }
1714
+ return `<div role="region" aria-live="polite" data-agent-state="${model.agentState}" class="${escapeHtml(model.classes.container)}" style="${containerStyle}">
1715
+ <div style="align-items:center;display:flex;gap:10px;margin-bottom:12px;">
1716
+ <span aria-hidden="true" class="${escapeHtml(model.classes.dot)}" style="${dotStyle}"></span>
1717
+ <strong style="font-size:15px;">${escapeHtml(model.title)}</strong>
1718
+ <span style="font-size:13px;margin-left:auto;opacity:0.7;">${escapeHtml(model.statusLabel)}</span>
1719
+ </div>
1720
+ ${model.partial ? `<p style="font-size:13px;margin:8px 0 12px;opacity:0.85;word-break:break-word;">\u201C${escapeHtml(model.partial)}\u201D</p>` : ""}
1721
+ <div style="display:flex;gap:10px;">${buttons.join("")}</div>
1722
+ ${model.errorMessage ? `<p style="color:${t.errorAccent};font-size:12px;margin-top:12px;">${escapeHtml(model.errorMessage)}</p>` : ""}
1723
+ </div>`;
1724
+ };
1725
+
1726
+ // src/angular/voice-widget.service.ts
1231
1727
  var _dec = [
1232
1728
  Injectable2({ providedIn: "root" })
1233
1729
  ];
1234
1730
  var _init = __decoratorStart(undefined);
1235
1731
 
1236
- class VoiceControllerService {
1732
+ class VoiceWidgetService {
1237
1733
  connect(path, options = {}) {
1238
1734
  const controller = createVoiceController(path, options);
1239
- const assistantAudioSignal = signal2([]);
1240
- const assistantTextsSignal = signal2([]);
1241
- const errorSignal = signal2(null);
1242
- const isConnectedSignal = signal2(false);
1243
- const isRecordingSignal = signal2(false);
1244
- const partialSignal = signal2("");
1245
- const recordingErrorSignal = signal2(null);
1246
- const sessionIdSignal = signal2(controller.sessionId);
1247
- const statusSignal = signal2(controller.status);
1248
- const turnsSignal = signal2([]);
1735
+ const viewModelSignal = signal2(createVoiceWidgetViewModel({
1736
+ labels: options.labels,
1737
+ state: controller.getSnapshot(),
1738
+ theme: options.theme,
1739
+ title: options.title
1740
+ }));
1249
1741
  const sync = () => {
1250
- assistantAudioSignal.set([...controller.assistantAudio]);
1251
- assistantTextsSignal.set([...controller.assistantTexts]);
1252
- errorSignal.set(controller.error);
1253
- isConnectedSignal.set(controller.isConnected);
1254
- isRecordingSignal.set(controller.isRecording);
1255
- partialSignal.set(controller.partial);
1256
- recordingErrorSignal.set(controller.recordingError);
1257
- sessionIdSignal.set(controller.sessionId);
1258
- statusSignal.set(controller.status);
1259
- turnsSignal.set([...controller.turns]);
1742
+ viewModelSignal.set(createVoiceWidgetViewModel({
1743
+ labels: options.labels,
1744
+ state: controller.getSnapshot(),
1745
+ theme: options.theme,
1746
+ title: options.title
1747
+ }));
1260
1748
  };
1261
1749
  const unsubscribe = controller.subscribe(sync);
1262
1750
  sync();
1263
1751
  return {
1264
- assistantAudio: computed2(() => assistantAudioSignal()),
1265
- assistantTexts: computed2(() => assistantTextsSignal()),
1266
- bindHTMX: controller.bindHTMX,
1267
1752
  close: () => {
1268
1753
  unsubscribe();
1269
1754
  controller.close();
1270
1755
  },
1271
- endTurn: () => controller.endTurn(),
1272
- error: computed2(() => errorSignal()),
1273
- isConnected: computed2(() => isConnectedSignal()),
1274
- isRecording: computed2(() => isRecordingSignal()),
1275
- partial: computed2(() => partialSignal()),
1276
- recordingError: computed2(() => recordingErrorSignal()),
1277
- sendAudio: (audio) => controller.sendAudio(audio),
1278
- sessionId: computed2(() => sessionIdSignal()),
1279
- startRecording: () => controller.startRecording(),
1280
- status: computed2(() => statusSignal()),
1281
- stopRecording: () => controller.stopRecording(),
1282
- toggleRecording: () => controller.toggleRecording(),
1283
- turns: computed2(() => turnsSignal())
1756
+ endCall: () => controller.close(),
1757
+ getHTML: () => renderVoiceWidgetHTML(viewModelSignal()),
1758
+ mute: () => controller.stopRecording(),
1759
+ startCall: () => controller.startRecording(),
1760
+ unmute: () => controller.startRecording(),
1761
+ viewModel: computed2(() => viewModelSignal())
1284
1762
  };
1285
1763
  }
1286
1764
  }
1287
- VoiceControllerService = __decorateElement(_init, 0, "VoiceControllerService", _dec, VoiceControllerService);
1288
- __runInitializers(_init, 1, VoiceControllerService);
1289
- __decoratorMetadata(_init, VoiceControllerService);
1290
- let _VoiceControllerService = VoiceControllerService;
1765
+ VoiceWidgetService = __decorateElement(_init, 0, "VoiceWidgetService", _dec, VoiceWidgetService);
1766
+ __runInitializers(_init, 1, VoiceWidgetService);
1767
+ __decoratorMetadata(_init, VoiceWidgetService);
1768
+ let _VoiceWidgetService = VoiceWidgetService;
1769
+ // src/angular/voice-platform-coverage.service.ts
1770
+ import { computed as computed3, Injectable as Injectable3, signal as signal3 } from "@angular/core";
1771
+
1772
+ // src/client/platformCoverage.ts
1773
+ var fetchVoicePlatformCoverage = async (path = "/api/voice/platform-coverage", options = {}) => {
1774
+ const fetchImpl = options.fetch ?? globalThis.fetch;
1775
+ const response = await fetchImpl(path);
1776
+ if (!response.ok) {
1777
+ throw new Error(`Voice platform coverage failed: HTTP ${response.status}`);
1778
+ }
1779
+ return await response.json();
1780
+ };
1781
+ var createVoicePlatformCoverageStore = (path = "/api/voice/platform-coverage", options = {}) => {
1782
+ const listeners = new Set;
1783
+ let closed = false;
1784
+ let timer;
1785
+ let snapshot = {
1786
+ error: null,
1787
+ isLoading: false
1788
+ };
1789
+ const emit = () => {
1790
+ for (const listener of listeners) {
1791
+ listener();
1792
+ }
1793
+ };
1794
+ const refresh = async () => {
1795
+ if (closed) {
1796
+ return snapshot.report;
1797
+ }
1798
+ snapshot = {
1799
+ ...snapshot,
1800
+ error: null,
1801
+ isLoading: true
1802
+ };
1803
+ emit();
1804
+ try {
1805
+ const report = await fetchVoicePlatformCoverage(path, options);
1806
+ snapshot = {
1807
+ error: null,
1808
+ isLoading: false,
1809
+ report,
1810
+ updatedAt: Date.now()
1811
+ };
1812
+ emit();
1813
+ return report;
1814
+ } catch (error) {
1815
+ snapshot = {
1816
+ ...snapshot,
1817
+ error: error instanceof Error ? error.message : String(error),
1818
+ isLoading: false
1819
+ };
1820
+ emit();
1821
+ throw error;
1822
+ }
1823
+ };
1824
+ const close = () => {
1825
+ closed = true;
1826
+ if (timer) {
1827
+ clearInterval(timer);
1828
+ timer = undefined;
1829
+ }
1830
+ listeners.clear();
1831
+ };
1832
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
1833
+ timer = setInterval(() => {
1834
+ refresh().catch(() => {});
1835
+ }, options.intervalMs);
1836
+ }
1837
+ return {
1838
+ close,
1839
+ getServerSnapshot: () => snapshot,
1840
+ getSnapshot: () => snapshot,
1841
+ refresh,
1842
+ subscribe: (listener) => {
1843
+ listeners.add(listener);
1844
+ return () => {
1845
+ listeners.delete(listener);
1846
+ };
1847
+ }
1848
+ };
1849
+ };
1850
+
1851
+ // src/angular/voice-platform-coverage.service.ts
1852
+ var _dec = [
1853
+ Injectable3({ providedIn: "root" })
1854
+ ];
1855
+ var _init = __decoratorStart(undefined);
1856
+
1857
+ class VoicePlatformCoverageService {
1858
+ connect(path = "/api/voice/platform-coverage", options = {}) {
1859
+ const store = createVoicePlatformCoverageStore(path, options);
1860
+ const errorSignal = signal3(null);
1861
+ const isLoadingSignal = signal3(false);
1862
+ const reportSignal = signal3(undefined);
1863
+ const updatedAtSignal = signal3(undefined);
1864
+ const sync = () => {
1865
+ const snapshot = store.getSnapshot();
1866
+ errorSignal.set(snapshot.error);
1867
+ isLoadingSignal.set(snapshot.isLoading);
1868
+ reportSignal.set(snapshot.report);
1869
+ updatedAtSignal.set(snapshot.updatedAt);
1870
+ };
1871
+ const unsubscribe = store.subscribe(sync);
1872
+ sync();
1873
+ if (typeof window !== "undefined") {
1874
+ store.refresh().catch(() => {});
1875
+ }
1876
+ return {
1877
+ close: () => {
1878
+ unsubscribe();
1879
+ store.close();
1880
+ },
1881
+ error: computed3(() => errorSignal()),
1882
+ isLoading: computed3(() => isLoadingSignal()),
1883
+ refresh: store.refresh,
1884
+ report: computed3(() => reportSignal()),
1885
+ updatedAt: computed3(() => updatedAtSignal())
1886
+ };
1887
+ }
1888
+ }
1889
+ VoicePlatformCoverageService = __decorateElement(_init, 0, "VoicePlatformCoverageService", _dec, VoicePlatformCoverageService);
1890
+ __runInitializers(_init, 1, VoicePlatformCoverageService);
1891
+ __decoratorMetadata(_init, VoicePlatformCoverageService);
1892
+ let _VoicePlatformCoverageService = VoicePlatformCoverageService;
1893
+ // src/angular/voice-proof-trends.service.ts
1894
+ import { computed as computed4, Injectable as Injectable4, signal as signal4 } from "@angular/core";
1895
+
1896
+ // src/client/proofTrends.ts
1897
+ var fetchVoiceProofTrends = async (path = "/api/voice/proof-trends", options = {}) => {
1898
+ const fetchImpl = options.fetch ?? globalThis.fetch;
1899
+ const response = await fetchImpl(path);
1900
+ if (!response.ok) {
1901
+ throw new Error(`Voice proof trends failed: HTTP ${response.status}`);
1902
+ }
1903
+ return await response.json();
1904
+ };
1905
+ var createVoiceProofTrendsStore = (path = "/api/voice/proof-trends", options = {}) => {
1906
+ const listeners = new Set;
1907
+ let closed = false;
1908
+ let timer;
1909
+ let snapshot = {
1910
+ error: null,
1911
+ isLoading: false
1912
+ };
1913
+ const emit = () => {
1914
+ for (const listener of listeners) {
1915
+ listener();
1916
+ }
1917
+ };
1918
+ const refresh = async () => {
1919
+ if (closed) {
1920
+ return snapshot.report;
1921
+ }
1922
+ snapshot = {
1923
+ ...snapshot,
1924
+ error: null,
1925
+ isLoading: true
1926
+ };
1927
+ emit();
1928
+ try {
1929
+ const report = await fetchVoiceProofTrends(path, options);
1930
+ snapshot = {
1931
+ error: null,
1932
+ isLoading: false,
1933
+ report,
1934
+ updatedAt: Date.now()
1935
+ };
1936
+ emit();
1937
+ return report;
1938
+ } catch (error) {
1939
+ snapshot = {
1940
+ ...snapshot,
1941
+ error: error instanceof Error ? error.message : String(error),
1942
+ isLoading: false
1943
+ };
1944
+ emit();
1945
+ throw error;
1946
+ }
1947
+ };
1948
+ const close = () => {
1949
+ closed = true;
1950
+ if (timer) {
1951
+ clearInterval(timer);
1952
+ timer = undefined;
1953
+ }
1954
+ listeners.clear();
1955
+ };
1956
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
1957
+ timer = setInterval(() => {
1958
+ refresh().catch(() => {});
1959
+ }, options.intervalMs);
1960
+ }
1961
+ return {
1962
+ close,
1963
+ getServerSnapshot: () => snapshot,
1964
+ getSnapshot: () => snapshot,
1965
+ refresh,
1966
+ subscribe: (listener) => {
1967
+ listeners.add(listener);
1968
+ return () => {
1969
+ listeners.delete(listener);
1970
+ };
1971
+ }
1972
+ };
1973
+ };
1974
+
1975
+ // src/angular/voice-proof-trends.service.ts
1976
+ var _dec = [
1977
+ Injectable4({ providedIn: "root" })
1978
+ ];
1979
+ var _init = __decoratorStart(undefined);
1980
+
1981
+ class VoiceProofTrendsService {
1982
+ connect(path = "/api/voice/proof-trends", options = {}) {
1983
+ const store = createVoiceProofTrendsStore(path, options);
1984
+ const errorSignal = signal4(null);
1985
+ const isLoadingSignal = signal4(false);
1986
+ const reportSignal = signal4(undefined);
1987
+ const updatedAtSignal = signal4(undefined);
1988
+ const sync = () => {
1989
+ const snapshot = store.getSnapshot();
1990
+ errorSignal.set(snapshot.error);
1991
+ isLoadingSignal.set(snapshot.isLoading);
1992
+ reportSignal.set(snapshot.report);
1993
+ updatedAtSignal.set(snapshot.updatedAt);
1994
+ };
1995
+ const unsubscribe = store.subscribe(sync);
1996
+ sync();
1997
+ if (typeof window !== "undefined") {
1998
+ store.refresh().catch(() => {});
1999
+ }
2000
+ return {
2001
+ close: () => {
2002
+ unsubscribe();
2003
+ store.close();
2004
+ },
2005
+ error: computed4(() => errorSignal()),
2006
+ isLoading: computed4(() => isLoadingSignal()),
2007
+ refresh: store.refresh,
2008
+ report: computed4(() => reportSignal()),
2009
+ updatedAt: computed4(() => updatedAtSignal())
2010
+ };
2011
+ }
2012
+ }
2013
+ VoiceProofTrendsService = __decorateElement(_init, 0, "VoiceProofTrendsService", _dec, VoiceProofTrendsService);
2014
+ __runInitializers(_init, 1, VoiceProofTrendsService);
2015
+ __decoratorMetadata(_init, VoiceProofTrendsService);
2016
+ let _VoiceProofTrendsService = VoiceProofTrendsService;
2017
+ // src/angular/voice-reconnect-profile-evidence.service.ts
2018
+ import { computed as computed5, Injectable as Injectable5, signal as signal5 } from "@angular/core";
2019
+
2020
+ // src/client/reconnectProfileEvidence.ts
2021
+ var fetchVoiceReconnectProfileEvidence = async (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
2022
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2023
+ const response = await fetchImpl(path);
2024
+ if (!response.ok) {
2025
+ throw new Error(`Voice reconnect profile evidence failed: HTTP ${response.status}`);
2026
+ }
2027
+ return await response.json();
2028
+ };
2029
+ var createVoiceReconnectProfileEvidenceStore = (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
2030
+ const listeners = new Set;
2031
+ let closed = false;
2032
+ let timer;
2033
+ let snapshot = {
2034
+ error: null,
2035
+ isLoading: false
2036
+ };
2037
+ const emit = () => {
2038
+ for (const listener of listeners) {
2039
+ listener();
2040
+ }
2041
+ };
2042
+ const refresh = async () => {
2043
+ if (closed) {
2044
+ return snapshot.report;
2045
+ }
2046
+ snapshot = { ...snapshot, error: null, isLoading: true };
2047
+ emit();
2048
+ try {
2049
+ const report = await fetchVoiceReconnectProfileEvidence(path, options);
2050
+ snapshot = {
2051
+ error: null,
2052
+ isLoading: false,
2053
+ report,
2054
+ updatedAt: Date.now()
2055
+ };
2056
+ emit();
2057
+ return report;
2058
+ } catch (error) {
2059
+ snapshot = {
2060
+ ...snapshot,
2061
+ error: error instanceof Error ? error.message : String(error),
2062
+ isLoading: false
2063
+ };
2064
+ emit();
2065
+ throw error;
2066
+ }
2067
+ };
2068
+ const close = () => {
2069
+ closed = true;
2070
+ if (timer) {
2071
+ clearInterval(timer);
2072
+ timer = undefined;
2073
+ }
2074
+ listeners.clear();
2075
+ };
2076
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2077
+ timer = setInterval(() => {
2078
+ refresh().catch(() => {});
2079
+ }, options.intervalMs);
2080
+ }
2081
+ return {
2082
+ close,
2083
+ getServerSnapshot: () => snapshot,
2084
+ getSnapshot: () => snapshot,
2085
+ refresh,
2086
+ subscribe: (listener) => {
2087
+ listeners.add(listener);
2088
+ return () => {
2089
+ listeners.delete(listener);
2090
+ };
2091
+ }
2092
+ };
2093
+ };
2094
+
2095
+ // src/angular/voice-reconnect-profile-evidence.service.ts
2096
+ var _dec = [
2097
+ Injectable5({ providedIn: "root" })
2098
+ ];
2099
+ var _init = __decoratorStart(undefined);
2100
+
2101
+ class VoiceReconnectProfileEvidenceService {
2102
+ connect(path = "/api/voice/reconnect-profile-evidence", options = {}) {
2103
+ const store = createVoiceReconnectProfileEvidenceStore(path, options);
2104
+ const errorSignal = signal5(null);
2105
+ const isLoadingSignal = signal5(false);
2106
+ const reportSignal = signal5(undefined);
2107
+ const updatedAtSignal = signal5(undefined);
2108
+ const sync = () => {
2109
+ const snapshot = store.getSnapshot();
2110
+ errorSignal.set(snapshot.error);
2111
+ isLoadingSignal.set(snapshot.isLoading);
2112
+ reportSignal.set(snapshot.report);
2113
+ updatedAtSignal.set(snapshot.updatedAt);
2114
+ };
2115
+ const unsubscribe = store.subscribe(sync);
2116
+ sync();
2117
+ if (typeof window !== "undefined") {
2118
+ store.refresh().catch(() => {});
2119
+ }
2120
+ return {
2121
+ close: () => {
2122
+ unsubscribe();
2123
+ store.close();
2124
+ },
2125
+ error: computed5(() => errorSignal()),
2126
+ isLoading: computed5(() => isLoadingSignal()),
2127
+ refresh: store.refresh,
2128
+ report: computed5(() => reportSignal()),
2129
+ updatedAt: computed5(() => updatedAtSignal())
2130
+ };
2131
+ }
2132
+ }
2133
+ VoiceReconnectProfileEvidenceService = __decorateElement(_init, 0, "VoiceReconnectProfileEvidenceService", _dec, VoiceReconnectProfileEvidenceService);
2134
+ __runInitializers(_init, 1, VoiceReconnectProfileEvidenceService);
2135
+ __decoratorMetadata(_init, VoiceReconnectProfileEvidenceService);
2136
+ let _VoiceReconnectProfileEvidenceService = VoiceReconnectProfileEvidenceService;
2137
+ // src/angular/voice-call-debugger.service.ts
2138
+ import { computed as computed6, Injectable as Injectable6, signal as signal6 } from "@angular/core";
2139
+
2140
+ // src/client/callDebugger.ts
2141
+ var fetchVoiceCallDebugger = async (path, options = {}) => {
2142
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2143
+ const response = await fetchImpl(path);
2144
+ if (!response.ok) {
2145
+ throw new Error(`Voice call debugger failed: HTTP ${response.status}`);
2146
+ }
2147
+ return await response.json();
2148
+ };
2149
+ var createVoiceCallDebuggerStore = (path, options = {}) => {
2150
+ const listeners = new Set;
2151
+ let closed = false;
2152
+ let timer;
2153
+ let snapshot = {
2154
+ error: null,
2155
+ isLoading: false
2156
+ };
2157
+ const emit = () => {
2158
+ for (const listener of listeners) {
2159
+ listener();
2160
+ }
2161
+ };
2162
+ const refresh = async () => {
2163
+ if (closed) {
2164
+ return snapshot.report;
2165
+ }
2166
+ snapshot = { ...snapshot, error: null, isLoading: true };
2167
+ emit();
2168
+ try {
2169
+ const report = await fetchVoiceCallDebugger(path, options);
2170
+ snapshot = {
2171
+ error: null,
2172
+ isLoading: false,
2173
+ report,
2174
+ updatedAt: Date.now()
2175
+ };
2176
+ emit();
2177
+ return report;
2178
+ } catch (error) {
2179
+ snapshot = {
2180
+ ...snapshot,
2181
+ error: error instanceof Error ? error.message : String(error),
2182
+ isLoading: false
2183
+ };
2184
+ emit();
2185
+ throw error;
2186
+ }
2187
+ };
2188
+ const close = () => {
2189
+ closed = true;
2190
+ if (timer) {
2191
+ clearInterval(timer);
2192
+ timer = undefined;
2193
+ }
2194
+ listeners.clear();
2195
+ };
2196
+ if (options.intervalMs && options.intervalMs > 0) {
2197
+ timer = setInterval(() => {
2198
+ refresh().catch(() => {});
2199
+ }, options.intervalMs);
2200
+ }
2201
+ return {
2202
+ close,
2203
+ getServerSnapshot: () => snapshot,
2204
+ getSnapshot: () => snapshot,
2205
+ refresh,
2206
+ subscribe: (listener) => {
2207
+ listeners.add(listener);
2208
+ return () => {
2209
+ listeners.delete(listener);
2210
+ };
2211
+ }
2212
+ };
2213
+ };
2214
+
2215
+ // src/angular/voice-call-debugger.service.ts
2216
+ var _dec = [
2217
+ Injectable6({ providedIn: "root" })
2218
+ ];
2219
+ var _init = __decoratorStart(undefined);
2220
+
2221
+ class VoiceCallDebuggerService {
2222
+ connect(path, options = {}) {
2223
+ const store = createVoiceCallDebuggerStore(path, options);
2224
+ const errorSignal = signal6(null);
2225
+ const isLoadingSignal = signal6(false);
2226
+ const reportSignal = signal6(undefined);
2227
+ const updatedAtSignal = signal6(undefined);
2228
+ const sync = () => {
2229
+ const state = store.getSnapshot();
2230
+ errorSignal.set(state.error);
2231
+ isLoadingSignal.set(state.isLoading);
2232
+ reportSignal.set(state.report);
2233
+ updatedAtSignal.set(state.updatedAt);
2234
+ };
2235
+ const unsubscribe = store.subscribe(sync);
2236
+ sync();
2237
+ store.refresh().catch(() => {});
2238
+ return {
2239
+ close: () => {
2240
+ unsubscribe();
2241
+ store.close();
2242
+ },
2243
+ error: computed6(() => errorSignal()),
2244
+ isLoading: computed6(() => isLoadingSignal()),
2245
+ refresh: store.refresh,
2246
+ report: computed6(() => reportSignal()),
2247
+ updatedAt: computed6(() => updatedAtSignal())
2248
+ };
2249
+ }
2250
+ }
2251
+ VoiceCallDebuggerService = __decorateElement(_init, 0, "VoiceCallDebuggerService", _dec, VoiceCallDebuggerService);
2252
+ __runInitializers(_init, 1, VoiceCallDebuggerService);
2253
+ __decoratorMetadata(_init, VoiceCallDebuggerService);
2254
+ let _VoiceCallDebuggerService = VoiceCallDebuggerService;
2255
+ // src/angular/voice-session-snapshot.service.ts
2256
+ import { computed as computed7, Injectable as Injectable7, signal as signal7 } from "@angular/core";
2257
+
2258
+ // src/client/sessionSnapshot.ts
2259
+ var withTurnId = (path, turnId) => {
2260
+ if (!turnId) {
2261
+ return path;
2262
+ }
2263
+ const url = new URL(path, "http://absolutejs.local");
2264
+ url.searchParams.set("turnId", turnId);
2265
+ return `${url.pathname}${url.search}`;
2266
+ };
2267
+ var fetchVoiceSessionSnapshot = async (path, options = {}) => {
2268
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2269
+ const response = await fetchImpl(withTurnId(path, options.turnId));
2270
+ if (!response.ok) {
2271
+ throw new Error(`Voice session snapshot failed: HTTP ${response.status}`);
2272
+ }
2273
+ return await response.json();
2274
+ };
2275
+ var createVoiceSessionSnapshotStore = (path, options = {}) => {
2276
+ const listeners = new Set;
2277
+ let closed = false;
2278
+ let timer;
2279
+ let snapshot = {
2280
+ error: null,
2281
+ isLoading: false
2282
+ };
2283
+ const emit = () => {
2284
+ for (const listener of listeners) {
2285
+ listener();
2286
+ }
2287
+ };
2288
+ const refresh = async () => {
2289
+ if (closed) {
2290
+ return snapshot.snapshot;
2291
+ }
2292
+ snapshot = { ...snapshot, error: null, isLoading: true };
2293
+ emit();
2294
+ try {
2295
+ const next = await fetchVoiceSessionSnapshot(path, options);
2296
+ snapshot = {
2297
+ error: null,
2298
+ isLoading: false,
2299
+ snapshot: next,
2300
+ updatedAt: Date.now()
2301
+ };
2302
+ emit();
2303
+ return next;
2304
+ } catch (error) {
2305
+ snapshot = {
2306
+ ...snapshot,
2307
+ error: error instanceof Error ? error.message : String(error),
2308
+ isLoading: false
2309
+ };
2310
+ emit();
2311
+ throw error;
2312
+ }
2313
+ };
2314
+ const download = () => {
2315
+ const current = snapshot.snapshot;
2316
+ if (current === undefined) {
2317
+ throw new Error("Voice session snapshot has not been loaded.");
2318
+ }
2319
+ return new Blob([JSON.stringify(current, null, 2)], {
2320
+ type: "application/json"
2321
+ });
2322
+ };
2323
+ const close = () => {
2324
+ closed = true;
2325
+ if (timer) {
2326
+ clearInterval(timer);
2327
+ timer = undefined;
2328
+ }
2329
+ listeners.clear();
2330
+ };
2331
+ if (options.intervalMs && options.intervalMs > 0) {
2332
+ timer = setInterval(() => {
2333
+ refresh().catch(() => {});
2334
+ }, options.intervalMs);
2335
+ }
2336
+ return {
2337
+ close,
2338
+ download,
2339
+ getServerSnapshot: () => snapshot,
2340
+ getSnapshot: () => snapshot,
2341
+ refresh,
2342
+ subscribe: (listener) => {
2343
+ listeners.add(listener);
2344
+ return () => {
2345
+ listeners.delete(listener);
2346
+ };
2347
+ }
2348
+ };
2349
+ };
2350
+
2351
+ // src/angular/voice-session-snapshot.service.ts
2352
+ var _dec = [
2353
+ Injectable7({ providedIn: "root" })
2354
+ ];
2355
+ var _init = __decoratorStart(undefined);
2356
+
2357
+ class VoiceSessionSnapshotService {
2358
+ connect(path, options = {}) {
2359
+ const store = createVoiceSessionSnapshotStore(path, options);
2360
+ const errorSignal = signal7(null);
2361
+ const isLoadingSignal = signal7(false);
2362
+ const snapshotSignal = signal7(undefined);
2363
+ const updatedAtSignal = signal7(undefined);
2364
+ const sync = () => {
2365
+ const state = store.getSnapshot();
2366
+ errorSignal.set(state.error);
2367
+ isLoadingSignal.set(state.isLoading);
2368
+ snapshotSignal.set(state.snapshot);
2369
+ updatedAtSignal.set(state.updatedAt);
2370
+ };
2371
+ const unsubscribe = store.subscribe(sync);
2372
+ sync();
2373
+ store.refresh().catch(() => {});
2374
+ return {
2375
+ close: () => {
2376
+ unsubscribe();
2377
+ store.close();
2378
+ },
2379
+ download: store.download,
2380
+ error: computed7(() => errorSignal()),
2381
+ isLoading: computed7(() => isLoadingSignal()),
2382
+ refresh: store.refresh,
2383
+ snapshot: computed7(() => snapshotSignal()),
2384
+ updatedAt: computed7(() => updatedAtSignal())
2385
+ };
2386
+ }
2387
+ }
2388
+ VoiceSessionSnapshotService = __decorateElement(_init, 0, "VoiceSessionSnapshotService", _dec, VoiceSessionSnapshotService);
2389
+ __runInitializers(_init, 1, VoiceSessionSnapshotService);
2390
+ __decoratorMetadata(_init, VoiceSessionSnapshotService);
2391
+ let _VoiceSessionSnapshotService = VoiceSessionSnapshotService;
2392
+ // src/angular/voice-session-observability.service.ts
2393
+ import { computed as computed8, Injectable as Injectable8, signal as signal8 } from "@angular/core";
2394
+
2395
+ // src/client/sessionObservability.ts
2396
+ var fetchVoiceSessionObservability = async (path, options = {}) => {
2397
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2398
+ const response = await fetchImpl(path);
2399
+ if (!response.ok) {
2400
+ throw new Error(`Voice session observability failed: HTTP ${response.status}`);
2401
+ }
2402
+ return await response.json();
2403
+ };
2404
+ var createVoiceSessionObservabilityStore = (path, options = {}) => {
2405
+ const listeners = new Set;
2406
+ let closed = false;
2407
+ let timer;
2408
+ let snapshot = {
2409
+ error: null,
2410
+ isLoading: false,
2411
+ report: null
2412
+ };
2413
+ const emit = () => {
2414
+ for (const listener of listeners) {
2415
+ listener();
2416
+ }
2417
+ };
2418
+ const refresh = async () => {
2419
+ if (closed) {
2420
+ return snapshot.report;
2421
+ }
2422
+ snapshot = {
2423
+ ...snapshot,
2424
+ error: null,
2425
+ isLoading: true
2426
+ };
2427
+ emit();
2428
+ try {
2429
+ const report = await fetchVoiceSessionObservability(path, options);
2430
+ snapshot = {
2431
+ error: null,
2432
+ isLoading: false,
2433
+ report,
2434
+ updatedAt: Date.now()
2435
+ };
2436
+ emit();
2437
+ return report;
2438
+ } catch (error) {
2439
+ snapshot = {
2440
+ ...snapshot,
2441
+ error: error instanceof Error ? error.message : String(error),
2442
+ isLoading: false
2443
+ };
2444
+ emit();
2445
+ throw error;
2446
+ }
2447
+ };
2448
+ const close = () => {
2449
+ closed = true;
2450
+ if (timer) {
2451
+ clearInterval(timer);
2452
+ timer = undefined;
2453
+ }
2454
+ listeners.clear();
2455
+ };
2456
+ if (options.intervalMs && options.intervalMs > 0) {
2457
+ timer = setInterval(() => {
2458
+ refresh().catch(() => {});
2459
+ }, options.intervalMs);
2460
+ }
2461
+ return {
2462
+ close,
2463
+ getServerSnapshot: () => snapshot,
2464
+ getSnapshot: () => snapshot,
2465
+ refresh,
2466
+ subscribe: (listener) => {
2467
+ listeners.add(listener);
2468
+ return () => {
2469
+ listeners.delete(listener);
2470
+ };
2471
+ }
2472
+ };
2473
+ };
2474
+
2475
+ // src/angular/voice-session-observability.service.ts
2476
+ var _dec = [
2477
+ Injectable8({ providedIn: "root" })
2478
+ ];
2479
+ var _init = __decoratorStart(undefined);
2480
+
2481
+ class VoiceSessionObservabilityService {
2482
+ connect(path = "/api/voice/session-observability/latest", options = {}) {
2483
+ const store = createVoiceSessionObservabilityStore(path, options);
2484
+ const errorSignal = signal8(null);
2485
+ const isLoadingSignal = signal8(false);
2486
+ const reportSignal = signal8(null);
2487
+ const updatedAtSignal = signal8(undefined);
2488
+ const sync = () => {
2489
+ const snapshot = store.getSnapshot();
2490
+ errorSignal.set(snapshot.error);
2491
+ isLoadingSignal.set(snapshot.isLoading);
2492
+ reportSignal.set(snapshot.report);
2493
+ updatedAtSignal.set(snapshot.updatedAt);
2494
+ };
2495
+ const unsubscribe = store.subscribe(sync);
2496
+ sync();
2497
+ store.refresh().catch(() => {});
2498
+ return {
2499
+ close: () => {
2500
+ unsubscribe();
2501
+ store.close();
2502
+ },
2503
+ error: computed8(() => errorSignal()),
2504
+ isLoading: computed8(() => isLoadingSignal()),
2505
+ refresh: store.refresh,
2506
+ report: computed8(() => reportSignal()),
2507
+ updatedAt: computed8(() => updatedAtSignal())
2508
+ };
2509
+ }
2510
+ }
2511
+ VoiceSessionObservabilityService = __decorateElement(_init, 0, "VoiceSessionObservabilityService", _dec, VoiceSessionObservabilityService);
2512
+ __runInitializers(_init, 1, VoiceSessionObservabilityService);
2513
+ __decoratorMetadata(_init, VoiceSessionObservabilityService);
2514
+ let _VoiceSessionObservabilityService = VoiceSessionObservabilityService;
2515
+ // src/angular/voice-profile-comparison.service.ts
2516
+ import { computed as computed9, Injectable as Injectable9, signal as signal9 } from "@angular/core";
2517
+
2518
+ // src/client/profileComparison.ts
2519
+ var fetchVoiceProfileComparison = async (path = "/api/voice/real-call-profile-history", options = {}) => {
2520
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2521
+ const response = await fetchImpl(path);
2522
+ if (!response.ok) {
2523
+ throw new Error(`Voice profile comparison failed: HTTP ${response.status}`);
2524
+ }
2525
+ return await response.json();
2526
+ };
2527
+ var createVoiceProfileComparisonStore = (path = "/api/voice/real-call-profile-history", options = {}) => {
2528
+ const listeners = new Set;
2529
+ let closed = false;
2530
+ let timer;
2531
+ let snapshot = {
2532
+ error: null,
2533
+ isLoading: false
2534
+ };
2535
+ const emit = () => {
2536
+ for (const listener of listeners) {
2537
+ listener();
2538
+ }
2539
+ };
2540
+ const refresh = async () => {
2541
+ if (closed) {
2542
+ return snapshot.report;
2543
+ }
2544
+ snapshot = { ...snapshot, error: null, isLoading: true };
2545
+ emit();
2546
+ try {
2547
+ const report = await fetchVoiceProfileComparison(path, options);
2548
+ snapshot = {
2549
+ error: null,
2550
+ isLoading: false,
2551
+ report,
2552
+ updatedAt: Date.now()
2553
+ };
2554
+ emit();
2555
+ return report;
2556
+ } catch (error) {
2557
+ snapshot = {
2558
+ ...snapshot,
2559
+ error: error instanceof Error ? error.message : String(error),
2560
+ isLoading: false
2561
+ };
2562
+ emit();
2563
+ throw error;
2564
+ }
2565
+ };
2566
+ const close = () => {
2567
+ closed = true;
2568
+ if (timer) {
2569
+ clearInterval(timer);
2570
+ timer = undefined;
2571
+ }
2572
+ listeners.clear();
2573
+ };
2574
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2575
+ timer = setInterval(() => {
2576
+ refresh().catch(() => {});
2577
+ }, options.intervalMs);
2578
+ }
2579
+ return {
2580
+ close,
2581
+ getServerSnapshot: () => snapshot,
2582
+ getSnapshot: () => snapshot,
2583
+ refresh,
2584
+ subscribe: (listener) => {
2585
+ listeners.add(listener);
2586
+ return () => {
2587
+ listeners.delete(listener);
2588
+ };
2589
+ }
2590
+ };
2591
+ };
2592
+
2593
+ // src/angular/voice-profile-comparison.service.ts
2594
+ var _dec = [
2595
+ Injectable9({ providedIn: "root" })
2596
+ ];
2597
+ var _init = __decoratorStart(undefined);
2598
+
2599
+ class VoiceProfileComparisonService {
2600
+ connect(path = "/api/voice/real-call-profile-history", options = {}) {
2601
+ const store = createVoiceProfileComparisonStore(path, options);
2602
+ const errorSignal = signal9(null);
2603
+ const isLoadingSignal = signal9(false);
2604
+ const reportSignal = signal9(undefined);
2605
+ const updatedAtSignal = signal9(undefined);
2606
+ const sync = () => {
2607
+ const snapshot = store.getSnapshot();
2608
+ errorSignal.set(snapshot.error);
2609
+ isLoadingSignal.set(snapshot.isLoading);
2610
+ reportSignal.set(snapshot.report);
2611
+ updatedAtSignal.set(snapshot.updatedAt);
2612
+ };
2613
+ const unsubscribe = store.subscribe(sync);
2614
+ sync();
2615
+ if (typeof window !== "undefined") {
2616
+ store.refresh().catch(() => {});
2617
+ }
2618
+ return {
2619
+ close: () => {
2620
+ unsubscribe();
2621
+ store.close();
2622
+ },
2623
+ error: computed9(() => errorSignal()),
2624
+ isLoading: computed9(() => isLoadingSignal()),
2625
+ refresh: store.refresh,
2626
+ report: computed9(() => reportSignal()),
2627
+ updatedAt: computed9(() => updatedAtSignal())
2628
+ };
2629
+ }
2630
+ }
2631
+ VoiceProfileComparisonService = __decorateElement(_init, 0, "VoiceProfileComparisonService", _dec, VoiceProfileComparisonService);
2632
+ __runInitializers(_init, 1, VoiceProfileComparisonService);
2633
+ __decoratorMetadata(_init, VoiceProfileComparisonService);
2634
+ let _VoiceProfileComparisonService = VoiceProfileComparisonService;
2635
+ // src/angular/voice-readiness-failures.service.ts
2636
+ import { computed as computed10, Injectable as Injectable10, signal as signal10 } from "@angular/core";
2637
+
2638
+ // src/client/readinessFailures.ts
2639
+ var fetchVoiceReadinessFailures = async (path = "/api/production-readiness", options = {}) => {
2640
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2641
+ const response = await fetchImpl(path);
2642
+ if (!response.ok) {
2643
+ throw new Error(`Voice readiness failed: HTTP ${response.status}`);
2644
+ }
2645
+ return await response.json();
2646
+ };
2647
+ var createVoiceReadinessFailuresStore = (path = "/api/production-readiness", options = {}) => {
2648
+ const listeners = new Set;
2649
+ let closed = false;
2650
+ let timer;
2651
+ let snapshot = {
2652
+ error: null,
2653
+ isLoading: false
2654
+ };
2655
+ const emit = () => {
2656
+ for (const listener of listeners) {
2657
+ listener();
2658
+ }
2659
+ };
2660
+ const refresh = async () => {
2661
+ if (closed) {
2662
+ return snapshot.report;
2663
+ }
2664
+ snapshot = { ...snapshot, error: null, isLoading: true };
2665
+ emit();
2666
+ try {
2667
+ const report = await fetchVoiceReadinessFailures(path, options);
2668
+ snapshot = {
2669
+ error: null,
2670
+ isLoading: false,
2671
+ report,
2672
+ updatedAt: Date.now()
2673
+ };
2674
+ emit();
2675
+ return report;
2676
+ } catch (error) {
2677
+ snapshot = {
2678
+ ...snapshot,
2679
+ error: error instanceof Error ? error.message : String(error),
2680
+ isLoading: false
2681
+ };
2682
+ emit();
2683
+ throw error;
2684
+ }
2685
+ };
2686
+ const close = () => {
2687
+ closed = true;
2688
+ if (timer) {
2689
+ clearInterval(timer);
2690
+ timer = undefined;
2691
+ }
2692
+ listeners.clear();
2693
+ };
2694
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2695
+ timer = setInterval(() => {
2696
+ refresh().catch(() => {});
2697
+ }, options.intervalMs);
2698
+ }
2699
+ return {
2700
+ close,
2701
+ getServerSnapshot: () => snapshot,
2702
+ getSnapshot: () => snapshot,
2703
+ refresh,
2704
+ subscribe: (listener) => {
2705
+ listeners.add(listener);
2706
+ return () => {
2707
+ listeners.delete(listener);
2708
+ };
2709
+ }
2710
+ };
2711
+ };
2712
+
2713
+ // src/angular/voice-readiness-failures.service.ts
2714
+ var _dec = [
2715
+ Injectable10({ providedIn: "root" })
2716
+ ];
2717
+ var _init = __decoratorStart(undefined);
2718
+
2719
+ class VoiceReadinessFailuresService {
2720
+ connect(path = "/api/production-readiness", options = {}) {
2721
+ const store = createVoiceReadinessFailuresStore(path, options);
2722
+ const errorSignal = signal10(null);
2723
+ const isLoadingSignal = signal10(false);
2724
+ const reportSignal = signal10(undefined);
2725
+ const updatedAtSignal = signal10(undefined);
2726
+ const sync = () => {
2727
+ const snapshot = store.getSnapshot();
2728
+ errorSignal.set(snapshot.error);
2729
+ isLoadingSignal.set(snapshot.isLoading);
2730
+ reportSignal.set(snapshot.report);
2731
+ updatedAtSignal.set(snapshot.updatedAt);
2732
+ };
2733
+ const unsubscribe = store.subscribe(sync);
2734
+ sync();
2735
+ if (typeof window !== "undefined") {
2736
+ store.refresh().catch(() => {});
2737
+ }
2738
+ return {
2739
+ close: () => {
2740
+ unsubscribe();
2741
+ store.close();
2742
+ },
2743
+ error: computed10(() => errorSignal()),
2744
+ explanations: computed10(() => reportSignal()?.checks.filter((check) => check.status !== "pass" && !!check.gateExplanation) ?? []),
2745
+ isLoading: computed10(() => isLoadingSignal()),
2746
+ refresh: store.refresh,
2747
+ report: computed10(() => reportSignal()),
2748
+ updatedAt: computed10(() => updatedAtSignal())
2749
+ };
2750
+ }
2751
+ }
2752
+ VoiceReadinessFailuresService = __decorateElement(_init, 0, "VoiceReadinessFailuresService", _dec, VoiceReadinessFailuresService);
2753
+ __runInitializers(_init, 1, VoiceReadinessFailuresService);
2754
+ __decoratorMetadata(_init, VoiceReadinessFailuresService);
2755
+ let _VoiceReadinessFailuresService = VoiceReadinessFailuresService;
2756
+ // src/angular/voice-ops-action-center.service.ts
2757
+ import { computed as computed11, Injectable as Injectable11, signal as signal11 } from "@angular/core";
2758
+
2759
+ // src/client/opsActionCenter.ts
2760
+ var recordVoiceOpsActionResult = async (result, options = {}) => {
2761
+ if (options.auditPath === false) {
2762
+ return;
2763
+ }
2764
+ const path = options.auditPath ?? "/api/voice/ops-actions/audit";
2765
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2766
+ const response = await fetchImpl(path, {
2767
+ body: JSON.stringify(result),
2768
+ headers: {
2769
+ "Content-Type": "application/json"
2770
+ },
2771
+ method: "POST"
2772
+ });
2773
+ if (!response.ok) {
2774
+ throw new Error(`Voice ops action audit failed: HTTP ${response.status}`);
2775
+ }
2776
+ };
2777
+ var createVoiceOpsActionCenterActions = (options = {}) => {
2778
+ const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
2779
+ const actions = [];
2780
+ if (options.includeProductionReadiness !== false) {
2781
+ actions.push({
2782
+ description: "Refresh the production readiness report.",
2783
+ id: "production-readiness",
2784
+ label: "Refresh readiness",
2785
+ method: "GET",
2786
+ path: options.productionReadinessPath ?? "/api/production-readiness"
2787
+ });
2788
+ }
2789
+ if (options.includeDeliveryRuntime !== false) {
2790
+ actions.push({
2791
+ description: "Drain pending and failed audit/trace deliveries.",
2792
+ id: "delivery-runtime.tick",
2793
+ label: "Tick delivery workers",
2794
+ method: "POST",
2795
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
2796
+ }, {
2797
+ description: "Move reviewed dead letters back to live delivery queues.",
2798
+ id: "delivery-runtime.requeue-dead-letters",
2799
+ label: "Requeue dead letters",
2800
+ method: "POST",
2801
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
2802
+ });
2803
+ }
2804
+ if (options.includeTurnLatencyProof !== false) {
2805
+ actions.push({
2806
+ description: "Run the synthetic turn latency proof.",
2807
+ id: "turn-latency.proof",
2808
+ label: "Run latency proof",
2809
+ method: "POST",
2810
+ path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
2811
+ });
2812
+ }
2813
+ if (options.includeProviderSimulation !== false) {
2814
+ const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
2815
+ for (const provider of options.providers ?? []) {
2816
+ actions.push({
2817
+ description: `Simulate ${provider} provider failure.`,
2818
+ id: `provider.${provider}.failure`,
2819
+ label: `Simulate ${provider} failure`,
2820
+ method: "POST",
2821
+ path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
2822
+ }, {
2823
+ description: `Mark ${provider} provider recovered.`,
2824
+ id: `provider.${provider}.recovery`,
2825
+ label: `Recover ${provider}`,
2826
+ method: "POST",
2827
+ path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
2828
+ });
2829
+ }
2830
+ }
2831
+ return actions;
2832
+ };
2833
+ var runVoiceOpsAction = async (action, options = {}) => {
2834
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2835
+ const response = await fetchImpl(action.path, {
2836
+ method: action.method ?? "POST"
2837
+ });
2838
+ const body = await response.json().catch(() => null);
2839
+ if (!response.ok) {
2840
+ const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
2841
+ throw new Error(message);
2842
+ }
2843
+ return {
2844
+ actionId: action.id,
2845
+ body,
2846
+ ok: response.ok,
2847
+ ranAt: Date.now(),
2848
+ status: response.status
2849
+ };
2850
+ };
2851
+ var createVoiceOpsActionCenterStore = (options = {}) => {
2852
+ const listeners = new Set;
2853
+ let closed = false;
2854
+ let timer;
2855
+ let snapshot = {
2856
+ actions: options.actions ?? createVoiceOpsActionCenterActions(),
2857
+ error: null,
2858
+ isRunning: false
2859
+ };
2860
+ const emit = () => {
2861
+ for (const listener of listeners) {
2862
+ listener();
2863
+ }
2864
+ };
2865
+ const setActions = (actions) => {
2866
+ snapshot = { ...snapshot, actions, updatedAt: Date.now() };
2867
+ emit();
2868
+ };
2869
+ const run = async (actionId) => {
2870
+ if (closed) {
2871
+ return snapshot.lastResult;
2872
+ }
2873
+ const action = snapshot.actions.find((item) => item.id === actionId);
2874
+ if (!action) {
2875
+ throw new Error(`Voice ops action "${actionId}" is not configured.`);
2876
+ }
2877
+ if (action.disabled) {
2878
+ throw new Error(`Voice ops action "${actionId}" is disabled.`);
2879
+ }
2880
+ snapshot = {
2881
+ ...snapshot,
2882
+ error: null,
2883
+ isRunning: true,
2884
+ runningActionId: action.id
2885
+ };
2886
+ emit();
2887
+ try {
2888
+ const result = await runVoiceOpsAction(action, options);
2889
+ await options.onActionResult?.(result);
2890
+ await recordVoiceOpsActionResult(result, options);
2891
+ snapshot = {
2892
+ ...snapshot,
2893
+ error: null,
2894
+ isRunning: false,
2895
+ lastResult: result,
2896
+ runningActionId: undefined,
2897
+ updatedAt: Date.now()
2898
+ };
2899
+ emit();
2900
+ return result;
2901
+ } catch (error) {
2902
+ const result = {
2903
+ actionId: action.id,
2904
+ body: null,
2905
+ error: error instanceof Error ? error.message : String(error),
2906
+ ok: false,
2907
+ ranAt: Date.now(),
2908
+ status: 0
2909
+ };
2910
+ await options.onActionResult?.(result);
2911
+ await recordVoiceOpsActionResult(result, options).catch(() => {});
2912
+ snapshot = {
2913
+ ...snapshot,
2914
+ error: error instanceof Error ? error.message : String(error),
2915
+ isRunning: false,
2916
+ runningActionId: undefined
2917
+ };
2918
+ emit();
2919
+ throw error;
2920
+ }
2921
+ };
2922
+ const close = () => {
2923
+ closed = true;
2924
+ if (timer) {
2925
+ clearInterval(timer);
2926
+ timer = undefined;
2927
+ }
2928
+ listeners.clear();
2929
+ };
2930
+ if (options.intervalMs && options.intervalMs > 0) {
2931
+ timer = setInterval(() => {
2932
+ emit();
2933
+ }, options.intervalMs);
2934
+ }
2935
+ return {
2936
+ close,
2937
+ getServerSnapshot: () => snapshot,
2938
+ getSnapshot: () => snapshot,
2939
+ run,
2940
+ setActions,
2941
+ subscribe: (listener) => {
2942
+ listeners.add(listener);
2943
+ return () => {
2944
+ listeners.delete(listener);
2945
+ };
2946
+ }
2947
+ };
2948
+ };
2949
+
2950
+ // src/angular/voice-ops-action-center.service.ts
2951
+ var _dec = [
2952
+ Injectable11({ providedIn: "root" })
2953
+ ];
2954
+ var _init = __decoratorStart(undefined);
2955
+
2956
+ class VoiceOpsActionCenterService {
2957
+ connect(options = {}) {
2958
+ const store = createVoiceOpsActionCenterStore(options);
2959
+ const actionsSignal = signal11([]);
2960
+ const errorSignal = signal11(null);
2961
+ const isRunningSignal = signal11(false);
2962
+ const lastResultSignal = signal11(undefined);
2963
+ const runningActionIdSignal = signal11(undefined);
2964
+ const sync = () => {
2965
+ const snapshot = store.getSnapshot();
2966
+ actionsSignal.set(snapshot.actions);
2967
+ errorSignal.set(snapshot.error);
2968
+ isRunningSignal.set(snapshot.isRunning);
2969
+ lastResultSignal.set(snapshot.lastResult);
2970
+ runningActionIdSignal.set(snapshot.runningActionId);
2971
+ };
2972
+ const unsubscribe = store.subscribe(sync);
2973
+ sync();
2974
+ return {
2975
+ actions: computed11(() => actionsSignal()),
2976
+ close: () => {
2977
+ unsubscribe();
2978
+ store.close();
2979
+ },
2980
+ error: computed11(() => errorSignal()),
2981
+ isRunning: computed11(() => isRunningSignal()),
2982
+ lastResult: computed11(() => lastResultSignal()),
2983
+ run: store.run,
2984
+ runningActionId: computed11(() => runningActionIdSignal()),
2985
+ setActions: store.setActions
2986
+ };
2987
+ }
2988
+ }
2989
+ VoiceOpsActionCenterService = __decorateElement(_init, 0, "VoiceOpsActionCenterService", _dec, VoiceOpsActionCenterService);
2990
+ __runInitializers(_init, 1, VoiceOpsActionCenterService);
2991
+ __decoratorMetadata(_init, VoiceOpsActionCenterService);
2992
+ let _VoiceOpsActionCenterService = VoiceOpsActionCenterService;
2993
+ // src/angular/voice-live-ops.service.ts
2994
+ import { computed as computed12, Injectable as Injectable12, signal as signal12 } from "@angular/core";
2995
+
2996
+ // src/client/liveOps.ts
2997
+ var postVoiceLiveOpsAction = async (input, options = {}) => {
2998
+ if (!input.sessionId) {
2999
+ throw new Error("Start a voice session before running live ops actions.");
3000
+ }
3001
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3002
+ const response = await fetchImpl(options.actionPath ?? "/api/voice/live-ops/action", {
3003
+ body: JSON.stringify(input),
3004
+ headers: {
3005
+ "Content-Type": "application/json"
3006
+ },
3007
+ method: "POST"
3008
+ });
3009
+ const payload = await response.json().catch(() => null);
3010
+ if (!response.ok || !payload?.ok) {
3011
+ const message = payload && typeof payload === "object" && "error" in payload ? String(payload.error) : `Voice live ops action failed: HTTP ${response.status}`;
3012
+ throw new Error(message);
3013
+ }
3014
+ return payload;
3015
+ };
3016
+ var createVoiceLiveOpsStore = (options = {}) => {
3017
+ const listeners = new Set;
3018
+ let closed = false;
3019
+ let snapshot = {
3020
+ error: null,
3021
+ isRunning: false
3022
+ };
3023
+ const emit = () => {
3024
+ for (const listener of listeners) {
3025
+ listener();
3026
+ }
3027
+ };
3028
+ const run = async (input) => {
3029
+ if (closed) {
3030
+ return snapshot.lastResult;
3031
+ }
3032
+ snapshot = {
3033
+ ...snapshot,
3034
+ error: null,
3035
+ isRunning: true,
3036
+ runningAction: input.action
3037
+ };
3038
+ emit();
3039
+ try {
3040
+ const result = await postVoiceLiveOpsAction(input, options);
3041
+ await options.onControl?.(result);
3042
+ snapshot = {
3043
+ ...snapshot,
3044
+ error: null,
3045
+ isRunning: false,
3046
+ lastResult: result,
3047
+ runningAction: undefined,
3048
+ updatedAt: Date.now()
3049
+ };
3050
+ emit();
3051
+ return result;
3052
+ } catch (error) {
3053
+ snapshot = {
3054
+ ...snapshot,
3055
+ error: error instanceof Error ? error.message : String(error),
3056
+ isRunning: false,
3057
+ runningAction: undefined,
3058
+ updatedAt: Date.now()
3059
+ };
3060
+ emit();
3061
+ throw error;
3062
+ }
3063
+ };
3064
+ const close = () => {
3065
+ closed = true;
3066
+ listeners.clear();
3067
+ };
3068
+ return {
3069
+ close,
3070
+ getServerSnapshot: () => snapshot,
3071
+ getSnapshot: () => snapshot,
3072
+ run,
3073
+ subscribe: (listener) => {
3074
+ listeners.add(listener);
3075
+ return () => {
3076
+ listeners.delete(listener);
3077
+ };
3078
+ }
3079
+ };
3080
+ };
3081
+
3082
+ // src/angular/voice-live-ops.service.ts
3083
+ var _dec = [
3084
+ Injectable12({ providedIn: "root" })
3085
+ ];
3086
+ var _init = __decoratorStart(undefined);
3087
+
3088
+ class VoiceLiveOpsService {
3089
+ connect(options = {}) {
3090
+ const store = createVoiceLiveOpsStore(options);
3091
+ const errorSignal = signal12(null);
3092
+ const isRunningSignal = signal12(false);
3093
+ const lastResultSignal = signal12(undefined);
3094
+ const runningActionSignal = signal12(undefined);
3095
+ const sync = () => {
3096
+ const snapshot = store.getSnapshot();
3097
+ errorSignal.set(snapshot.error);
3098
+ isRunningSignal.set(snapshot.isRunning);
3099
+ lastResultSignal.set(snapshot.lastResult);
3100
+ runningActionSignal.set(snapshot.runningAction);
3101
+ };
3102
+ const unsubscribe = store.subscribe(sync);
3103
+ sync();
3104
+ return {
3105
+ close: () => {
3106
+ unsubscribe();
3107
+ store.close();
3108
+ },
3109
+ error: computed12(() => errorSignal()),
3110
+ isRunning: computed12(() => isRunningSignal()),
3111
+ lastResult: computed12(() => lastResultSignal()),
3112
+ run: store.run,
3113
+ runningAction: computed12(() => runningActionSignal())
3114
+ };
3115
+ }
3116
+ }
3117
+ VoiceLiveOpsService = __decorateElement(_init, 0, "VoiceLiveOpsService", _dec, VoiceLiveOpsService);
3118
+ __runInitializers(_init, 1, VoiceLiveOpsService);
3119
+ __decoratorMetadata(_init, VoiceLiveOpsService);
3120
+ let _VoiceLiveOpsService = VoiceLiveOpsService;
3121
+ // src/angular/voice-delivery-runtime.service.ts
3122
+ import { computed as computed13, Injectable as Injectable13, signal as signal13 } from "@angular/core";
3123
+
3124
+ // src/client/deliveryRuntime.ts
3125
+ var getDefaultActionPath = (path, action, options) => {
3126
+ if (action === "tick") {
3127
+ return options.tickPath ?? `${path.replace(/\/$/, "")}/tick`;
3128
+ }
3129
+ return options.requeueDeadLettersPath ?? `${path.replace(/\/$/, "")}/requeue-dead-letters`;
3130
+ };
3131
+ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
3132
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3133
+ const response = await fetchImpl(path);
3134
+ if (!response.ok) {
3135
+ throw new Error(`Voice delivery runtime failed: HTTP ${response.status}`);
3136
+ }
3137
+ return await response.json();
3138
+ };
3139
+ var runVoiceDeliveryRuntimeAction = async (action, path = "/api/voice-delivery-runtime", options = {}) => {
3140
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3141
+ const response = await fetchImpl(getDefaultActionPath(path, action, options), {
3142
+ method: "POST"
3143
+ });
3144
+ if (!response.ok) {
3145
+ throw new Error(`Voice delivery runtime ${action} failed: HTTP ${response.status}`);
3146
+ }
3147
+ const body = await response.json();
3148
+ return {
3149
+ action,
3150
+ result: body.result,
3151
+ summary: body.summary,
3152
+ updatedAt: Date.now()
3153
+ };
3154
+ };
3155
+ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
3156
+ const listeners = new Set;
3157
+ let closed = false;
3158
+ let timer;
3159
+ let snapshot = {
3160
+ actionError: null,
3161
+ actionStatus: "idle",
3162
+ error: null,
3163
+ isLoading: false
3164
+ };
3165
+ const emit = () => {
3166
+ for (const listener of listeners) {
3167
+ listener();
3168
+ }
3169
+ };
3170
+ const refresh = async () => {
3171
+ if (closed) {
3172
+ return snapshot.report;
3173
+ }
3174
+ snapshot = {
3175
+ ...snapshot,
3176
+ error: null,
3177
+ isLoading: true
3178
+ };
3179
+ emit();
3180
+ try {
3181
+ const report = await fetchVoiceDeliveryRuntime(path, options);
3182
+ snapshot = {
3183
+ ...snapshot,
3184
+ error: null,
3185
+ isLoading: false,
3186
+ report,
3187
+ updatedAt: Date.now()
3188
+ };
3189
+ emit();
3190
+ return report;
3191
+ } catch (error) {
3192
+ snapshot = {
3193
+ ...snapshot,
3194
+ error: error instanceof Error ? error.message : String(error),
3195
+ isLoading: false
3196
+ };
3197
+ emit();
3198
+ throw error;
3199
+ }
3200
+ };
3201
+ const runAction = async (action) => {
3202
+ if (closed) {
3203
+ return snapshot.lastAction;
3204
+ }
3205
+ snapshot = {
3206
+ ...snapshot,
3207
+ actionError: null,
3208
+ actionStatus: "running"
3209
+ };
3210
+ emit();
3211
+ try {
3212
+ const result = await runVoiceDeliveryRuntimeAction(action, path, options);
3213
+ snapshot = {
3214
+ ...snapshot,
3215
+ actionError: null,
3216
+ actionStatus: "completed",
3217
+ lastAction: result
3218
+ };
3219
+ emit();
3220
+ await refresh();
3221
+ return result;
3222
+ } catch (error) {
3223
+ snapshot = {
3224
+ ...snapshot,
3225
+ actionError: error instanceof Error ? error.message : String(error),
3226
+ actionStatus: "failed"
3227
+ };
3228
+ emit();
3229
+ throw error;
3230
+ }
3231
+ };
3232
+ const close = () => {
3233
+ closed = true;
3234
+ if (timer) {
3235
+ clearInterval(timer);
3236
+ timer = undefined;
3237
+ }
3238
+ listeners.clear();
3239
+ };
3240
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
3241
+ timer = setInterval(() => {
3242
+ refresh().catch(() => {});
3243
+ }, options.intervalMs);
3244
+ }
3245
+ return {
3246
+ close,
3247
+ getServerSnapshot: () => snapshot,
3248
+ getSnapshot: () => snapshot,
3249
+ requeueDeadLetters: () => runAction("requeue-dead-letters"),
3250
+ refresh,
3251
+ tick: () => runAction("tick"),
3252
+ subscribe: (listener) => {
3253
+ listeners.add(listener);
3254
+ return () => {
3255
+ listeners.delete(listener);
3256
+ };
3257
+ }
3258
+ };
3259
+ };
3260
+
3261
+ // src/angular/voice-delivery-runtime.service.ts
3262
+ var _dec = [
3263
+ Injectable13({ providedIn: "root" })
3264
+ ];
3265
+ var _init = __decoratorStart(undefined);
3266
+
3267
+ class VoiceDeliveryRuntimeService {
3268
+ connect(path = "/api/voice-delivery-runtime", options = {}) {
3269
+ const store = createVoiceDeliveryRuntimeStore(path, options);
3270
+ const actionErrorSignal = signal13(null);
3271
+ const actionStatusSignal = signal13("idle");
3272
+ const errorSignal = signal13(null);
3273
+ const isLoadingSignal = signal13(false);
3274
+ const reportSignal = signal13(undefined);
3275
+ const updatedAtSignal = signal13(undefined);
3276
+ const sync = () => {
3277
+ const snapshot = store.getSnapshot();
3278
+ actionErrorSignal.set(snapshot.actionError);
3279
+ actionStatusSignal.set(snapshot.actionStatus);
3280
+ errorSignal.set(snapshot.error);
3281
+ isLoadingSignal.set(snapshot.isLoading);
3282
+ reportSignal.set(snapshot.report);
3283
+ updatedAtSignal.set(snapshot.updatedAt);
3284
+ };
3285
+ const unsubscribe = store.subscribe(sync);
3286
+ sync();
3287
+ if (typeof window !== "undefined") {
3288
+ store.refresh().catch(() => {});
3289
+ }
3290
+ return {
3291
+ close: () => {
3292
+ unsubscribe();
3293
+ store.close();
3294
+ },
3295
+ error: computed13(() => errorSignal()),
3296
+ actionError: computed13(() => actionErrorSignal()),
3297
+ actionStatus: computed13(() => actionStatusSignal()),
3298
+ isLoading: computed13(() => isLoadingSignal()),
3299
+ requeueDeadLetters: store.requeueDeadLetters,
3300
+ refresh: store.refresh,
3301
+ report: computed13(() => reportSignal()),
3302
+ tick: store.tick,
3303
+ updatedAt: computed13(() => updatedAtSignal())
3304
+ };
3305
+ }
3306
+ }
3307
+ VoiceDeliveryRuntimeService = __decorateElement(_init, 0, "VoiceDeliveryRuntimeService", _dec, VoiceDeliveryRuntimeService);
3308
+ __runInitializers(_init, 1, VoiceDeliveryRuntimeService);
3309
+ __decoratorMetadata(_init, VoiceDeliveryRuntimeService);
3310
+ let _VoiceDeliveryRuntimeService = VoiceDeliveryRuntimeService;
3311
+ // src/angular/voice-campaign-dialer-proof.service.ts
3312
+ import { computed as computed14, Injectable as Injectable14, signal as signal14 } from "@angular/core";
3313
+
3314
+ // src/client/campaignDialerProof.ts
3315
+ var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3316
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3317
+ const response = await fetchImpl(path);
3318
+ if (!response.ok) {
3319
+ throw new Error(`Voice campaign dialer proof status failed: HTTP ${response.status}`);
3320
+ }
3321
+ return await response.json();
3322
+ };
3323
+ var runVoiceCampaignDialerProofAction = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3324
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3325
+ const response = await fetchImpl(path, { method: "POST" });
3326
+ if (!response.ok) {
3327
+ throw new Error(`Voice campaign dialer proof failed: HTTP ${response.status}`);
3328
+ }
3329
+ return await response.json();
3330
+ };
3331
+ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3332
+ const listeners = new Set;
3333
+ let closed = false;
3334
+ let timer;
3335
+ let snapshot = {
3336
+ error: null,
3337
+ isLoading: false
3338
+ };
3339
+ const emit = () => {
3340
+ for (const listener of listeners) {
3341
+ listener();
3342
+ }
3343
+ };
3344
+ const refresh = async () => {
3345
+ if (closed) {
3346
+ return snapshot.status;
3347
+ }
3348
+ snapshot = { ...snapshot, error: null, isLoading: true };
3349
+ emit();
3350
+ try {
3351
+ const status = await fetchVoiceCampaignDialerProofStatus(path, options);
3352
+ snapshot = {
3353
+ ...snapshot,
3354
+ error: null,
3355
+ isLoading: false,
3356
+ status,
3357
+ updatedAt: Date.now()
3358
+ };
3359
+ emit();
3360
+ return status;
3361
+ } catch (error) {
3362
+ snapshot = {
3363
+ ...snapshot,
3364
+ error: error instanceof Error ? error.message : String(error),
3365
+ isLoading: false
3366
+ };
3367
+ emit();
3368
+ throw error;
3369
+ }
3370
+ };
3371
+ const runProof = async () => {
3372
+ const runPath = options.runPath ?? snapshot.status?.runPath ?? path;
3373
+ snapshot = { ...snapshot, error: null, isLoading: true };
3374
+ emit();
3375
+ try {
3376
+ const report = await runVoiceCampaignDialerProofAction(runPath, options);
3377
+ snapshot = {
3378
+ ...snapshot,
3379
+ error: null,
3380
+ isLoading: false,
3381
+ report,
3382
+ status: {
3383
+ generatedAt: Date.now(),
3384
+ mode: report.mode,
3385
+ ok: report.ok,
3386
+ providers: report.providers.map((provider) => provider.provider),
3387
+ runPath,
3388
+ safe: true
3389
+ },
3390
+ updatedAt: Date.now()
3391
+ };
3392
+ emit();
3393
+ return report;
3394
+ } catch (error) {
3395
+ snapshot = {
3396
+ ...snapshot,
3397
+ error: error instanceof Error ? error.message : String(error),
3398
+ isLoading: false
3399
+ };
3400
+ emit();
3401
+ throw error;
3402
+ }
3403
+ };
3404
+ const close = () => {
3405
+ closed = true;
3406
+ if (timer) {
3407
+ clearInterval(timer);
3408
+ timer = undefined;
3409
+ }
3410
+ listeners.clear();
3411
+ };
3412
+ if (options.intervalMs && options.intervalMs > 0) {
3413
+ timer = setInterval(() => {
3414
+ refresh().catch(() => {});
3415
+ }, options.intervalMs);
3416
+ }
3417
+ return {
3418
+ close,
3419
+ getServerSnapshot: () => snapshot,
3420
+ getSnapshot: () => snapshot,
3421
+ refresh,
3422
+ runProof,
3423
+ subscribe: (listener) => {
3424
+ listeners.add(listener);
3425
+ return () => {
3426
+ listeners.delete(listener);
3427
+ };
3428
+ }
3429
+ };
3430
+ };
3431
+
3432
+ // src/angular/voice-campaign-dialer-proof.service.ts
3433
+ var _dec = [
3434
+ Injectable14({ providedIn: "root" })
3435
+ ];
3436
+ var _init = __decoratorStart(undefined);
3437
+
3438
+ class VoiceCampaignDialerProofService {
3439
+ connect(path = "/api/voice/campaigns/dialer-proof", options = {}) {
3440
+ const store = createVoiceCampaignDialerProofStore(path, options);
3441
+ const errorSignal = signal14(null);
3442
+ const isLoadingSignal = signal14(false);
3443
+ const reportSignal = signal14(undefined);
3444
+ const statusSignal = signal14(undefined);
3445
+ const updatedAtSignal = signal14(undefined);
3446
+ const sync = () => {
3447
+ const snapshot = store.getSnapshot();
3448
+ errorSignal.set(snapshot.error);
3449
+ isLoadingSignal.set(snapshot.isLoading);
3450
+ reportSignal.set(snapshot.report);
3451
+ statusSignal.set(snapshot.status);
3452
+ updatedAtSignal.set(snapshot.updatedAt);
3453
+ };
3454
+ const unsubscribe = store.subscribe(sync);
3455
+ sync();
3456
+ store.refresh().catch(() => {});
3457
+ return {
3458
+ close: () => {
3459
+ unsubscribe();
3460
+ store.close();
3461
+ },
3462
+ error: computed14(() => errorSignal()),
3463
+ isLoading: computed14(() => isLoadingSignal()),
3464
+ refresh: store.refresh,
3465
+ report: computed14(() => reportSignal()),
3466
+ runProof: store.runProof,
3467
+ status: computed14(() => statusSignal()),
3468
+ updatedAt: computed14(() => updatedAtSignal())
3469
+ };
3470
+ }
3471
+ }
3472
+ VoiceCampaignDialerProofService = __decorateElement(_init, 0, "VoiceCampaignDialerProofService", _dec, VoiceCampaignDialerProofService);
3473
+ __runInitializers(_init, 1, VoiceCampaignDialerProofService);
3474
+ __decoratorMetadata(_init, VoiceCampaignDialerProofService);
3475
+ let _VoiceCampaignDialerProofService = VoiceCampaignDialerProofService;
3476
+ // src/angular/voice-stream.service.ts
3477
+ import { computed as computed15, Injectable as Injectable15, signal as signal15 } from "@angular/core";
3478
+ var _dec = [
3479
+ Injectable15({ providedIn: "root" })
3480
+ ];
3481
+ var _init = __decoratorStart(undefined);
3482
+
3483
+ class VoiceStreamService {
3484
+ connect(path, options = {}) {
3485
+ const stream = createVoiceStream(path, options);
3486
+ const assistantAudioSignal = signal15([]);
3487
+ const assistantTextsSignal = signal15([]);
3488
+ const callSignal = signal15(null);
3489
+ const errorSignal = signal15(null);
3490
+ const isConnectedSignal = signal15(false);
3491
+ const partialSignal = signal15("");
3492
+ const reconnectSignal = signal15(stream.reconnect);
3493
+ const sessionIdSignal = signal15(stream.sessionId);
3494
+ const sessionMetadataSignal = signal15(stream.sessionMetadata);
3495
+ const statusSignal = signal15(stream.status);
3496
+ const turnsSignal = signal15([]);
3497
+ const sync = () => {
3498
+ assistantAudioSignal.set([...stream.assistantAudio]);
3499
+ assistantTextsSignal.set([...stream.assistantTexts]);
3500
+ callSignal.set(stream.call);
3501
+ errorSignal.set(stream.error);
3502
+ isConnectedSignal.set(stream.isConnected);
3503
+ partialSignal.set(stream.partial);
3504
+ reconnectSignal.set(stream.reconnect);
3505
+ sessionIdSignal.set(stream.sessionId);
3506
+ sessionMetadataSignal.set(stream.sessionMetadata);
3507
+ statusSignal.set(stream.status);
3508
+ turnsSignal.set([...stream.turns]);
3509
+ };
3510
+ const unsubscribe = stream.subscribe(sync);
3511
+ sync();
3512
+ return {
3513
+ assistantAudio: computed15(() => assistantAudioSignal()),
3514
+ assistantTexts: computed15(() => assistantTextsSignal()),
3515
+ call: computed15(() => callSignal()),
3516
+ callControl: (message) => stream.callControl(message),
3517
+ close: () => {
3518
+ unsubscribe();
3519
+ stream.close();
3520
+ },
3521
+ endTurn: () => stream.endTurn(),
3522
+ error: computed15(() => errorSignal()),
3523
+ isConnected: computed15(() => isConnectedSignal()),
3524
+ partial: computed15(() => partialSignal()),
3525
+ reconnect: computed15(() => reconnectSignal()),
3526
+ sendAudio: (audio) => stream.sendAudio(audio),
3527
+ simulateDisconnect: () => stream.simulateDisconnect(),
3528
+ sessionId: computed15(() => sessionIdSignal()),
3529
+ sessionMetadata: computed15(() => sessionMetadataSignal()),
3530
+ status: computed15(() => statusSignal()),
3531
+ turns: computed15(() => turnsSignal())
3532
+ };
3533
+ }
3534
+ }
3535
+ VoiceStreamService = __decorateElement(_init, 0, "VoiceStreamService", _dec, VoiceStreamService);
3536
+ __runInitializers(_init, 1, VoiceStreamService);
3537
+ __decoratorMetadata(_init, VoiceStreamService);
3538
+ let _VoiceStreamService = VoiceStreamService;
3539
+ // src/angular/voice-controller.service.ts
3540
+ import { computed as computed16, Injectable as Injectable16, signal as signal16 } from "@angular/core";
3541
+ var _dec = [
3542
+ Injectable16({ providedIn: "root" })
3543
+ ];
3544
+ var _init = __decoratorStart(undefined);
3545
+
3546
+ class VoiceControllerService {
3547
+ connect(path, options = {}) {
3548
+ const controller = createVoiceController(path, options);
3549
+ const assistantAudioSignal = signal16([]);
3550
+ const assistantTextsSignal = signal16([]);
3551
+ const errorSignal = signal16(null);
3552
+ const isConnectedSignal = signal16(false);
3553
+ const isRecordingSignal = signal16(false);
3554
+ const partialSignal = signal16("");
3555
+ const reconnectSignal = signal16(controller.reconnect);
3556
+ const recordingErrorSignal = signal16(null);
3557
+ const sessionIdSignal = signal16(controller.sessionId);
3558
+ const statusSignal = signal16(controller.status);
3559
+ const turnsSignal = signal16([]);
3560
+ const sync = () => {
3561
+ assistantAudioSignal.set([...controller.assistantAudio]);
3562
+ assistantTextsSignal.set([...controller.assistantTexts]);
3563
+ errorSignal.set(controller.error);
3564
+ isConnectedSignal.set(controller.isConnected);
3565
+ isRecordingSignal.set(controller.isRecording);
3566
+ partialSignal.set(controller.partial);
3567
+ reconnectSignal.set(controller.reconnect);
3568
+ recordingErrorSignal.set(controller.recordingError);
3569
+ sessionIdSignal.set(controller.sessionId);
3570
+ statusSignal.set(controller.status);
3571
+ turnsSignal.set([...controller.turns]);
3572
+ };
3573
+ const unsubscribe = controller.subscribe(sync);
3574
+ sync();
3575
+ return {
3576
+ assistantAudio: computed16(() => assistantAudioSignal()),
3577
+ assistantTexts: computed16(() => assistantTextsSignal()),
3578
+ bindHTMX: controller.bindHTMX,
3579
+ close: () => {
3580
+ unsubscribe();
3581
+ controller.close();
3582
+ },
3583
+ endTurn: () => controller.endTurn(),
3584
+ error: computed16(() => errorSignal()),
3585
+ isConnected: computed16(() => isConnectedSignal()),
3586
+ isRecording: computed16(() => isRecordingSignal()),
3587
+ partial: computed16(() => partialSignal()),
3588
+ reconnect: computed16(() => reconnectSignal()),
3589
+ recordingError: computed16(() => recordingErrorSignal()),
3590
+ sendAudio: (audio) => controller.sendAudio(audio),
3591
+ simulateDisconnect: () => controller.simulateDisconnect(),
3592
+ sessionId: computed16(() => sessionIdSignal()),
3593
+ startRecording: () => controller.startRecording(),
3594
+ status: computed16(() => statusSignal()),
3595
+ stopRecording: () => controller.stopRecording(),
3596
+ toggleRecording: () => controller.toggleRecording(),
3597
+ turns: computed16(() => turnsSignal())
3598
+ };
3599
+ }
3600
+ }
3601
+ VoiceControllerService = __decorateElement(_init, 0, "VoiceControllerService", _dec, VoiceControllerService);
3602
+ __runInitializers(_init, 1, VoiceControllerService);
3603
+ __decoratorMetadata(_init, VoiceControllerService);
3604
+ let _VoiceControllerService = VoiceControllerService;
3605
+ // src/angular/voice-provider-capabilities.service.ts
3606
+ import { computed as computed17, Injectable as Injectable17, signal as signal17 } from "@angular/core";
3607
+
3608
+ // src/client/providerCapabilities.ts
3609
+ var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
3610
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3611
+ const response = await fetchImpl(path);
3612
+ if (!response.ok) {
3613
+ throw new Error(`Voice provider capabilities failed: HTTP ${response.status}`);
3614
+ }
3615
+ return await response.json();
3616
+ };
3617
+ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities", options = {}) => {
3618
+ const listeners = new Set;
3619
+ let closed = false;
3620
+ let timer;
3621
+ let snapshot = {
3622
+ error: null,
3623
+ isLoading: false
3624
+ };
3625
+ const emit = () => {
3626
+ for (const listener of listeners) {
3627
+ listener();
3628
+ }
3629
+ };
3630
+ const refresh = async () => {
3631
+ if (closed) {
3632
+ return snapshot.report;
3633
+ }
3634
+ snapshot = {
3635
+ ...snapshot,
3636
+ error: null,
3637
+ isLoading: true
3638
+ };
3639
+ emit();
3640
+ try {
3641
+ const report = await fetchVoiceProviderCapabilities(path, options);
3642
+ snapshot = {
3643
+ error: null,
3644
+ isLoading: false,
3645
+ report,
3646
+ updatedAt: Date.now()
3647
+ };
3648
+ emit();
3649
+ return report;
3650
+ } catch (error) {
3651
+ snapshot = {
3652
+ ...snapshot,
3653
+ error: error instanceof Error ? error.message : String(error),
3654
+ isLoading: false
3655
+ };
3656
+ emit();
3657
+ throw error;
3658
+ }
3659
+ };
3660
+ const close = () => {
3661
+ closed = true;
3662
+ if (timer) {
3663
+ clearInterval(timer);
3664
+ timer = undefined;
3665
+ }
3666
+ listeners.clear();
3667
+ };
3668
+ if (options.intervalMs && options.intervalMs > 0) {
3669
+ timer = setInterval(() => {
3670
+ refresh().catch(() => {});
3671
+ }, options.intervalMs);
3672
+ }
3673
+ return {
3674
+ close,
3675
+ getServerSnapshot: () => snapshot,
3676
+ getSnapshot: () => snapshot,
3677
+ refresh,
3678
+ subscribe: (listener) => {
3679
+ listeners.add(listener);
3680
+ return () => {
3681
+ listeners.delete(listener);
3682
+ };
3683
+ }
3684
+ };
3685
+ };
3686
+
3687
+ // src/angular/voice-provider-capabilities.service.ts
3688
+ var _dec = [
3689
+ Injectable17({ providedIn: "root" })
3690
+ ];
3691
+ var _init = __decoratorStart(undefined);
3692
+
3693
+ class VoiceProviderCapabilitiesService {
3694
+ connect(path = "/api/provider-capabilities", options = {}) {
3695
+ const store = createVoiceProviderCapabilitiesStore(path, options);
3696
+ const errorSignal = signal17(null);
3697
+ const isLoadingSignal = signal17(false);
3698
+ const reportSignal = signal17(undefined);
3699
+ const updatedAtSignal = signal17(undefined);
3700
+ const sync = () => {
3701
+ const snapshot = store.getSnapshot();
3702
+ errorSignal.set(snapshot.error);
3703
+ isLoadingSignal.set(snapshot.isLoading);
3704
+ reportSignal.set(snapshot.report);
3705
+ updatedAtSignal.set(snapshot.updatedAt);
3706
+ };
3707
+ const unsubscribe = store.subscribe(sync);
3708
+ sync();
3709
+ store.refresh().catch(() => {});
3710
+ return {
3711
+ close: () => {
3712
+ unsubscribe();
3713
+ store.close();
3714
+ },
3715
+ error: computed17(() => errorSignal()),
3716
+ isLoading: computed17(() => isLoadingSignal()),
3717
+ refresh: store.refresh,
3718
+ report: computed17(() => reportSignal()),
3719
+ updatedAt: computed17(() => updatedAtSignal())
3720
+ };
3721
+ }
3722
+ }
3723
+ VoiceProviderCapabilitiesService = __decorateElement(_init, 0, "VoiceProviderCapabilitiesService", _dec, VoiceProviderCapabilitiesService);
3724
+ __runInitializers(_init, 1, VoiceProviderCapabilitiesService);
3725
+ __decoratorMetadata(_init, VoiceProviderCapabilitiesService);
3726
+ let _VoiceProviderCapabilitiesService = VoiceProviderCapabilitiesService;
3727
+ // src/angular/voice-provider-contracts.service.ts
3728
+ import { computed as computed18, Injectable as Injectable18, signal as signal18 } from "@angular/core";
3729
+
3730
+ // src/client/providerContracts.ts
3731
+ var fetchVoiceProviderContracts = async (path = "/api/provider-contracts", options = {}) => {
3732
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3733
+ const response = await fetchImpl(path);
3734
+ if (!response.ok) {
3735
+ throw new Error(`Voice provider contracts failed: HTTP ${response.status}`);
3736
+ }
3737
+ return await response.json();
3738
+ };
3739
+ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", options = {}) => {
3740
+ const listeners = new Set;
3741
+ let closed = false;
3742
+ let timer;
3743
+ let snapshot = {
3744
+ error: null,
3745
+ isLoading: false
3746
+ };
3747
+ const emit = () => {
3748
+ for (const listener of listeners) {
3749
+ listener();
3750
+ }
3751
+ };
3752
+ const refresh = async () => {
3753
+ if (closed) {
3754
+ return snapshot.report;
3755
+ }
3756
+ snapshot = { ...snapshot, error: null, isLoading: true };
3757
+ emit();
3758
+ try {
3759
+ const report = await fetchVoiceProviderContracts(path, options);
3760
+ snapshot = {
3761
+ error: null,
3762
+ isLoading: false,
3763
+ report,
3764
+ updatedAt: Date.now()
3765
+ };
3766
+ emit();
3767
+ return report;
3768
+ } catch (error) {
3769
+ snapshot = {
3770
+ ...snapshot,
3771
+ error: error instanceof Error ? error.message : String(error),
3772
+ isLoading: false
3773
+ };
3774
+ emit();
3775
+ throw error;
3776
+ }
3777
+ };
3778
+ const close = () => {
3779
+ closed = true;
3780
+ if (timer) {
3781
+ clearInterval(timer);
3782
+ timer = undefined;
3783
+ }
3784
+ listeners.clear();
3785
+ };
3786
+ if (options.intervalMs && options.intervalMs > 0) {
3787
+ timer = setInterval(() => {
3788
+ refresh().catch(() => {});
3789
+ }, options.intervalMs);
3790
+ }
3791
+ return {
3792
+ close,
3793
+ getServerSnapshot: () => snapshot,
3794
+ getSnapshot: () => snapshot,
3795
+ refresh,
3796
+ subscribe: (listener) => {
3797
+ listeners.add(listener);
3798
+ return () => {
3799
+ listeners.delete(listener);
3800
+ };
3801
+ }
3802
+ };
3803
+ };
3804
+
3805
+ // src/angular/voice-provider-contracts.service.ts
3806
+ var _dec = [
3807
+ Injectable18({ providedIn: "root" })
3808
+ ];
3809
+ var _init = __decoratorStart(undefined);
3810
+
3811
+ class VoiceProviderContractsService {
3812
+ connect(path = "/api/provider-contracts", options = {}) {
3813
+ const store = createVoiceProviderContractsStore(path, options);
3814
+ const errorSignal = signal18(null);
3815
+ const isLoadingSignal = signal18(false);
3816
+ const reportSignal = signal18(undefined);
3817
+ const updatedAtSignal = signal18(undefined);
3818
+ const sync = () => {
3819
+ const snapshot = store.getSnapshot();
3820
+ errorSignal.set(snapshot.error);
3821
+ isLoadingSignal.set(snapshot.isLoading);
3822
+ reportSignal.set(snapshot.report);
3823
+ updatedAtSignal.set(snapshot.updatedAt);
3824
+ };
3825
+ const unsubscribe = store.subscribe(sync);
3826
+ sync();
3827
+ store.refresh().catch(() => {});
3828
+ return {
3829
+ close: () => {
3830
+ unsubscribe();
3831
+ store.close();
3832
+ },
3833
+ error: computed18(() => errorSignal()),
3834
+ isLoading: computed18(() => isLoadingSignal()),
3835
+ refresh: store.refresh,
3836
+ report: computed18(() => reportSignal()),
3837
+ updatedAt: computed18(() => updatedAtSignal())
3838
+ };
3839
+ }
3840
+ }
3841
+ VoiceProviderContractsService = __decorateElement(_init, 0, "VoiceProviderContractsService", _dec, VoiceProviderContractsService);
3842
+ __runInitializers(_init, 1, VoiceProviderContractsService);
3843
+ __decoratorMetadata(_init, VoiceProviderContractsService);
3844
+ let _VoiceProviderContractsService = VoiceProviderContractsService;
3845
+ // src/angular/voice-provider-status.service.ts
3846
+ import { computed as computed19, Injectable as Injectable19, signal as signal19 } from "@angular/core";
3847
+
3848
+ // src/client/providerStatus.ts
3849
+ var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
3850
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3851
+ const response = await fetchImpl(path);
3852
+ if (!response.ok) {
3853
+ throw new Error(`Voice provider status failed: HTTP ${response.status}`);
3854
+ }
3855
+ return await response.json();
3856
+ };
3857
+ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {}) => {
3858
+ const listeners = new Set;
3859
+ let closed = false;
3860
+ let timer;
3861
+ let snapshot = {
3862
+ error: null,
3863
+ isLoading: false,
3864
+ providers: []
3865
+ };
3866
+ const emit = () => {
3867
+ for (const listener of listeners) {
3868
+ listener();
3869
+ }
3870
+ };
3871
+ const refresh = async () => {
3872
+ if (closed) {
3873
+ return snapshot.providers;
3874
+ }
3875
+ snapshot = {
3876
+ ...snapshot,
3877
+ error: null,
3878
+ isLoading: true
3879
+ };
3880
+ emit();
3881
+ try {
3882
+ const providers = await fetchVoiceProviderStatus(path, options);
3883
+ snapshot = {
3884
+ error: null,
3885
+ isLoading: false,
3886
+ providers,
3887
+ updatedAt: Date.now()
3888
+ };
3889
+ emit();
3890
+ return providers;
3891
+ } catch (error) {
3892
+ snapshot = {
3893
+ ...snapshot,
3894
+ error: error instanceof Error ? error.message : String(error),
3895
+ isLoading: false
3896
+ };
3897
+ emit();
3898
+ throw error;
3899
+ }
3900
+ };
3901
+ const close = () => {
3902
+ closed = true;
3903
+ if (timer) {
3904
+ clearInterval(timer);
3905
+ timer = undefined;
3906
+ }
3907
+ listeners.clear();
3908
+ };
3909
+ if (options.intervalMs && options.intervalMs > 0) {
3910
+ timer = setInterval(() => {
3911
+ refresh().catch(() => {});
3912
+ }, options.intervalMs);
3913
+ }
3914
+ return {
3915
+ close,
3916
+ getServerSnapshot: () => snapshot,
3917
+ getSnapshot: () => snapshot,
3918
+ refresh,
3919
+ subscribe: (listener) => {
3920
+ listeners.add(listener);
3921
+ return () => {
3922
+ listeners.delete(listener);
3923
+ };
3924
+ }
3925
+ };
3926
+ };
3927
+
3928
+ // src/angular/voice-provider-status.service.ts
3929
+ var _dec = [
3930
+ Injectable19({ providedIn: "root" })
3931
+ ];
3932
+ var _init = __decoratorStart(undefined);
3933
+
3934
+ class VoiceProviderStatusService {
3935
+ connect(path = "/api/provider-status", options = {}) {
3936
+ const store = createVoiceProviderStatusStore(path, options);
3937
+ const errorSignal = signal19(null);
3938
+ const isLoadingSignal = signal19(false);
3939
+ const providersSignal = signal19([]);
3940
+ const updatedAtSignal = signal19(undefined);
3941
+ const sync = () => {
3942
+ const snapshot = store.getSnapshot();
3943
+ errorSignal.set(snapshot.error);
3944
+ isLoadingSignal.set(snapshot.isLoading);
3945
+ providersSignal.set([...snapshot.providers]);
3946
+ updatedAtSignal.set(snapshot.updatedAt);
3947
+ };
3948
+ const unsubscribe = store.subscribe(sync);
3949
+ sync();
3950
+ store.refresh().catch(() => {});
3951
+ return {
3952
+ close: () => {
3953
+ unsubscribe();
3954
+ store.close();
3955
+ },
3956
+ error: computed19(() => errorSignal()),
3957
+ isLoading: computed19(() => isLoadingSignal()),
3958
+ providers: computed19(() => providersSignal()),
3959
+ refresh: store.refresh,
3960
+ updatedAt: computed19(() => updatedAtSignal())
3961
+ };
3962
+ }
3963
+ }
3964
+ VoiceProviderStatusService = __decorateElement(_init, 0, "VoiceProviderStatusService", _dec, VoiceProviderStatusService);
3965
+ __runInitializers(_init, 1, VoiceProviderStatusService);
3966
+ __decoratorMetadata(_init, VoiceProviderStatusService);
3967
+ let _VoiceProviderStatusService = VoiceProviderStatusService;
3968
+ // src/angular/voice-routing-status.service.ts
3969
+ import { Injectable as Injectable20, signal as signal20 } from "@angular/core";
3970
+
3971
+ // src/client/routingStatus.ts
3972
+ var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
3973
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3974
+ const response = await fetchImpl(path);
3975
+ if (!response.ok) {
3976
+ throw new Error(`Voice routing status failed: HTTP ${response.status}`);
3977
+ }
3978
+ return await response.json();
3979
+ };
3980
+ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {}) => {
3981
+ const listeners = new Set;
3982
+ let closed = false;
3983
+ let timer;
3984
+ let snapshot = {
3985
+ decision: null,
3986
+ error: null,
3987
+ isLoading: false
3988
+ };
3989
+ const emit = () => {
3990
+ for (const listener of listeners) {
3991
+ listener();
3992
+ }
3993
+ };
3994
+ const refresh = async () => {
3995
+ if (closed) {
3996
+ return snapshot.decision;
3997
+ }
3998
+ snapshot = {
3999
+ ...snapshot,
4000
+ error: null,
4001
+ isLoading: true
4002
+ };
4003
+ emit();
4004
+ try {
4005
+ const decision = await fetchVoiceRoutingStatus(path, options);
4006
+ snapshot = {
4007
+ decision,
4008
+ error: null,
4009
+ isLoading: false,
4010
+ updatedAt: Date.now()
4011
+ };
4012
+ emit();
4013
+ return decision;
4014
+ } catch (error) {
4015
+ snapshot = {
4016
+ ...snapshot,
4017
+ error: error instanceof Error ? error.message : String(error),
4018
+ isLoading: false
4019
+ };
4020
+ emit();
4021
+ throw error;
4022
+ }
4023
+ };
4024
+ const close = () => {
4025
+ closed = true;
4026
+ if (timer) {
4027
+ clearInterval(timer);
4028
+ timer = undefined;
4029
+ }
4030
+ listeners.clear();
4031
+ };
4032
+ if (options.intervalMs && options.intervalMs > 0) {
4033
+ timer = setInterval(() => {
4034
+ refresh().catch(() => {});
4035
+ }, options.intervalMs);
4036
+ }
4037
+ return {
4038
+ close,
4039
+ getServerSnapshot: () => snapshot,
4040
+ getSnapshot: () => snapshot,
4041
+ refresh,
4042
+ subscribe: (listener) => {
4043
+ listeners.add(listener);
4044
+ return () => {
4045
+ listeners.delete(listener);
4046
+ };
4047
+ }
4048
+ };
4049
+ };
4050
+
4051
+ // src/angular/voice-routing-status.service.ts
4052
+ var _dec = [
4053
+ Injectable20({ providedIn: "root" })
4054
+ ];
4055
+ var _init = __decoratorStart(undefined);
4056
+
4057
+ class VoiceRoutingStatusService {
4058
+ connect(path = "/api/routing/latest", options = {}) {
4059
+ const store = createVoiceRoutingStatusStore(path, options);
4060
+ const decisionSignal = signal20(null);
4061
+ const errorSignal = signal20(null);
4062
+ const isLoadingSignal = signal20(false);
4063
+ const updatedAtSignal = signal20(undefined);
4064
+ const sync = () => {
4065
+ const snapshot = store.getSnapshot();
4066
+ decisionSignal.set(snapshot.decision);
4067
+ errorSignal.set(snapshot.error);
4068
+ isLoadingSignal.set(snapshot.isLoading);
4069
+ updatedAtSignal.set(snapshot.updatedAt);
4070
+ };
4071
+ const unsubscribe = store.subscribe(sync);
4072
+ sync();
4073
+ store.refresh().catch(() => {});
4074
+ return {
4075
+ close: () => {
4076
+ unsubscribe();
4077
+ store.close();
4078
+ },
4079
+ decision: decisionSignal.asReadonly(),
4080
+ error: errorSignal.asReadonly(),
4081
+ isLoading: isLoadingSignal.asReadonly(),
4082
+ refresh: store.refresh,
4083
+ updatedAt: updatedAtSignal.asReadonly()
4084
+ };
4085
+ }
4086
+ }
4087
+ VoiceRoutingStatusService = __decorateElement(_init, 0, "VoiceRoutingStatusService", _dec, VoiceRoutingStatusService);
4088
+ __runInitializers(_init, 1, VoiceRoutingStatusService);
4089
+ __decoratorMetadata(_init, VoiceRoutingStatusService);
4090
+ let _VoiceRoutingStatusService = VoiceRoutingStatusService;
4091
+ // src/angular/voice-trace-timeline.service.ts
4092
+ import { computed as computed20, Injectable as Injectable21, signal as signal21 } from "@angular/core";
4093
+
4094
+ // src/client/traceTimeline.ts
4095
+ var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
4096
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4097
+ const response = await fetchImpl(path);
4098
+ if (!response.ok) {
4099
+ throw new Error(`Voice trace timeline failed: HTTP ${response.status}`);
4100
+ }
4101
+ return await response.json();
4102
+ };
4103
+ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) => {
4104
+ const listeners = new Set;
4105
+ let closed = false;
4106
+ let timer;
4107
+ let snapshot = {
4108
+ error: null,
4109
+ isLoading: false,
4110
+ report: null
4111
+ };
4112
+ const emit = () => {
4113
+ for (const listener of listeners) {
4114
+ listener();
4115
+ }
4116
+ };
4117
+ const refresh = async () => {
4118
+ if (closed) {
4119
+ return snapshot.report;
4120
+ }
4121
+ snapshot = {
4122
+ ...snapshot,
4123
+ error: null,
4124
+ isLoading: true
4125
+ };
4126
+ emit();
4127
+ try {
4128
+ const report = await fetchVoiceTraceTimeline(path, options);
4129
+ snapshot = {
4130
+ error: null,
4131
+ isLoading: false,
4132
+ report,
4133
+ updatedAt: Date.now()
4134
+ };
4135
+ emit();
4136
+ return report;
4137
+ } catch (error) {
4138
+ snapshot = {
4139
+ ...snapshot,
4140
+ error: error instanceof Error ? error.message : String(error),
4141
+ isLoading: false
4142
+ };
4143
+ emit();
4144
+ throw error;
4145
+ }
4146
+ };
4147
+ const close = () => {
4148
+ closed = true;
4149
+ if (timer) {
4150
+ clearInterval(timer);
4151
+ timer = undefined;
4152
+ }
4153
+ listeners.clear();
4154
+ };
4155
+ if (options.intervalMs && options.intervalMs > 0) {
4156
+ timer = setInterval(() => {
4157
+ refresh().catch(() => {});
4158
+ }, options.intervalMs);
4159
+ }
4160
+ return {
4161
+ close,
4162
+ getServerSnapshot: () => snapshot,
4163
+ getSnapshot: () => snapshot,
4164
+ refresh,
4165
+ subscribe: (listener) => {
4166
+ listeners.add(listener);
4167
+ return () => {
4168
+ listeners.delete(listener);
4169
+ };
4170
+ }
4171
+ };
4172
+ };
4173
+
4174
+ // src/angular/voice-trace-timeline.service.ts
4175
+ var _dec = [
4176
+ Injectable21({ providedIn: "root" })
4177
+ ];
4178
+ var _init = __decoratorStart(undefined);
4179
+
4180
+ class VoiceTraceTimelineService {
4181
+ connect(path = "/api/voice-traces", options = {}) {
4182
+ const store = createVoiceTraceTimelineStore(path, options);
4183
+ const errorSignal = signal21(null);
4184
+ const isLoadingSignal = signal21(false);
4185
+ const reportSignal = signal21(null);
4186
+ const updatedAtSignal = signal21(undefined);
4187
+ const sync = () => {
4188
+ const snapshot = store.getSnapshot();
4189
+ errorSignal.set(snapshot.error);
4190
+ isLoadingSignal.set(snapshot.isLoading);
4191
+ reportSignal.set(snapshot.report);
4192
+ updatedAtSignal.set(snapshot.updatedAt);
4193
+ };
4194
+ const unsubscribe = store.subscribe(sync);
4195
+ sync();
4196
+ store.refresh().catch(() => {});
4197
+ return {
4198
+ close: () => {
4199
+ unsubscribe();
4200
+ store.close();
4201
+ },
4202
+ error: computed20(() => errorSignal()),
4203
+ isLoading: computed20(() => isLoadingSignal()),
4204
+ refresh: store.refresh,
4205
+ report: computed20(() => reportSignal()),
4206
+ updatedAt: computed20(() => updatedAtSignal())
4207
+ };
4208
+ }
4209
+ }
4210
+ VoiceTraceTimelineService = __decorateElement(_init, 0, "VoiceTraceTimelineService", _dec, VoiceTraceTimelineService);
4211
+ __runInitializers(_init, 1, VoiceTraceTimelineService);
4212
+ __decoratorMetadata(_init, VoiceTraceTimelineService);
4213
+ let _VoiceTraceTimelineService = VoiceTraceTimelineService;
4214
+ // src/angular/voice-agent-squad-status.service.ts
4215
+ import { computed as computed21, Injectable as Injectable22, signal as signal22 } from "@angular/core";
4216
+
4217
+ // src/client/agentSquadStatus.ts
4218
+ var getString = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
4219
+ var getPayloadString = (event, key) => getString(event.payload?.[key]);
4220
+ var eventStatus = (event) => {
4221
+ const status = getPayloadString(event, "status");
4222
+ if (status === "blocked")
4223
+ return "blocked";
4224
+ if (status === "unknown-target")
4225
+ return "unknown-target";
4226
+ if (status === "allowed")
4227
+ return "handoff";
4228
+ return event.type === "agent.result" ? "active" : "handoff";
4229
+ };
4230
+ var deriveSessionSpecialist = (session) => {
4231
+ const events = [...session.events].sort((left, right) => left.at - right.at);
4232
+ const agentEvents = events.filter((event) => event.type === "agent.handoff" || event.type === "agent.context" || event.type === "agent.result" || event.type === "agent.model");
4233
+ const latest = agentEvents.at(-1);
4234
+ if (!latest) {
4235
+ return {
4236
+ lastEventAt: session.lastEventAt,
4237
+ sessionId: session.sessionId,
4238
+ status: "idle"
4239
+ };
4240
+ }
4241
+ const handoffEvents = events.filter((event) => event.type === "agent.handoff");
4242
+ const lastHandoff = handoffEvents.at(-1);
4243
+ const latestAgentId = getPayloadString(latest, "agentId");
4244
+ const handoffStatus = lastHandoff ? eventStatus(lastHandoff) : undefined;
4245
+ const currentTarget = handoffStatus === "blocked" || handoffStatus === "unknown-target" ? getPayloadString(lastHandoff, "fromAgentId") ?? latestAgentId : getPayloadString(lastHandoff ?? latest, "targetAgentId") ?? latestAgentId;
4246
+ return {
4247
+ fromAgentId: getPayloadString(lastHandoff ?? latest, "fromAgentId"),
4248
+ lastEventAt: latest.at,
4249
+ reason: getPayloadString(lastHandoff ?? latest, "reason") ?? getPayloadString(latest, "handoffTarget"),
4250
+ sessionId: session.sessionId,
4251
+ status: lastHandoff ? eventStatus(lastHandoff) : "active",
4252
+ summary: getPayloadString(lastHandoff ?? latest, "summary"),
4253
+ targetAgentId: currentTarget,
4254
+ turnId: latest.turnId
4255
+ };
4256
+ };
4257
+ var buildVoiceAgentSquadStatusReport = (timeline, options = {}) => {
4258
+ const sessions = (timeline?.sessions ?? []).filter((session) => !options.sessionId || session.sessionId === options.sessionId).map(deriveSessionSpecialist).sort((left, right) => (right.lastEventAt ?? 0) - (left.lastEventAt ?? 0));
4259
+ const active = sessions.filter((session) => session.status !== "idle");
4260
+ return {
4261
+ active,
4262
+ checkedAt: timeline?.checkedAt,
4263
+ current: active[0] ?? sessions[0],
4264
+ sessionCount: sessions.length,
4265
+ sessions
4266
+ };
4267
+ };
4268
+ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}) => {
4269
+ const timelineStore = createVoiceTraceTimelineStore(path, options);
4270
+ const getReport = () => buildVoiceAgentSquadStatusReport(timelineStore.getSnapshot().report, {
4271
+ sessionId: options.sessionId
4272
+ });
4273
+ const getSnapshot = () => {
4274
+ const snapshot = timelineStore.getSnapshot();
4275
+ return {
4276
+ error: snapshot.error,
4277
+ isLoading: snapshot.isLoading,
4278
+ report: getReport(),
4279
+ updatedAt: snapshot.updatedAt
4280
+ };
4281
+ };
4282
+ return {
4283
+ close: timelineStore.close,
4284
+ getServerSnapshot: getSnapshot,
4285
+ getSnapshot,
4286
+ refresh: timelineStore.refresh,
4287
+ subscribe: timelineStore.subscribe
4288
+ };
4289
+ };
4290
+
4291
+ // src/angular/voice-agent-squad-status.service.ts
4292
+ var _dec = [
4293
+ Injectable22({ providedIn: "root" })
4294
+ ];
4295
+ var _init = __decoratorStart(undefined);
4296
+
4297
+ class VoiceAgentSquadStatusService {
4298
+ connect(path = "/api/voice-traces", options = {}) {
4299
+ const store = createVoiceAgentSquadStatusStore(path, options);
4300
+ const errorSignal = signal22(null);
4301
+ const isLoadingSignal = signal22(false);
4302
+ const reportSignal = signal22(undefined);
4303
+ const updatedAtSignal = signal22(undefined);
4304
+ const sync = () => {
4305
+ const snapshot = store.getSnapshot();
4306
+ errorSignal.set(snapshot.error);
4307
+ isLoadingSignal.set(snapshot.isLoading);
4308
+ reportSignal.set(snapshot.report);
4309
+ updatedAtSignal.set(snapshot.updatedAt);
4310
+ };
4311
+ const unsubscribe = store.subscribe(sync);
4312
+ sync();
4313
+ store.refresh().catch(() => {});
4314
+ return {
4315
+ close: () => {
4316
+ unsubscribe();
4317
+ store.close();
4318
+ },
4319
+ current: computed21(() => reportSignal()?.current),
4320
+ error: computed21(() => errorSignal()),
4321
+ isLoading: computed21(() => isLoadingSignal()),
4322
+ refresh: store.refresh,
4323
+ report: computed21(() => reportSignal()),
4324
+ updatedAt: computed21(() => updatedAtSignal())
4325
+ };
4326
+ }
4327
+ }
4328
+ VoiceAgentSquadStatusService = __decorateElement(_init, 0, "VoiceAgentSquadStatusService", _dec, VoiceAgentSquadStatusService);
4329
+ __runInitializers(_init, 1, VoiceAgentSquadStatusService);
4330
+ __decoratorMetadata(_init, VoiceAgentSquadStatusService);
4331
+ let _VoiceAgentSquadStatusService = VoiceAgentSquadStatusService;
4332
+ // src/angular/voice-turn-latency.service.ts
4333
+ import { computed as computed22, Injectable as Injectable23, signal as signal23 } from "@angular/core";
4334
+
4335
+ // src/client/turnLatency.ts
4336
+ var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
4337
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4338
+ const response = await fetchImpl(path);
4339
+ if (!response.ok) {
4340
+ throw new Error(`Voice turn latency failed: HTTP ${response.status}`);
4341
+ }
4342
+ return await response.json();
4343
+ };
4344
+ var runVoiceTurnLatencyProof = async (path, options = {}) => {
4345
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4346
+ const response = await fetchImpl(path, { method: "POST" });
4347
+ if (!response.ok) {
4348
+ throw new Error(`Voice turn latency proof failed: HTTP ${response.status}`);
4349
+ }
4350
+ return response.json();
4351
+ };
4352
+ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) => {
4353
+ const listeners = new Set;
4354
+ let closed = false;
4355
+ let timer;
4356
+ let snapshot = {
4357
+ error: null,
4358
+ isLoading: false
4359
+ };
4360
+ const emit = () => {
4361
+ for (const listener of listeners) {
4362
+ listener();
4363
+ }
4364
+ };
4365
+ const refresh = async () => {
4366
+ if (closed) {
4367
+ return snapshot.report;
4368
+ }
4369
+ snapshot = { ...snapshot, error: null, isLoading: true };
4370
+ emit();
4371
+ try {
4372
+ const report = await fetchVoiceTurnLatency(path, options);
4373
+ snapshot = {
4374
+ error: null,
4375
+ isLoading: false,
4376
+ report,
4377
+ updatedAt: Date.now()
4378
+ };
4379
+ emit();
4380
+ return report;
4381
+ } catch (error) {
4382
+ snapshot = {
4383
+ ...snapshot,
4384
+ error: error instanceof Error ? error.message : String(error),
4385
+ isLoading: false
4386
+ };
4387
+ emit();
4388
+ throw error;
4389
+ }
4390
+ };
4391
+ const runProof = async () => {
4392
+ if (!options.proofPath) {
4393
+ throw new Error("Voice turn latency proof path is not configured.");
4394
+ }
4395
+ snapshot = { ...snapshot, error: null, isLoading: true };
4396
+ emit();
4397
+ try {
4398
+ await runVoiceTurnLatencyProof(options.proofPath, options);
4399
+ return await refresh();
4400
+ } catch (error) {
4401
+ snapshot = {
4402
+ ...snapshot,
4403
+ error: error instanceof Error ? error.message : String(error),
4404
+ isLoading: false
4405
+ };
4406
+ emit();
4407
+ throw error;
4408
+ }
4409
+ };
4410
+ const close = () => {
4411
+ closed = true;
4412
+ if (timer) {
4413
+ clearInterval(timer);
4414
+ timer = undefined;
4415
+ }
4416
+ listeners.clear();
4417
+ };
4418
+ if (options.intervalMs && options.intervalMs > 0) {
4419
+ timer = setInterval(() => {
4420
+ refresh().catch(() => {});
4421
+ }, options.intervalMs);
4422
+ }
4423
+ return {
4424
+ close,
4425
+ getServerSnapshot: () => snapshot,
4426
+ getSnapshot: () => snapshot,
4427
+ refresh,
4428
+ runProof,
4429
+ subscribe: (listener) => {
4430
+ listeners.add(listener);
4431
+ return () => {
4432
+ listeners.delete(listener);
4433
+ };
4434
+ }
4435
+ };
4436
+ };
4437
+
4438
+ // src/angular/voice-turn-latency.service.ts
4439
+ var _dec = [
4440
+ Injectable23({ providedIn: "root" })
4441
+ ];
4442
+ var _init = __decoratorStart(undefined);
4443
+
4444
+ class VoiceTurnLatencyService {
4445
+ connect(path = "/api/turn-latency", options = {}) {
4446
+ const store = createVoiceTurnLatencyStore(path, options);
4447
+ const errorSignal = signal23(null);
4448
+ const isLoadingSignal = signal23(false);
4449
+ const reportSignal = signal23(undefined);
4450
+ const updatedAtSignal = signal23(undefined);
4451
+ const sync = () => {
4452
+ const snapshot = store.getSnapshot();
4453
+ errorSignal.set(snapshot.error);
4454
+ isLoadingSignal.set(snapshot.isLoading);
4455
+ reportSignal.set(snapshot.report);
4456
+ updatedAtSignal.set(snapshot.updatedAt);
4457
+ };
4458
+ const unsubscribe = store.subscribe(sync);
4459
+ sync();
4460
+ store.refresh().catch(() => {});
4461
+ return {
4462
+ close: () => {
4463
+ unsubscribe();
4464
+ store.close();
4465
+ },
4466
+ error: computed22(() => errorSignal()),
4467
+ isLoading: computed22(() => isLoadingSignal()),
4468
+ refresh: store.refresh,
4469
+ report: computed22(() => reportSignal()),
4470
+ runProof: store.runProof,
4471
+ updatedAt: computed22(() => updatedAtSignal())
4472
+ };
4473
+ }
4474
+ }
4475
+ VoiceTurnLatencyService = __decorateElement(_init, 0, "VoiceTurnLatencyService", _dec, VoiceTurnLatencyService);
4476
+ __runInitializers(_init, 1, VoiceTurnLatencyService);
4477
+ __decoratorMetadata(_init, VoiceTurnLatencyService);
4478
+ let _VoiceTurnLatencyService = VoiceTurnLatencyService;
4479
+ // src/angular/voice-turn-quality.service.ts
4480
+ import { computed as computed23, Injectable as Injectable24, signal as signal24 } from "@angular/core";
4481
+
4482
+ // src/client/turnQuality.ts
4483
+ var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
4484
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4485
+ const response = await fetchImpl(path);
4486
+ if (!response.ok) {
4487
+ throw new Error(`Voice turn quality failed: HTTP ${response.status}`);
4488
+ }
4489
+ return await response.json();
4490
+ };
4491
+ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) => {
4492
+ const listeners = new Set;
4493
+ let closed = false;
4494
+ let timer;
4495
+ let snapshot = {
4496
+ error: null,
4497
+ isLoading: false
4498
+ };
4499
+ const emit = () => {
4500
+ for (const listener of listeners) {
4501
+ listener();
4502
+ }
4503
+ };
4504
+ const refresh = async () => {
4505
+ if (closed) {
4506
+ return snapshot.report;
4507
+ }
4508
+ snapshot = {
4509
+ ...snapshot,
4510
+ error: null,
4511
+ isLoading: true
4512
+ };
4513
+ emit();
4514
+ try {
4515
+ const report = await fetchVoiceTurnQuality(path, options);
4516
+ snapshot = {
4517
+ error: null,
4518
+ isLoading: false,
4519
+ report,
4520
+ updatedAt: Date.now()
4521
+ };
4522
+ emit();
4523
+ return report;
4524
+ } catch (error) {
4525
+ snapshot = {
4526
+ ...snapshot,
4527
+ error: error instanceof Error ? error.message : String(error),
4528
+ isLoading: false
4529
+ };
4530
+ emit();
4531
+ throw error;
4532
+ }
4533
+ };
4534
+ const close = () => {
4535
+ closed = true;
4536
+ if (timer) {
4537
+ clearInterval(timer);
4538
+ timer = undefined;
4539
+ }
4540
+ listeners.clear();
4541
+ };
4542
+ if (options.intervalMs && options.intervalMs > 0) {
4543
+ timer = setInterval(() => {
4544
+ refresh().catch(() => {});
4545
+ }, options.intervalMs);
4546
+ }
4547
+ return {
4548
+ close,
4549
+ getServerSnapshot: () => snapshot,
4550
+ getSnapshot: () => snapshot,
4551
+ refresh,
4552
+ subscribe: (listener) => {
4553
+ listeners.add(listener);
4554
+ return () => {
4555
+ listeners.delete(listener);
4556
+ };
4557
+ }
4558
+ };
4559
+ };
4560
+
4561
+ // src/angular/voice-turn-quality.service.ts
4562
+ var _dec = [
4563
+ Injectable24({ providedIn: "root" })
4564
+ ];
4565
+ var _init = __decoratorStart(undefined);
4566
+
4567
+ class VoiceTurnQualityService {
4568
+ connect(path = "/api/turn-quality", options = {}) {
4569
+ const store = createVoiceTurnQualityStore(path, options);
4570
+ const errorSignal = signal24(null);
4571
+ const isLoadingSignal = signal24(false);
4572
+ const reportSignal = signal24(undefined);
4573
+ const updatedAtSignal = signal24(undefined);
4574
+ const sync = () => {
4575
+ const snapshot = store.getSnapshot();
4576
+ errorSignal.set(snapshot.error);
4577
+ isLoadingSignal.set(snapshot.isLoading);
4578
+ reportSignal.set(snapshot.report);
4579
+ updatedAtSignal.set(snapshot.updatedAt);
4580
+ };
4581
+ const unsubscribe = store.subscribe(sync);
4582
+ sync();
4583
+ store.refresh().catch(() => {});
4584
+ return {
4585
+ close: () => {
4586
+ unsubscribe();
4587
+ store.close();
4588
+ },
4589
+ error: computed23(() => errorSignal()),
4590
+ isLoading: computed23(() => isLoadingSignal()),
4591
+ refresh: store.refresh,
4592
+ report: computed23(() => reportSignal()),
4593
+ updatedAt: computed23(() => updatedAtSignal())
4594
+ };
4595
+ }
4596
+ }
4597
+ VoiceTurnQualityService = __decorateElement(_init, 0, "VoiceTurnQualityService", _dec, VoiceTurnQualityService);
4598
+ __runInitializers(_init, 1, VoiceTurnQualityService);
4599
+ __decoratorMetadata(_init, VoiceTurnQualityService);
4600
+ let _VoiceTurnQualityService = VoiceTurnQualityService;
4601
+ // src/angular/voice-workflow-status.service.ts
4602
+ import { computed as computed24, Injectable as Injectable25, signal as signal25 } from "@angular/core";
4603
+
4604
+ // src/client/workflowStatus.ts
4605
+ var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
4606
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4607
+ const response = await fetchImpl(path);
4608
+ if (!response.ok) {
4609
+ throw new Error(`Voice workflow status failed: HTTP ${response.status}`);
4610
+ }
4611
+ return await response.json();
4612
+ };
4613
+ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options = {}) => {
4614
+ const listeners = new Set;
4615
+ let closed = false;
4616
+ let timer;
4617
+ let snapshot = {
4618
+ error: null,
4619
+ isLoading: false
4620
+ };
4621
+ const emit = () => {
4622
+ for (const listener of listeners) {
4623
+ listener();
4624
+ }
4625
+ };
4626
+ const refresh = async () => {
4627
+ if (closed) {
4628
+ return snapshot.report;
4629
+ }
4630
+ snapshot = {
4631
+ ...snapshot,
4632
+ error: null,
4633
+ isLoading: true
4634
+ };
4635
+ emit();
4636
+ try {
4637
+ const report = await fetchVoiceWorkflowStatus(path, options);
4638
+ snapshot = {
4639
+ error: null,
4640
+ isLoading: false,
4641
+ report,
4642
+ updatedAt: Date.now()
4643
+ };
4644
+ emit();
4645
+ return report;
4646
+ } catch (error) {
4647
+ snapshot = {
4648
+ ...snapshot,
4649
+ error: error instanceof Error ? error.message : String(error),
4650
+ isLoading: false
4651
+ };
4652
+ emit();
4653
+ throw error;
4654
+ }
4655
+ };
4656
+ const close = () => {
4657
+ closed = true;
4658
+ if (timer) {
4659
+ clearInterval(timer);
4660
+ timer = undefined;
4661
+ }
4662
+ listeners.clear();
4663
+ };
4664
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
4665
+ timer = setInterval(() => {
4666
+ refresh().catch(() => {});
4667
+ }, options.intervalMs);
4668
+ }
4669
+ return {
4670
+ close,
4671
+ getServerSnapshot: () => snapshot,
4672
+ getSnapshot: () => snapshot,
4673
+ refresh,
4674
+ subscribe: (listener) => {
4675
+ listeners.add(listener);
4676
+ return () => {
4677
+ listeners.delete(listener);
4678
+ };
4679
+ }
4680
+ };
4681
+ };
4682
+
4683
+ // src/angular/voice-workflow-status.service.ts
4684
+ var _dec = [
4685
+ Injectable25({ providedIn: "root" })
4686
+ ];
4687
+ var _init = __decoratorStart(undefined);
4688
+
4689
+ class VoiceWorkflowStatusService {
4690
+ connect(path = "/evals/scenarios/json", options = {}) {
4691
+ const store = createVoiceWorkflowStatusStore(path, options);
4692
+ const errorSignal = signal25(null);
4693
+ const isLoadingSignal = signal25(false);
4694
+ const reportSignal = signal25(undefined);
4695
+ const updatedAtSignal = signal25(undefined);
4696
+ const sync = () => {
4697
+ const snapshot = store.getSnapshot();
4698
+ errorSignal.set(snapshot.error);
4699
+ isLoadingSignal.set(snapshot.isLoading);
4700
+ reportSignal.set(snapshot.report);
4701
+ updatedAtSignal.set(snapshot.updatedAt);
4702
+ };
4703
+ const unsubscribe = store.subscribe(sync);
4704
+ sync();
4705
+ if (typeof window !== "undefined") {
4706
+ store.refresh().catch(() => {});
4707
+ }
4708
+ return {
4709
+ close: () => {
4710
+ unsubscribe();
4711
+ store.close();
4712
+ },
4713
+ error: computed24(() => errorSignal()),
4714
+ isLoading: computed24(() => isLoadingSignal()),
4715
+ refresh: store.refresh,
4716
+ report: computed24(() => reportSignal()),
4717
+ updatedAt: computed24(() => updatedAtSignal())
4718
+ };
4719
+ }
4720
+ }
4721
+ VoiceWorkflowStatusService = __decorateElement(_init, 0, "VoiceWorkflowStatusService", _dec, VoiceWorkflowStatusService);
4722
+ __runInitializers(_init, 1, VoiceWorkflowStatusService);
4723
+ __decoratorMetadata(_init, VoiceWorkflowStatusService);
4724
+ let _VoiceWorkflowStatusService = VoiceWorkflowStatusService;
1291
4725
  export {
4726
+ VoiceWorkflowStatusService,
4727
+ VoiceWidgetService,
4728
+ VoiceTurnQualityService,
4729
+ VoiceTurnLatencyService,
4730
+ VoiceTraceTimelineService,
1292
4731
  VoiceStreamService,
1293
- VoiceControllerService
4732
+ VoiceSessionSnapshotService,
4733
+ VoiceSessionObservabilityService,
4734
+ VoiceRoutingStatusService,
4735
+ VoiceReconnectProfileEvidenceService,
4736
+ VoiceReadinessFailuresService,
4737
+ VoiceProviderStatusService,
4738
+ VoiceProviderContractsService,
4739
+ VoiceProviderCapabilitiesService,
4740
+ VoiceProofTrendsService,
4741
+ VoiceProfileComparisonService,
4742
+ VoicePlatformCoverageService,
4743
+ VoiceOpsStatusService,
4744
+ VoiceOpsActionCenterService,
4745
+ VoiceLiveOpsService,
4746
+ VoiceDeliveryRuntimeService,
4747
+ VoiceControllerService,
4748
+ VoiceCampaignDialerProofService,
4749
+ VoiceCallDebuggerService,
4750
+ VoiceAgentSquadStatusService
1294
4751
  };