@absolutejs/voice 0.0.22-beta.51 → 0.0.22-beta.511

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 (435) 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 +36 -5
  9. package/dist/angular/index.js +4004 -338
  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-call-player.service.d.ts +19 -0
  13. package/dist/angular/voice-campaign-dialer-proof.service.d.ts +14 -0
  14. package/dist/angular/voice-controller.service.d.ts +3 -1
  15. package/dist/angular/voice-cost-dashboard.service.d.ts +15 -0
  16. package/dist/angular/voice-delivery-runtime.component.d.ts +17 -0
  17. package/dist/angular/voice-delivery-runtime.service.d.ts +16 -0
  18. package/dist/angular/voice-live-agent-console.service.d.ts +16 -0
  19. package/dist/angular/voice-live-call-viewer.service.d.ts +16 -0
  20. package/dist/angular/voice-live-ops.service.d.ts +11 -0
  21. package/dist/angular/voice-ops-action-center.service.d.ts +13 -0
  22. package/dist/angular/voice-ops-status.component.d.ts +15 -0
  23. package/dist/angular/voice-ops-status.service.d.ts +12 -0
  24. package/dist/angular/voice-platform-coverage.service.d.ts +12 -0
  25. package/dist/angular/voice-profile-comparison.service.d.ts +12 -0
  26. package/dist/angular/voice-proof-trends.service.d.ts +12 -0
  27. package/dist/angular/voice-provider-capabilities.service.d.ts +12 -0
  28. package/dist/angular/voice-provider-contracts.service.d.ts +12 -0
  29. package/dist/angular/voice-provider-status.service.d.ts +2 -2
  30. package/dist/angular/voice-readiness-failures.service.d.ts +13 -0
  31. package/dist/angular/voice-reconnect-profile-evidence.service.d.ts +12 -0
  32. package/dist/angular/voice-replay-timeline.service.d.ts +13 -0
  33. package/dist/angular/voice-routing-status.service.d.ts +11 -0
  34. package/dist/angular/voice-session-observability.service.d.ts +12 -0
  35. package/dist/angular/voice-session-snapshot.service.d.ts +13 -0
  36. package/dist/angular/voice-stream.service.d.ts +4 -1
  37. package/dist/angular/voice-trace-timeline.service.d.ts +12 -0
  38. package/dist/angular/voice-turn-latency.service.d.ts +13 -0
  39. package/dist/angular/voice-turn-quality.service.d.ts +12 -0
  40. package/dist/angular/voice-widget.service.d.ts +18 -0
  41. package/dist/angular/voice-workflow-status.service.d.ts +2 -2
  42. package/dist/assistant.d.ts +12 -13
  43. package/dist/assistantExperiment.d.ts +41 -0
  44. package/dist/assistantHealth.d.ts +6 -6
  45. package/dist/assistantMemory.d.ts +3 -3
  46. package/dist/assistantMode.d.ts +22 -0
  47. package/dist/audioConditioning.d.ts +1 -1
  48. package/dist/audit.d.ts +131 -0
  49. package/dist/auditDeliveryRoutes.d.ts +85 -0
  50. package/dist/auditExport.d.ts +34 -0
  51. package/dist/auditRoutes.d.ts +66 -0
  52. package/dist/auditSinks.d.ts +151 -0
  53. package/dist/backchannel.d.ts +18 -0
  54. package/dist/bargeInRoutes.d.ts +56 -0
  55. package/dist/browserCallProfiles.d.ts +120 -0
  56. package/dist/browserMediaRoutes.d.ts +62 -0
  57. package/dist/callDebugger.d.ts +66 -0
  58. package/dist/callDisposition.d.ts +38 -0
  59. package/dist/callQuota.d.ts +54 -0
  60. package/dist/callerMemory.d.ts +37 -0
  61. package/dist/callingWindow.d.ts +26 -0
  62. package/dist/campaign.d.ts +794 -0
  63. package/dist/campaignControls.d.ts +37 -0
  64. package/dist/campaignDialers.d.ts +111 -0
  65. package/dist/campaignTemplate.d.ts +16 -0
  66. package/dist/client/actions.d.ts +95 -1
  67. package/dist/client/agentSquadStatus.d.ts +37 -0
  68. package/dist/client/agentSquadStatusWidget.d.ts +24 -0
  69. package/dist/client/audioPlayer.d.ts +2 -2
  70. package/dist/client/bargeInMonitor.d.ts +7 -0
  71. package/dist/client/browserMedia.d.ts +8 -0
  72. package/dist/client/browserNoiseSuppression.d.ts +42 -0
  73. package/dist/client/browserVoiceSupport.d.ts +22 -0
  74. package/dist/client/callDebugger.d.ts +19 -0
  75. package/dist/client/callDebuggerWidget.d.ts +30 -0
  76. package/dist/client/callPlayer.d.ts +41 -0
  77. package/dist/client/campaignDialerProof.d.ts +23 -0
  78. package/dist/client/connection.d.ts +4 -3
  79. package/dist/client/controller.d.ts +1 -1
  80. package/dist/client/conversationAnalytics.d.ts +29 -0
  81. package/dist/client/costDashboard.d.ts +27 -0
  82. package/dist/client/createVoiceStream.d.ts +1 -1
  83. package/dist/client/deliveryRuntime.d.ts +34 -0
  84. package/dist/client/deliveryRuntimeWidget.d.ts +37 -0
  85. package/dist/client/duplex.d.ts +2 -2
  86. package/dist/client/htmx.d.ts +1 -1
  87. package/dist/client/htmxAttributes.d.ts +28 -0
  88. package/dist/client/htmxBootstrap.js +967 -14
  89. package/dist/client/htmxDashboardRenderers.d.ts +72 -0
  90. package/dist/client/index.d.ts +104 -13
  91. package/dist/client/index.js +10142 -26
  92. package/dist/client/liveAgentConsole.d.ts +28 -0
  93. package/dist/client/liveCallViewer.d.ts +42 -0
  94. package/dist/client/liveOps.d.ts +22 -0
  95. package/dist/client/liveOpsWidget.d.ts +23 -0
  96. package/dist/client/liveTurnLatency.d.ts +41 -0
  97. package/dist/client/microphone.d.ts +4 -4
  98. package/dist/client/opsActionCenter.d.ts +54 -0
  99. package/dist/client/opsActionCenterWidget.d.ts +29 -0
  100. package/dist/client/opsActionHistory.d.ts +19 -0
  101. package/dist/client/opsActionHistoryWidget.d.ts +11 -0
  102. package/dist/client/opsStatus.d.ts +19 -0
  103. package/dist/client/opsStatusWidget.d.ts +40 -0
  104. package/dist/client/platformCoverage.d.ts +19 -0
  105. package/dist/client/platformCoverageWidget.d.ts +37 -0
  106. package/dist/client/profileComparison.d.ts +19 -0
  107. package/dist/client/profileComparisonWidget.d.ts +41 -0
  108. package/dist/client/profileSwitchRecommendation.d.ts +19 -0
  109. package/dist/client/profileSwitchRecommendationWidget.d.ts +12 -0
  110. package/dist/client/proofTrends.d.ts +19 -0
  111. package/dist/client/proofTrendsWidget.d.ts +37 -0
  112. package/dist/client/providerCapabilities.d.ts +19 -0
  113. package/dist/client/providerCapabilitiesWidget.d.ts +32 -0
  114. package/dist/client/providerContracts.d.ts +19 -0
  115. package/dist/client/providerContractsWidget.d.ts +37 -0
  116. package/dist/client/providerSimulationControls.d.ts +33 -0
  117. package/dist/client/providerSimulationControlsWidget.d.ts +20 -0
  118. package/dist/client/providerStatus.d.ts +1 -1
  119. package/dist/client/providerStatusWidget.d.ts +32 -0
  120. package/dist/client/readinessFailures.d.ts +19 -0
  121. package/dist/client/readinessFailuresWidget.d.ts +42 -0
  122. package/dist/client/reconnectProfileEvidence.d.ts +19 -0
  123. package/dist/client/reconnectProfileEvidenceWidget.d.ts +39 -0
  124. package/dist/client/replayTimeline.d.ts +26 -0
  125. package/dist/client/routingStatus.d.ts +19 -0
  126. package/dist/client/routingStatusWidget.d.ts +32 -0
  127. package/dist/client/sessionObservability.d.ts +19 -0
  128. package/dist/client/sessionObservabilityWidget.d.ts +31 -0
  129. package/dist/client/sessionSnapshot.d.ts +21 -0
  130. package/dist/client/sessionSnapshotWidget.d.ts +33 -0
  131. package/dist/client/store.d.ts +1 -1
  132. package/dist/client/traceTimeline.d.ts +19 -0
  133. package/dist/client/traceTimelineWidget.d.ts +36 -0
  134. package/dist/client/turnLatency.d.ts +22 -0
  135. package/dist/client/turnLatencyWidget.d.ts +33 -0
  136. package/dist/client/turnQuality.d.ts +19 -0
  137. package/dist/client/turnQualityWidget.d.ts +32 -0
  138. package/dist/client/voiceWidgetView.d.ts +50 -0
  139. package/dist/client/workflowStatus.d.ts +1 -1
  140. package/dist/competitiveCoverage.d.ts +141 -0
  141. package/dist/correction.d.ts +2 -2
  142. package/dist/costAccounting.d.ts +76 -0
  143. package/dist/costPredictor.d.ts +74 -0
  144. package/dist/dataControl.d.ts +180 -0
  145. package/dist/defineVoiceAssistant.d.ts +68 -0
  146. package/dist/deliveryRuntime.d.ts +158 -0
  147. package/dist/deliverySinkRoutes.d.ts +117 -0
  148. package/dist/demoReadyRoutes.d.ts +98 -0
  149. package/dist/diagnosticsRoutes.d.ts +2 -2
  150. package/dist/dncRegistry.d.ts +38 -0
  151. package/dist/dtmfCollector.d.ts +37 -0
  152. package/dist/evalRoutes.d.ts +10 -4
  153. package/dist/fileStore.d.ts +21 -7
  154. package/dist/generated/htmxBootstrapBundle.d.ts +1 -0
  155. package/dist/guardrails.d.ts +128 -0
  156. package/dist/handoff.d.ts +6 -6
  157. package/dist/handoffHealth.d.ts +5 -5
  158. package/dist/holdAudio.d.ts +23 -0
  159. package/dist/htmx.d.ts +1 -1
  160. package/dist/htmxDashboardRoutes.d.ts +249 -0
  161. package/dist/iceServers.d.ts +34 -0
  162. package/dist/incidentBundle.d.ts +119 -0
  163. package/dist/incidentTimeline.d.ts +260 -0
  164. package/dist/index.d.ts +324 -74
  165. package/dist/index.js +42843 -6521
  166. package/dist/ivrPlan.d.ts +40 -0
  167. package/dist/latencySlo.d.ts +56 -0
  168. package/dist/liveCoach.d.ts +43 -0
  169. package/dist/liveLatency.d.ts +78 -0
  170. package/dist/liveOps.d.ts +190 -0
  171. package/dist/llmJudge.d.ts +45 -0
  172. package/dist/logger.d.ts +1 -1
  173. package/dist/mediaPipelineRoutes.d.ts +171 -0
  174. package/dist/mediaPipelineSurfaces.d.ts +48 -0
  175. package/dist/memoryStore.d.ts +1 -1
  176. package/dist/midCallSummary.d.ts +27 -0
  177. package/dist/modelAdapters.d.ts +59 -7
  178. package/dist/monitor.d.ts +148 -0
  179. package/dist/multilingualProof.d.ts +77 -0
  180. package/dist/oauth2TokenSource.d.ts +21 -0
  181. package/dist/observabilityExport.d.ts +501 -0
  182. package/dist/openaiTTS.d.ts +18 -0
  183. package/dist/operationalStatus.d.ts +87 -0
  184. package/dist/operationsRecord.d.ts +370 -0
  185. package/dist/ops.d.ts +12 -12
  186. package/dist/opsActionAuditRoutes.d.ts +99 -0
  187. package/dist/opsConsoleRoutes.d.ts +8 -5
  188. package/dist/opsPresets.d.ts +2 -2
  189. package/dist/opsRecovery.d.ts +137 -0
  190. package/dist/opsRuntime.d.ts +6 -6
  191. package/dist/opsSinks.d.ts +13 -13
  192. package/dist/opsStatus.d.ts +76 -0
  193. package/dist/opsStatusRoutes.d.ts +33 -0
  194. package/dist/opsWebhook.d.ts +6 -6
  195. package/dist/otelExporter.d.ts +83 -0
  196. package/dist/outcomeContract.d.ts +146 -0
  197. package/dist/outcomeRecipes.d.ts +4 -4
  198. package/dist/phoneAgent.d.ts +139 -0
  199. package/dist/phoneAgentProductionSmoke.d.ts +115 -0
  200. package/dist/phoneProvisioning.d.ts +29 -0
  201. package/dist/platformCoverage.d.ts +91 -0
  202. package/dist/plugin.d.ts +2 -2
  203. package/dist/postCallAnalysis.d.ts +98 -0
  204. package/dist/postCallSurvey.d.ts +41 -0
  205. package/dist/postgresStore.d.ts +17 -6
  206. package/dist/presets.d.ts +3 -3
  207. package/dist/productionReadiness.d.ts +756 -0
  208. package/dist/profileSwitchRecommendation.d.ts +350 -0
  209. package/dist/promptInjectionGuard.d.ts +30 -0
  210. package/dist/proofAssertions.d.ts +32 -0
  211. package/dist/proofPack.d.ts +211 -0
  212. package/dist/proofRunner.d.ts +79 -0
  213. package/dist/proofTrends.d.ts +966 -0
  214. package/dist/providerAdapters.d.ts +16 -5
  215. package/dist/providerCapabilities.d.ts +92 -0
  216. package/dist/providerDecisionTraces.d.ts +130 -0
  217. package/dist/providerHealth.d.ts +3 -3
  218. package/dist/providerOrchestration.d.ts +109 -0
  219. package/dist/providerRouterTraces.d.ts +35 -0
  220. package/dist/providerRoutingContract.d.ts +71 -0
  221. package/dist/providerSlo.d.ts +142 -0
  222. package/dist/providerStackRecommendations.d.ts +187 -0
  223. package/dist/qualityRoutes.d.ts +4 -4
  224. package/dist/queue.d.ts +23 -14
  225. package/dist/ragTool.d.ts +57 -0
  226. package/dist/react/VoiceAgentSquadStatus.d.ts +5 -0
  227. package/dist/react/VoiceCallDebuggerLaunch.d.ts +6 -0
  228. package/dist/react/VoiceCallPlayer.d.ts +11 -0
  229. package/dist/react/VoiceCostDashboard.d.ts +10 -0
  230. package/dist/react/VoiceDeliveryRuntime.d.ts +7 -0
  231. package/dist/react/VoiceLiveAgentConsole.d.ts +11 -0
  232. package/dist/react/VoiceLiveCallViewer.d.ts +9 -0
  233. package/dist/react/VoiceOpsActionCenter.d.ts +5 -0
  234. package/dist/react/VoiceOpsStatus.d.ts +6 -0
  235. package/dist/react/VoicePlatformCoverage.d.ts +6 -0
  236. package/dist/react/VoiceProfileComparison.d.ts +6 -0
  237. package/dist/react/VoiceProfileSwitchRecommendation.d.ts +6 -0
  238. package/dist/react/VoiceProofTrends.d.ts +6 -0
  239. package/dist/react/VoiceProviderCapabilities.d.ts +6 -0
  240. package/dist/react/VoiceProviderContracts.d.ts +6 -0
  241. package/dist/react/VoiceProviderSimulationControls.d.ts +5 -0
  242. package/dist/react/VoiceProviderStatus.d.ts +6 -0
  243. package/dist/react/VoiceReadinessFailures.d.ts +6 -0
  244. package/dist/react/VoiceReconnectProfileEvidence.d.ts +6 -0
  245. package/dist/react/VoiceReplayTimeline.d.ts +6 -0
  246. package/dist/react/VoiceRoutingStatus.d.ts +6 -0
  247. package/dist/react/VoiceSessionObservability.d.ts +6 -0
  248. package/dist/react/VoiceSessionSnapshot.d.ts +6 -0
  249. package/dist/react/VoiceTraceTimeline.d.ts +6 -0
  250. package/dist/react/VoiceTurnLatency.d.ts +6 -0
  251. package/dist/react/VoiceTurnQuality.d.ts +6 -0
  252. package/dist/react/VoiceWidget.d.ts +13 -0
  253. package/dist/react/index.d.ts +59 -5
  254. package/dist/react/index.js +12733 -168
  255. package/dist/react/useVoiceAgentSquadStatus.d.ts +8 -0
  256. package/dist/react/useVoiceCallDebugger.d.ts +8 -0
  257. package/dist/react/useVoiceCampaignDialerProof.d.ts +10 -0
  258. package/dist/react/useVoiceController.d.ts +4 -1
  259. package/dist/react/useVoiceDeliveryRuntime.d.ts +13 -0
  260. package/dist/react/useVoiceLiveOps.d.ts +9 -0
  261. package/dist/react/useVoiceOpsActionCenter.d.ts +11 -0
  262. package/dist/react/useVoiceOpsStatus.d.ts +8 -0
  263. package/dist/react/useVoicePlatformCoverage.d.ts +8 -0
  264. package/dist/react/useVoiceProfileComparison.d.ts +8 -0
  265. package/dist/react/useVoiceProfileSwitchRecommendation.d.ts +8 -0
  266. package/dist/react/useVoiceProofTrends.d.ts +8 -0
  267. package/dist/react/useVoiceProviderCapabilities.d.ts +8 -0
  268. package/dist/react/useVoiceProviderContracts.d.ts +8 -0
  269. package/dist/react/useVoiceProviderSimulationControls.d.ts +10 -0
  270. package/dist/react/useVoiceProviderStatus.d.ts +1 -1
  271. package/dist/react/useVoiceReadinessFailures.d.ts +8 -0
  272. package/dist/react/useVoiceReconnectProfileEvidence.d.ts +8 -0
  273. package/dist/react/useVoiceRoutingStatus.d.ts +8 -0
  274. package/dist/react/useVoiceSessionObservability.d.ts +8 -0
  275. package/dist/react/useVoiceSessionSnapshot.d.ts +9 -0
  276. package/dist/react/useVoiceStream.d.ts +4 -1
  277. package/dist/react/useVoiceTraceTimeline.d.ts +8 -0
  278. package/dist/react/useVoiceTurnLatency.d.ts +9 -0
  279. package/dist/react/useVoiceTurnQuality.d.ts +8 -0
  280. package/dist/react/useVoiceWorkflowStatus.d.ts +1 -1
  281. package/dist/readinessProfiles.d.ts +45 -0
  282. package/dist/realtimeChannel.d.ts +136 -0
  283. package/dist/realtimeProviderContracts.d.ts +133 -0
  284. package/dist/reconnectContract.d.ts +176 -0
  285. package/dist/recordingRedaction.d.ts +18 -0
  286. package/dist/recordingStore.d.ts +60 -0
  287. package/dist/redaction.d.ts +13 -0
  288. package/dist/resilienceRoutes.d.ts +45 -5
  289. package/dist/retention.d.ts +37 -0
  290. package/dist/retryPolicy.d.ts +38 -0
  291. package/dist/routeAuth.d.ts +58 -0
  292. package/dist/routing.d.ts +1 -1
  293. package/dist/runtimeOps.d.ts +3 -3
  294. package/dist/s3Store.d.ts +18 -3
  295. package/dist/semanticTurn.d.ts +27 -0
  296. package/dist/session.d.ts +1 -1
  297. package/dist/sessionObservability.d.ts +145 -0
  298. package/dist/sessionReplay.d.ts +19 -7
  299. package/dist/sessionSnapshot.d.ts +109 -0
  300. package/dist/simulationSuite.d.ts +143 -0
  301. package/dist/sloCalibration.d.ts +185 -0
  302. package/dist/sqliteStore.d.ts +17 -6
  303. package/dist/store.d.ts +1 -1
  304. package/dist/supervisorPermissions.d.ts +33 -0
  305. package/dist/supervisorPresence.d.ts +49 -0
  306. package/dist/svelte/createVoiceAgentSquadStatus.d.ts +9 -0
  307. package/dist/svelte/createVoiceCallDebugger.d.ts +12 -0
  308. package/dist/svelte/createVoiceCallPlayer.d.ts +33 -0
  309. package/dist/svelte/createVoiceCampaignDialerProof.d.ts +9 -0
  310. package/dist/svelte/createVoiceCostDashboard.d.ts +13 -0
  311. package/dist/svelte/createVoiceDeliveryRuntime.d.ts +11 -0
  312. package/dist/svelte/createVoiceLiveAgentConsole.d.ts +23 -0
  313. package/dist/svelte/createVoiceLiveCallViewer.d.ts +26 -0
  314. package/dist/svelte/createVoiceLiveOps.d.ts +13 -0
  315. package/dist/svelte/createVoiceOpsActionCenter.d.ts +10 -0
  316. package/dist/svelte/createVoiceOpsStatus.d.ts +9 -0
  317. package/dist/svelte/createVoicePlatformCoverage.d.ts +7 -0
  318. package/dist/svelte/createVoiceProfileComparison.d.ts +7 -0
  319. package/dist/svelte/createVoiceProofTrends.d.ts +7 -0
  320. package/dist/svelte/createVoiceProviderCapabilities.d.ts +10 -0
  321. package/dist/svelte/createVoiceProviderContracts.d.ts +10 -0
  322. package/dist/svelte/createVoiceProviderSimulationControls.d.ts +11 -0
  323. package/dist/svelte/createVoiceProviderStatus.d.ts +4 -2
  324. package/dist/svelte/createVoiceReadinessFailures.d.ts +7 -0
  325. package/dist/svelte/createVoiceReconnectProfileEvidence.d.ts +7 -0
  326. package/dist/svelte/createVoiceReplayTimeline.d.ts +13 -0
  327. package/dist/svelte/createVoiceRoutingStatus.d.ts +10 -0
  328. package/dist/svelte/createVoiceSessionObservability.d.ts +10 -0
  329. package/dist/svelte/createVoiceSessionSnapshot.d.ts +13 -0
  330. package/dist/svelte/createVoiceStream.d.ts +1 -1
  331. package/dist/svelte/createVoiceTraceTimeline.d.ts +10 -0
  332. package/dist/svelte/createVoiceTurnLatency.d.ts +11 -0
  333. package/dist/svelte/createVoiceTurnQuality.d.ts +10 -0
  334. package/dist/svelte/createVoiceWidget.d.ts +19 -0
  335. package/dist/svelte/createVoiceWorkflowStatus.d.ts +1 -1
  336. package/dist/svelte/index.d.ts +37 -5
  337. package/dist/svelte/index.js +6931 -684
  338. package/dist/telephony/contract.d.ts +61 -0
  339. package/dist/telephony/matrix.d.ts +97 -0
  340. package/dist/telephony/plivo.d.ts +303 -0
  341. package/dist/telephony/response.d.ts +1 -1
  342. package/dist/telephony/security.d.ts +182 -0
  343. package/dist/telephony/telnyx.d.ts +291 -0
  344. package/dist/telephony/twilio.d.ts +147 -13
  345. package/dist/telephonyMediaRoutes.d.ts +72 -0
  346. package/dist/telephonyOutcome.d.ts +273 -0
  347. package/dist/testing/accuracy.d.ts +1 -1
  348. package/dist/testing/benchmark.d.ts +9 -9
  349. package/dist/testing/corrected.d.ts +5 -5
  350. package/dist/testing/duplex.d.ts +3 -3
  351. package/dist/testing/fixtures.d.ts +3 -3
  352. package/dist/testing/index.d.ts +13 -13
  353. package/dist/testing/index.js +5223 -159
  354. package/dist/testing/ioProviderSimulator.d.ts +5 -5
  355. package/dist/testing/providerSimulator.d.ts +5 -5
  356. package/dist/testing/review.d.ts +4 -4
  357. package/dist/testing/sessionBenchmark.d.ts +3 -3
  358. package/dist/testing/stt.d.ts +3 -3
  359. package/dist/testing/telephony.d.ts +25 -0
  360. package/dist/testing/tts.d.ts +1 -1
  361. package/dist/toolContract.d.ts +161 -0
  362. package/dist/toolRuntime.d.ts +50 -0
  363. package/dist/trace.d.ts +46 -7
  364. package/dist/traceDeliveryRoutes.d.ts +86 -0
  365. package/dist/traceTimeline.d.ts +97 -0
  366. package/dist/transcriptAnnotator.d.ts +41 -0
  367. package/dist/turnDetection.d.ts +1 -1
  368. package/dist/turnLatency.d.ts +95 -0
  369. package/dist/turnProfiles.d.ts +2 -2
  370. package/dist/turnQuality.d.ts +94 -0
  371. package/dist/types.d.ts +293 -80
  372. package/dist/vapiAdapter.d.ts +160 -0
  373. package/dist/voiceMonitoring.d.ts +444 -0
  374. package/dist/vue/VoiceCallDebuggerLaunch.d.ts +68 -0
  375. package/dist/vue/VoiceCallPlayer.d.ts +40 -0
  376. package/dist/vue/VoiceCostDashboard.d.ts +57 -0
  377. package/dist/vue/VoiceDeliveryRuntime.d.ts +30 -0
  378. package/dist/vue/VoiceLiveAgentConsole.d.ts +50 -0
  379. package/dist/vue/VoiceLiveCallViewer.d.ts +35 -0
  380. package/dist/vue/VoiceOpsActionCenter.d.ts +13 -0
  381. package/dist/vue/VoiceOpsStatus.d.ts +30 -0
  382. package/dist/vue/VoicePlatformCoverage.d.ts +23 -0
  383. package/dist/vue/VoiceProofTrends.d.ts +21 -0
  384. package/dist/vue/VoiceProviderCapabilities.d.ts +51 -0
  385. package/dist/vue/VoiceProviderContracts.d.ts +21 -0
  386. package/dist/vue/VoiceProviderSimulationControls.d.ts +88 -0
  387. package/dist/vue/VoiceProviderStatus.d.ts +51 -0
  388. package/dist/vue/VoiceReadinessFailures.d.ts +21 -0
  389. package/dist/vue/VoiceReconnectProfileEvidence.d.ts +21 -0
  390. package/dist/vue/VoiceReplayTimeline.d.ts +17 -0
  391. package/dist/vue/VoiceRoutingStatus.d.ts +51 -0
  392. package/dist/vue/VoiceSessionObservability.d.ts +23 -0
  393. package/dist/vue/VoiceSessionSnapshot.d.ts +68 -0
  394. package/dist/vue/VoiceTurnLatency.d.ts +69 -0
  395. package/dist/vue/VoiceTurnQuality.d.ts +51 -0
  396. package/dist/vue/VoiceWidget.d.ts +77 -0
  397. package/dist/vue/index.d.ts +49 -5
  398. package/dist/vue/index.js +11954 -226
  399. package/dist/vue/useVoiceAgentSquadStatus.d.ts +9 -0
  400. package/dist/vue/useVoiceCallDebugger.d.ts +10 -0
  401. package/dist/vue/useVoiceCampaignDialerProof.d.ts +11 -0
  402. package/dist/vue/useVoiceController.d.ts +4 -2
  403. package/dist/vue/useVoiceDeliveryRuntime.d.ts +13 -0
  404. package/dist/vue/useVoiceLiveOps.d.ts +9 -0
  405. package/dist/vue/useVoiceOpsActionCenter.d.ts +11 -0
  406. package/dist/vue/useVoiceOpsStatus.d.ts +9 -0
  407. package/dist/vue/useVoicePlatformCoverage.d.ts +9 -0
  408. package/dist/vue/useVoiceProfileComparison.d.ts +9 -0
  409. package/dist/vue/useVoiceProofTrends.d.ts +9 -0
  410. package/dist/vue/useVoiceProviderCapabilities.d.ts +9 -0
  411. package/dist/vue/useVoiceProviderContracts.d.ts +9 -0
  412. package/dist/vue/useVoiceProviderSimulationControls.d.ts +24 -0
  413. package/dist/vue/useVoiceProviderStatus.d.ts +3 -3
  414. package/dist/vue/useVoiceReadinessFailures.d.ts +959 -0
  415. package/dist/vue/useVoiceReconnectProfileEvidence.d.ts +9 -0
  416. package/dist/vue/useVoiceRoutingStatus.d.ts +8 -0
  417. package/dist/vue/useVoiceSessionObservability.d.ts +9 -0
  418. package/dist/vue/useVoiceSessionSnapshot.d.ts +10 -0
  419. package/dist/vue/useVoiceStream.d.ts +5 -2
  420. package/dist/vue/useVoiceTraceTimeline.d.ts +9 -0
  421. package/dist/vue/useVoiceTurnLatency.d.ts +10 -0
  422. package/dist/vue/useVoiceTurnQuality.d.ts +9 -0
  423. package/dist/vue/useVoiceWorkflowStatus.d.ts +3 -3
  424. package/dist/webhookFanout.d.ts +48 -0
  425. package/dist/webhookVerification.d.ts +27 -0
  426. package/dist/whisperChannel.d.ts +50 -0
  427. package/dist/workflowContract.d.ts +8 -8
  428. package/fixtures/manifest.json +356 -197
  429. package/package.json +265 -256
  430. package/dist/angular/voice-app-kit-status.service.d.ts +0 -12
  431. package/dist/appKit.d.ts +0 -92
  432. package/dist/client/appKitStatus.d.ts +0 -19
  433. package/dist/react/useVoiceAppKitStatus.d.ts +0 -8
  434. package/dist/svelte/createVoiceAppKitStatus.d.ts +0 -8
  435. package/dist/vue/useVoiceAppKitStatus.d.ts +0 -9
@@ -68,20 +68,21 @@ 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-app-kit-status.service.ts
73
+ // src/angular/voice-ops-status.service.ts
73
74
  import { computed, Injectable, signal } from "@angular/core";
74
75
 
75
- // src/client/appKitStatus.ts
76
- var fetchVoiceAppKitStatus = async (path = "/app-kit/status", options = {}) => {
76
+ // src/client/opsStatus.ts
77
+ var fetchVoiceOpsStatus = async (path = "/api/voice/ops-status", options = {}) => {
77
78
  const fetchImpl = options.fetch ?? globalThis.fetch;
78
79
  const response = await fetchImpl(path);
79
80
  if (!response.ok) {
80
- throw new Error(`Voice app kit status failed: HTTP ${response.status}`);
81
+ throw new Error(`Voice ops status failed: HTTP ${response.status}`);
81
82
  }
82
83
  return await response.json();
83
84
  };
84
- var createVoiceAppKitStatusStore = (path = "/app-kit/status", options = {}) => {
85
+ var createVoiceOpsStatusStore = (path = "/api/voice/ops-status", options = {}) => {
85
86
  const listeners = new Set;
86
87
  let closed = false;
87
88
  let timer;
@@ -105,7 +106,7 @@ var createVoiceAppKitStatusStore = (path = "/app-kit/status", options = {}) => {
105
106
  };
106
107
  emit();
107
108
  try {
108
- const report = await fetchVoiceAppKitStatus(path, options);
109
+ const report = await fetchVoiceOpsStatus(path, options);
109
110
  snapshot = {
110
111
  error: null,
111
112
  isLoading: false,
@@ -151,15 +152,15 @@ var createVoiceAppKitStatusStore = (path = "/app-kit/status", options = {}) => {
151
152
  };
152
153
  };
153
154
 
154
- // src/angular/voice-app-kit-status.service.ts
155
+ // src/angular/voice-ops-status.service.ts
155
156
  var _dec = [
156
157
  Injectable({ providedIn: "root" })
157
158
  ];
158
159
  var _init = __decoratorStart(undefined);
159
160
 
160
- class VoiceAppKitStatusService {
161
- connect(path = "/app-kit/status", options = {}) {
162
- const store = createVoiceAppKitStatusStore(path, options);
161
+ class VoiceOpsStatusService {
162
+ connect(path = "/api/voice/ops-status", options = {}) {
163
+ const store = createVoiceOpsStatusStore(path, options);
163
164
  const errorSignal = signal(null);
164
165
  const isLoadingSignal = signal(false);
165
166
  const reportSignal = signal(undefined);
@@ -189,13 +190,155 @@ class VoiceAppKitStatusService {
189
190
  };
190
191
  }
191
192
  }
192
- VoiceAppKitStatusService = __decorateElement(_init, 0, "VoiceAppKitStatusService", _dec, VoiceAppKitStatusService);
193
- __runInitializers(_init, 1, VoiceAppKitStatusService);
194
- __decoratorMetadata(_init, VoiceAppKitStatusService);
195
- let _VoiceAppKitStatusService = VoiceAppKitStatusService;
196
- // src/angular/voice-stream.service.ts
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
197
198
  import { computed as computed2, Injectable as Injectable2, signal as signal2 } from "@angular/core";
198
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
+
199
342
  // src/client/actions.ts
200
343
  var normalizeErrorMessage = (value) => {
201
344
  if (typeof value === "string" && value.trim()) {
@@ -244,6 +387,11 @@ var serverMessageToAction = (message) => {
244
387
  sessionId: message.sessionId,
245
388
  type: "complete"
246
389
  };
390
+ case "connection":
391
+ return {
392
+ reconnect: message.reconnect,
393
+ type: "connection"
394
+ };
247
395
  case "call_lifecycle":
248
396
  return {
249
397
  event: message.event,
@@ -265,9 +413,22 @@ var serverMessageToAction = (message) => {
265
413
  transcript: message.transcript,
266
414
  type: "partial"
267
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
+ };
268
428
  case "session":
269
429
  return {
270
430
  sessionId: message.sessionId,
431
+ sessionMetadata: message.sessionMetadata,
271
432
  scenarioId: message.scenarioId,
272
433
  status: message.status,
273
434
  type: "session"
@@ -282,6 +443,84 @@ var serverMessageToAction = (message) => {
282
443
  }
283
444
  };
284
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
+
285
524
  // src/client/connection.ts
286
525
  var WS_OPEN = 1;
287
526
  var WS_CLOSED = 3;
@@ -301,6 +540,7 @@ var NOOP_CONNECTION = {
301
540
  getSessionId: () => "",
302
541
  send: noop,
303
542
  sendAudio: noop,
543
+ simulateDisconnect: noop,
304
544
  start: () => {},
305
545
  subscribe: noopUnsubscribe
306
546
  };
@@ -325,10 +565,12 @@ var isVoiceServerMessage = (value) => {
325
565
  case "assistant":
326
566
  case "call_lifecycle":
327
567
  case "complete":
568
+ case "connection":
328
569
  case "error":
329
570
  case "final":
330
571
  case "partial":
331
572
  case "pong":
573
+ case "replay":
332
574
  case "session":
333
575
  case "turn":
334
576
  return true;
@@ -365,6 +607,9 @@ var createVoiceConnection = (path, options = {}) => {
365
607
  sessionId: options.sessionId ?? createSessionId(),
366
608
  ws: null
367
609
  };
610
+ const emitConnection = (reconnect) => {
611
+ listeners.forEach((listener) => listener(reconnect));
612
+ };
368
613
  const clearTimers = () => {
369
614
  if (state.pingInterval) {
370
615
  clearInterval(state.pingInterval);
@@ -387,9 +632,28 @@ var createVoiceConnection = (path, options = {}) => {
387
632
  }
388
633
  };
389
634
  const scheduleReconnect = () => {
635
+ const nextAttemptAt = Date.now() + RECONNECT_DELAY_MS;
390
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
+ });
391
647
  state.reconnectTimeout = setTimeout(() => {
392
648
  if (state.reconnectAttempts > maxReconnectAttempts) {
649
+ emitConnection({
650
+ reconnect: {
651
+ attempts: state.reconnectAttempts,
652
+ maxAttempts: maxReconnectAttempts,
653
+ status: "exhausted"
654
+ },
655
+ type: "connection"
656
+ });
393
657
  return;
394
658
  }
395
659
  connect();
@@ -399,9 +663,21 @@ var createVoiceConnection = (path, options = {}) => {
399
663
  const ws = new WebSocket(buildWsUrl(path, state.sessionId, state.scenarioId));
400
664
  ws.binaryType = "arraybuffer";
401
665
  ws.onopen = () => {
666
+ const wasReconnecting = state.reconnectAttempts > 0;
402
667
  state.isConnected = true;
403
- state.reconnectAttempts = 0;
404
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
+ }
405
681
  listeners.forEach((listener) => listener({
406
682
  scenarioId: state.scenarioId ?? undefined,
407
683
  sessionId: state.sessionId,
@@ -431,6 +707,16 @@ var createVoiceConnection = (path, options = {}) => {
431
707
  const reconnectable = shouldReconnect && event.code !== WS_NORMAL_CLOSURE && state.reconnectAttempts < maxReconnectAttempts;
432
708
  if (reconnectable) {
433
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
+ });
434
720
  }
435
721
  };
436
722
  state.ws = ws;
@@ -479,6 +765,11 @@ var createVoiceConnection = (path, options = {}) => {
479
765
  state.isConnected = false;
480
766
  listeners.clear();
481
767
  };
768
+ const simulateDisconnect = () => {
769
+ if (state.ws?.readyState === WS_OPEN) {
770
+ state.ws.close(4000, "absolutejs-voice-reconnect-proof");
771
+ }
772
+ };
482
773
  const subscribe = (callback) => {
483
774
  listeners.add(callback);
484
775
  return () => {
@@ -495,20 +786,28 @@ var createVoiceConnection = (path, options = {}) => {
495
786
  getSessionId: () => state.sessionId,
496
787
  send,
497
788
  sendAudio,
789
+ simulateDisconnect,
498
790
  start,
499
791
  subscribe
500
792
  };
501
793
  };
502
794
 
503
795
  // src/client/store.ts
796
+ var createInitialReconnectState = () => ({
797
+ attempts: 0,
798
+ maxAttempts: 0,
799
+ status: "idle"
800
+ });
504
801
  var createInitialState = () => ({
505
802
  assistantAudio: [],
506
803
  assistantTexts: [],
507
804
  call: null,
508
805
  error: null,
509
806
  isConnected: false,
807
+ sessionMetadata: null,
510
808
  scenarioId: null,
511
809
  partial: "",
810
+ reconnect: createInitialReconnectState(),
512
811
  sessionId: null,
513
812
  status: "idle",
514
813
  turns: []
@@ -565,7 +864,19 @@ var createVoiceStreamStore = () => {
565
864
  case "connected":
566
865
  state = {
567
866
  ...state,
568
- 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
569
880
  };
570
881
  break;
571
882
  case "disconnected":
@@ -593,6 +904,27 @@ var createVoiceStreamStore = () => {
593
904
  partial: action.transcript.text
594
905
  };
595
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;
596
928
  case "session":
597
929
  state = {
598
930
  ...state,
@@ -600,6 +932,7 @@ var createVoiceStreamStore = () => {
600
932
  scenarioId: action.scenarioId ?? state.scenarioId,
601
933
  isConnected: action.status === "active",
602
934
  sessionId: action.sessionId,
935
+ sessionMetadata: action.sessionMetadata ?? state.sessionMetadata,
603
936
  status: action.status
604
937
  };
605
938
  break;
@@ -630,20 +963,50 @@ var createVoiceStreamStore = () => {
630
963
  var createVoiceStream = (path, options = {}) => {
631
964
  const connection = createVoiceConnection(path, options);
632
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;
633
971
  const subscribers = new Set;
634
972
  const start = (input) => Promise.resolve().then(() => {
635
973
  if (!input?.sessionId && !input?.scenarioId) {
636
974
  return;
637
975
  }
638
976
  connection.start(input);
977
+ browserMediaReporter?.start();
639
978
  });
640
979
  const notify = () => {
641
980
  subscribers.forEach((subscriber) => subscriber());
642
981
  };
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
+ };
643
1003
  const unsubscribeConnection = connection.subscribe((message) => {
644
1004
  const action = serverMessageToAction(message);
645
1005
  if (action) {
646
1006
  store.dispatch(action);
1007
+ if (message.type === "connection") {
1008
+ reportReconnect();
1009
+ }
647
1010
  notify();
648
1011
  }
649
1012
  });
@@ -653,6 +1016,7 @@ var createVoiceStream = (path, options = {}) => {
653
1016
  },
654
1017
  close() {
655
1018
  unsubscribeConnection();
1019
+ browserMediaReporter?.close();
656
1020
  connection.close();
657
1021
  store.dispatch({ type: "disconnected" });
658
1022
  notify();
@@ -675,10 +1039,16 @@ var createVoiceStream = (path, options = {}) => {
675
1039
  get scenarioId() {
676
1040
  return store.getSnapshot().scenarioId;
677
1041
  },
1042
+ get sessionMetadata() {
1043
+ return store.getSnapshot().sessionMetadata;
1044
+ },
678
1045
  start,
679
1046
  get partial() {
680
1047
  return store.getSnapshot().partial;
681
1048
  },
1049
+ get reconnect() {
1050
+ return store.getSnapshot().reconnect;
1051
+ },
682
1052
  get sessionId() {
683
1053
  return connection.getSessionId();
684
1054
  },
@@ -700,6 +1070,9 @@ var createVoiceStream = (path, options = {}) => {
700
1070
  sendAudio(audio) {
701
1071
  connection.sendAudio(audio);
702
1072
  },
1073
+ simulateDisconnect() {
1074
+ connection.simulateDisconnect();
1075
+ },
703
1076
  subscribe(subscriber) {
704
1077
  subscribers.add(subscriber);
705
1078
  return () => {
@@ -709,214 +1082,14 @@ var createVoiceStream = (path, options = {}) => {
709
1082
  };
710
1083
  };
711
1084
 
712
- // src/angular/voice-stream.service.ts
713
- var _dec = [
714
- Injectable2({ providedIn: "root" })
715
- ];
716
- var _init = __decoratorStart(undefined);
717
-
718
- class VoiceStreamService {
719
- connect(path, options = {}) {
720
- const stream = createVoiceStream(path, options);
721
- const assistantAudioSignal = signal2([]);
722
- const assistantTextsSignal = signal2([]);
723
- const callSignal = signal2(null);
724
- const errorSignal = signal2(null);
725
- const isConnectedSignal = signal2(false);
726
- const partialSignal = signal2("");
727
- const sessionIdSignal = signal2(stream.sessionId);
728
- const statusSignal = signal2(stream.status);
729
- const turnsSignal = signal2([]);
730
- const sync = () => {
731
- assistantAudioSignal.set([...stream.assistantAudio]);
732
- assistantTextsSignal.set([...stream.assistantTexts]);
733
- callSignal.set(stream.call);
734
- errorSignal.set(stream.error);
735
- isConnectedSignal.set(stream.isConnected);
736
- partialSignal.set(stream.partial);
737
- sessionIdSignal.set(stream.sessionId);
738
- statusSignal.set(stream.status);
739
- turnsSignal.set([...stream.turns]);
740
- };
741
- const unsubscribe = stream.subscribe(sync);
742
- sync();
743
- return {
744
- assistantAudio: computed2(() => assistantAudioSignal()),
745
- assistantTexts: computed2(() => assistantTextsSignal()),
746
- call: computed2(() => callSignal()),
747
- callControl: (message) => stream.callControl(message),
748
- close: () => {
749
- unsubscribe();
750
- stream.close();
751
- },
752
- endTurn: () => stream.endTurn(),
753
- error: computed2(() => errorSignal()),
754
- isConnected: computed2(() => isConnectedSignal()),
755
- partial: computed2(() => partialSignal()),
756
- sendAudio: (audio) => stream.sendAudio(audio),
757
- sessionId: computed2(() => sessionIdSignal()),
758
- status: computed2(() => statusSignal()),
759
- turns: computed2(() => turnsSignal())
760
- };
761
- }
762
- }
763
- VoiceStreamService = __decorateElement(_init, 0, "VoiceStreamService", _dec, VoiceStreamService);
764
- __runInitializers(_init, 1, VoiceStreamService);
765
- __decoratorMetadata(_init, VoiceStreamService);
766
- let _VoiceStreamService = VoiceStreamService;
767
- // src/angular/voice-controller.service.ts
768
- import { computed as computed3, Injectable as Injectable3, signal as signal3 } from "@angular/core";
769
-
770
- // src/client/htmx.ts
771
- var DEFAULT_EVENT_NAME = "voice-refresh";
772
- var DEFAULT_QUERY_PARAM = "sessionId";
773
- var resolveElement = (input) => {
774
- if (typeof input !== "string") {
775
- return input;
776
- }
777
- return document.querySelector(input);
778
- };
779
- var buildRoute = (element, route, queryParam, sessionId) => {
780
- const baseRoute = route ?? element.getAttribute("hx-get") ?? "";
781
- if (!baseRoute) {
782
- return "";
783
- }
784
- const url = new URL(baseRoute, window.location.origin);
785
- if (sessionId) {
786
- url.searchParams.set(queryParam, sessionId);
787
- } else {
788
- url.searchParams.delete(queryParam);
789
- }
790
- return `${url.pathname}${url.search}${url.hash}`;
791
- };
792
- var bindVoiceHTMX = (stream, options) => {
793
- if (typeof window === "undefined" || typeof document === "undefined") {
794
- return () => {};
795
- }
796
- const element = resolveElement(options.element);
797
- if (!element) {
798
- return () => {};
799
- }
800
- const eventName = options.eventName ?? DEFAULT_EVENT_NAME;
801
- const queryParam = options.sessionQueryParam ?? DEFAULT_QUERY_PARAM;
802
- const sync = () => {
803
- const htmxWindow = window;
804
- const nextRoute = buildRoute(element, options.route, queryParam, stream.sessionId);
805
- if (nextRoute) {
806
- element.setAttribute("hx-get", nextRoute);
807
- }
808
- htmxWindow.htmx?.process?.(element);
809
- htmxWindow.htmx?.trigger?.(element, eventName);
810
- };
811
- const unsubscribe = stream.subscribe(sync);
812
- sync();
813
- return () => {
814
- unsubscribe();
815
- };
816
- };
817
-
818
- // src/client/microphone.ts
819
- var clampSample = (value) => Math.max(-1, Math.min(1, value));
820
- var floatTo16BitPCM = (input) => {
821
- const output = new Int16Array(input.length);
822
- for (let index = 0;index < input.length; index += 1) {
823
- const sample = clampSample(input[index] ?? 0);
824
- output[index] = sample < 0 ? sample * 32768 : sample * 32767;
825
- }
826
- return new Uint8Array(output.buffer);
827
- };
828
- var getPcmLevel = (audio) => {
829
- const bytes = audio instanceof Uint8Array ? audio : new Uint8Array(audio);
830
- if (bytes.byteLength < 2) {
831
- return 0;
832
- }
833
- const samples = new Int16Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 2));
834
- if (samples.length === 0) {
835
- return 0;
836
- }
837
- let sumSquares = 0;
838
- for (const sample of samples) {
839
- const normalized = sample / 32768;
840
- sumSquares += normalized * normalized;
841
- }
842
- return Math.min(1, Math.max(0, Math.sqrt(sumSquares / samples.length) * 5.5));
843
- };
844
- var downsampleBuffer = (input, sourceRate, targetRate) => {
845
- if (sourceRate === targetRate) {
846
- return input;
847
- }
848
- const ratio = sourceRate / targetRate;
849
- const length = Math.round(input.length / ratio);
850
- const output = new Float32Array(length);
851
- let offsetResult = 0;
852
- let offsetBuffer = 0;
853
- while (offsetResult < output.length) {
854
- const nextOffsetBuffer = Math.round((offsetResult + 1) * ratio);
855
- let accum = 0;
856
- let count = 0;
857
- for (let index = offsetBuffer;index < nextOffsetBuffer && index < input.length; index += 1) {
858
- accum += input[index] ?? 0;
859
- count += 1;
860
- }
861
- output[offsetResult] = count > 0 ? accum / count : 0;
862
- offsetResult += 1;
863
- offsetBuffer = nextOffsetBuffer;
864
- }
865
- return output;
866
- };
867
- var createMicrophoneCapture = (options) => {
868
- let audioContext = null;
869
- let sourceNode = null;
870
- let processorNode = null;
871
- let mediaStream = null;
872
- const start = async () => {
873
- if (typeof navigator === "undefined" || !navigator.mediaDevices?.getUserMedia) {
874
- throw new Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");
875
- }
876
- const AudioContextCtor = (typeof window !== "undefined" ? window.AudioContext ?? window.webkitAudioContext : undefined) ?? AudioContext;
877
- if (!AudioContextCtor) {
878
- throw new Error("Browser microphone capture requires AudioContext support.");
879
- }
880
- mediaStream = await navigator.mediaDevices.getUserMedia({
881
- audio: {
882
- channelCount: options.channelCount ?? 1
883
- }
884
- });
885
- audioContext = new AudioContextCtor;
886
- sourceNode = audioContext.createMediaStreamSource(mediaStream);
887
- processorNode = audioContext.createScriptProcessor(4096, 1, 1);
888
- processorNode.onaudioprocess = (event) => {
889
- const channel = event.inputBuffer.getChannelData(0);
890
- const downsampled = downsampleBuffer(channel, audioContext?.sampleRate ?? 48000, options.sampleRateHz ?? 16000);
891
- const pcm = floatTo16BitPCM(downsampled);
892
- options.onLevel?.(getPcmLevel(pcm));
893
- options.onAudio(pcm);
894
- };
895
- sourceNode.connect(processorNode);
896
- processorNode.connect(audioContext.destination);
897
- };
898
- const stop = () => {
899
- processorNode?.disconnect();
900
- sourceNode?.disconnect();
901
- mediaStream?.getTracks().forEach((track) => track.stop());
902
- audioContext?.close();
903
- options.onLevel?.(0);
904
- audioContext = null;
905
- mediaStream = null;
906
- processorNode = null;
907
- sourceNode = null;
908
- };
909
- return { start, stop };
910
- };
911
-
912
- // src/audioConditioning.ts
913
- var DEFAULT_TARGET_LEVEL = 0.08;
914
- var DEFAULT_MAX_GAIN = 3;
915
- var DEFAULT_NOISE_GATE_THRESHOLD = 0.006;
916
- var DEFAULT_NOISE_GATE_ATTENUATION = 0.15;
917
- var toInt16Array = (audio) => {
918
- if (audio instanceof ArrayBuffer) {
919
- return new Int16Array(audio, 0, Math.floor(audio.byteLength / 2));
1085
+ // src/audioConditioning.ts
1086
+ var DEFAULT_TARGET_LEVEL = 0.08;
1087
+ var DEFAULT_MAX_GAIN = 3;
1088
+ var DEFAULT_NOISE_GATE_THRESHOLD = 0.006;
1089
+ var DEFAULT_NOISE_GATE_ATTENUATION = 0.15;
1090
+ var toInt16Array = (audio) => {
1091
+ if (audio instanceof ArrayBuffer) {
1092
+ return new Int16Array(audio, 0, Math.floor(audio.byteLength / 2));
920
1093
  }
921
1094
  return new Int16Array(audio.buffer, audio.byteOffset, Math.floor(audio.byteLength / 2));
922
1095
  };
@@ -1234,8 +1407,10 @@ var createInitialState2 = (stream) => ({
1234
1407
  isConnected: stream.isConnected,
1235
1408
  isRecording: false,
1236
1409
  partial: stream.partial,
1410
+ reconnect: stream.reconnect,
1237
1411
  recordingError: null,
1238
1412
  sessionId: stream.sessionId,
1413
+ sessionMetadata: stream.sessionMetadata,
1239
1414
  scenarioId: stream.scenarioId,
1240
1415
  status: stream.status,
1241
1416
  turns: [...stream.turns]
@@ -1263,7 +1438,9 @@ var createVoiceController = (path, options = {}) => {
1263
1438
  error: stream.error,
1264
1439
  isConnected: stream.isConnected,
1265
1440
  partial: stream.partial,
1441
+ reconnect: stream.reconnect,
1266
1442
  sessionId: stream.sessionId,
1443
+ sessionMetadata: stream.sessionMetadata,
1267
1444
  scenarioId: stream.scenarioId,
1268
1445
  status: stream.status,
1269
1446
  turns: [...stream.turns]
@@ -1287,7 +1464,13 @@ var createVoiceController = (path, options = {}) => {
1287
1464
  capture = createMicrophoneCapture({
1288
1465
  channelCount: options.capture?.channelCount ?? preset.capture.channelCount,
1289
1466
  onLevel: options.capture?.onLevel,
1290
- 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
+ },
1291
1474
  sampleRateHz: options.capture?.sampleRateHz ?? preset.capture.sampleRateHz
1292
1475
  });
1293
1476
  return capture;
@@ -1357,10 +1540,17 @@ var createVoiceController = (path, options = {}) => {
1357
1540
  get recordingError() {
1358
1541
  return state.recordingError;
1359
1542
  },
1543
+ get reconnect() {
1544
+ return state.reconnect;
1545
+ },
1360
1546
  sendAudio: (audio) => stream.sendAudio(audio),
1547
+ simulateDisconnect: () => stream.simulateDisconnect(),
1361
1548
  get sessionId() {
1362
1549
  return state.sessionId;
1363
1550
  },
1551
+ get sessionMetadata() {
1552
+ return state.sessionMetadata;
1553
+ },
1364
1554
  get scenarioId() {
1365
1555
  return state.scenarioId;
1366
1556
  },
@@ -1397,114 +1587,3441 @@ var createVoiceController = (path, options = {}) => {
1397
1587
  };
1398
1588
  };
1399
1589
 
1400
- // 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
1401
1727
  var _dec = [
1402
- Injectable3({ providedIn: "root" })
1728
+ Injectable2({ providedIn: "root" })
1403
1729
  ];
1404
1730
  var _init = __decoratorStart(undefined);
1405
1731
 
1406
- class VoiceControllerService {
1732
+ class VoiceWidgetService {
1407
1733
  connect(path, options = {}) {
1408
1734
  const controller = createVoiceController(path, options);
1409
- const assistantAudioSignal = signal3([]);
1410
- const assistantTextsSignal = signal3([]);
1411
- const errorSignal = signal3(null);
1412
- const isConnectedSignal = signal3(false);
1413
- const isRecordingSignal = signal3(false);
1414
- const partialSignal = signal3("");
1415
- const recordingErrorSignal = signal3(null);
1416
- const sessionIdSignal = signal3(controller.sessionId);
1417
- const statusSignal = signal3(controller.status);
1418
- const turnsSignal = signal3([]);
1735
+ const viewModelSignal = signal2(createVoiceWidgetViewModel({
1736
+ labels: options.labels,
1737
+ state: controller.getSnapshot(),
1738
+ theme: options.theme,
1739
+ title: options.title
1740
+ }));
1419
1741
  const sync = () => {
1420
- assistantAudioSignal.set([...controller.assistantAudio]);
1421
- assistantTextsSignal.set([...controller.assistantTexts]);
1422
- errorSignal.set(controller.error);
1423
- isConnectedSignal.set(controller.isConnected);
1424
- isRecordingSignal.set(controller.isRecording);
1425
- partialSignal.set(controller.partial);
1426
- recordingErrorSignal.set(controller.recordingError);
1427
- sessionIdSignal.set(controller.sessionId);
1428
- statusSignal.set(controller.status);
1429
- 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
+ }));
1430
1748
  };
1431
1749
  const unsubscribe = controller.subscribe(sync);
1432
1750
  sync();
1433
1751
  return {
1434
- assistantAudio: computed3(() => assistantAudioSignal()),
1435
- assistantTexts: computed3(() => assistantTextsSignal()),
1436
- bindHTMX: controller.bindHTMX,
1437
1752
  close: () => {
1438
1753
  unsubscribe();
1439
1754
  controller.close();
1440
1755
  },
1441
- endTurn: () => controller.endTurn(),
1442
- error: computed3(() => errorSignal()),
1443
- isConnected: computed3(() => isConnectedSignal()),
1444
- isRecording: computed3(() => isRecordingSignal()),
1445
- partial: computed3(() => partialSignal()),
1446
- recordingError: computed3(() => recordingErrorSignal()),
1447
- sendAudio: (audio) => controller.sendAudio(audio),
1448
- sessionId: computed3(() => sessionIdSignal()),
1449
- startRecording: () => controller.startRecording(),
1450
- status: computed3(() => statusSignal()),
1451
- stopRecording: () => controller.stopRecording(),
1452
- toggleRecording: () => controller.toggleRecording(),
1453
- turns: computed3(() => 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())
1454
1762
  };
1455
1763
  }
1456
1764
  }
1457
- VoiceControllerService = __decorateElement(_init, 0, "VoiceControllerService", _dec, VoiceControllerService);
1458
- __runInitializers(_init, 1, VoiceControllerService);
1459
- __decoratorMetadata(_init, VoiceControllerService);
1460
- let _VoiceControllerService = VoiceControllerService;
1461
- // src/angular/voice-provider-status.service.ts
1462
- import { computed as computed4, Injectable as Injectable4, signal as signal4 } from "@angular/core";
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-call-player.service.ts
1770
+ import { computed as computed3, Injectable as Injectable3, signal as signal3 } from "@angular/core";
1463
1771
 
1464
- // src/client/providerStatus.ts
1465
- var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
1466
- const fetchImpl = options.fetch ?? globalThis.fetch;
1467
- const response = await fetchImpl(path);
1468
- if (!response.ok) {
1469
- throw new Error(`Voice provider status failed: HTTP ${response.status}`);
1772
+ // src/client/callPlayer.ts
1773
+ var cloneState = (state) => ({
1774
+ ...state
1775
+ });
1776
+ var normalizeTranscriptTimes = (transcripts, baseEpoch) => {
1777
+ if (typeof baseEpoch !== "number") {
1778
+ return transcripts;
1470
1779
  }
1471
- return await response.json();
1780
+ return transcripts.map((transcript) => {
1781
+ const adjusted = { ...transcript };
1782
+ if (typeof adjusted.startedAtMs === "number" && adjusted.startedAtMs >= baseEpoch) {
1783
+ adjusted.startedAtMs = adjusted.startedAtMs - baseEpoch;
1784
+ }
1785
+ if (typeof adjusted.endedAtMs === "number" && adjusted.endedAtMs >= baseEpoch) {
1786
+ adjusted.endedAtMs = adjusted.endedAtMs - baseEpoch;
1787
+ }
1788
+ return adjusted;
1789
+ });
1472
1790
  };
1473
- var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {}) => {
1474
- const listeners = new Set;
1475
- let closed = false;
1476
- let timer;
1477
- let snapshot = {
1478
- error: null,
1479
- isLoading: false,
1480
- providers: []
1791
+ var findActiveTranscript = (transcripts, positionMs) => {
1792
+ let candidate;
1793
+ for (let index = 0;index < transcripts.length; index += 1) {
1794
+ const transcript = transcripts[index];
1795
+ if (typeof transcript.startedAtMs !== "number")
1796
+ continue;
1797
+ if (transcript.startedAtMs > positionMs)
1798
+ break;
1799
+ if (typeof transcript.endedAtMs === "number" && transcript.endedAtMs < positionMs) {
1800
+ continue;
1801
+ }
1802
+ candidate = { id: transcript.id, index };
1803
+ }
1804
+ return candidate ?? {};
1805
+ };
1806
+ var createVoiceCallPlayer = (options = {}) => {
1807
+ let transcripts = normalizeTranscriptTimes(options.transcripts ?? [], options.recordingStartedAtEpochMs);
1808
+ let state = {
1809
+ audioUrl: options.audioUrl,
1810
+ buffered: 0,
1811
+ currentTimeMs: 0,
1812
+ durationMs: 0,
1813
+ isPlaying: false,
1814
+ isReady: false,
1815
+ playbackRate: options.initialPlaybackRate ?? 1
1481
1816
  };
1482
- const emit = () => {
1483
- for (const listener of listeners) {
1817
+ const listeners = new Set;
1818
+ const notify = () => {
1819
+ for (const listener of listeners)
1484
1820
  listener();
1485
- }
1486
1821
  };
1487
- const refresh = async () => {
1488
- if (closed) {
1489
- return snapshot.providers;
1490
- }
1491
- snapshot = {
1492
- ...snapshot,
1493
- error: null,
1494
- isLoading: true
1495
- };
1496
- emit();
1497
- try {
1498
- const providers = await fetchVoiceProviderStatus(path, options);
1499
- snapshot = {
1500
- error: null,
1501
- isLoading: false,
1502
- providers,
1503
- updatedAt: Date.now()
1822
+ const update = (next) => {
1823
+ state = { ...state, ...next };
1824
+ notify();
1825
+ };
1826
+ const refreshActive = () => {
1827
+ const { id, index } = findActiveTranscript(transcripts, state.currentTimeMs);
1828
+ if (id !== state.activeTranscriptId || index !== state.activeTranscriptIndex) {
1829
+ state = {
1830
+ ...state,
1831
+ activeTranscriptId: id,
1832
+ activeTranscriptIndex: index
1504
1833
  };
1505
- emit();
1506
- return providers;
1507
- } catch (error) {
1834
+ notify();
1835
+ }
1836
+ };
1837
+ return {
1838
+ getState: () => cloneState(state),
1839
+ pause: () => {
1840
+ if (!state.isPlaying)
1841
+ return;
1842
+ update({ isPlaying: false });
1843
+ },
1844
+ play: async () => {
1845
+ update({ isPlaying: true });
1846
+ },
1847
+ reset: () => {
1848
+ state = {
1849
+ audioUrl: state.audioUrl,
1850
+ buffered: 0,
1851
+ currentTimeMs: 0,
1852
+ durationMs: 0,
1853
+ isPlaying: false,
1854
+ isReady: false,
1855
+ playbackRate: 1
1856
+ };
1857
+ notify();
1858
+ },
1859
+ seekMs: (positionMs) => {
1860
+ const clamped = Math.max(0, Math.min(state.durationMs || Number.POSITIVE_INFINITY, positionMs));
1861
+ update({ currentTimeMs: clamped });
1862
+ refreshActive();
1863
+ },
1864
+ seekToTranscript: (transcriptId) => {
1865
+ const found = transcripts.find((t) => t.id === transcriptId);
1866
+ if (!found || typeof found.startedAtMs !== "number") {
1867
+ return;
1868
+ }
1869
+ update({ currentTimeMs: Math.max(0, found.startedAtMs) });
1870
+ refreshActive();
1871
+ },
1872
+ setAudioUrl: (url) => {
1873
+ update({ audioUrl: url, isReady: false });
1874
+ },
1875
+ setBuffered: (seconds) => {
1876
+ update({ buffered: Math.max(0, seconds) });
1877
+ },
1878
+ setDuration: (durationMs) => {
1879
+ update({ durationMs: Math.max(0, durationMs) });
1880
+ },
1881
+ setError: (error) => {
1882
+ update({ error });
1883
+ },
1884
+ setPlaybackRate: (rate) => {
1885
+ update({ playbackRate: Math.max(0.25, Math.min(4, rate)) });
1886
+ },
1887
+ setPlaying: (playing) => {
1888
+ if (playing === state.isPlaying)
1889
+ return;
1890
+ update({ isPlaying: playing });
1891
+ },
1892
+ setReady: (ready) => {
1893
+ update({ isReady: ready });
1894
+ },
1895
+ setTime: (positionMs) => {
1896
+ const next = Math.max(0, positionMs);
1897
+ if (next === state.currentTimeMs)
1898
+ return;
1899
+ update({ currentTimeMs: next });
1900
+ refreshActive();
1901
+ },
1902
+ setTranscripts: (next) => {
1903
+ transcripts = normalizeTranscriptTimes(next, options.recordingStartedAtEpochMs);
1904
+ refreshActive();
1905
+ },
1906
+ subscribe: (listener) => {
1907
+ listeners.add(listener);
1908
+ return () => {
1909
+ listeners.delete(listener);
1910
+ };
1911
+ },
1912
+ transcripts: () => transcripts
1913
+ };
1914
+ };
1915
+ var formatVoiceCallPlayerTimestamp = (ms) => {
1916
+ const seconds = Math.max(0, Math.floor(ms / 1000));
1917
+ const minutes = Math.floor(seconds / 60);
1918
+ const remaining = seconds % 60;
1919
+ return `${String(minutes).padStart(2, "0")}:${String(remaining).padStart(2, "0")}`;
1920
+ };
1921
+
1922
+ // src/angular/voice-call-player.service.ts
1923
+ var _dec = [
1924
+ Injectable3({ providedIn: "root" })
1925
+ ];
1926
+ var _init = __decoratorStart(undefined);
1927
+
1928
+ class VoiceCallPlayerService {
1929
+ build(options = {}) {
1930
+ const player = createVoiceCallPlayer(options);
1931
+ const stateSignal = signal3(player.getState());
1932
+ const unsubscribe = player.subscribe(() => {
1933
+ stateSignal.set(player.getState());
1934
+ });
1935
+ return {
1936
+ formatTimestamp: formatVoiceCallPlayerTimestamp,
1937
+ pause: () => player.pause(),
1938
+ play: () => player.play(),
1939
+ seekMs: (ms) => player.seekMs(ms),
1940
+ seekToTranscript: (id) => player.seekToTranscript(id),
1941
+ setPlaybackRate: (rate) => player.setPlaybackRate(rate),
1942
+ setTime: (ms) => player.setTime(ms),
1943
+ state: computed3(() => stateSignal()),
1944
+ stop: () => unsubscribe(),
1945
+ title: options.title ?? "Call replay",
1946
+ transcripts: () => player.transcripts()
1947
+ };
1948
+ }
1949
+ }
1950
+ VoiceCallPlayerService = __decorateElement(_init, 0, "VoiceCallPlayerService", _dec, VoiceCallPlayerService);
1951
+ __runInitializers(_init, 1, VoiceCallPlayerService);
1952
+ __decoratorMetadata(_init, VoiceCallPlayerService);
1953
+ let _VoiceCallPlayerService = VoiceCallPlayerService;
1954
+ // src/angular/voice-cost-dashboard.service.ts
1955
+ import { computed as computed4, Injectable as Injectable4, signal as signal4 } from "@angular/core";
1956
+
1957
+ // src/client/costDashboard.ts
1958
+ var padTwo = (value) => String(value).padStart(2, "0");
1959
+ var formatBucketKey = (epochMs, bucketBy) => {
1960
+ const date = new Date(epochMs);
1961
+ const y = date.getUTCFullYear();
1962
+ const m = padTwo(date.getUTCMonth() + 1);
1963
+ const d = padTwo(date.getUTCDate());
1964
+ const h = padTwo(date.getUTCHours());
1965
+ if (bucketBy === "month")
1966
+ return `${y}-${m}`;
1967
+ if (bucketBy === "day")
1968
+ return `${y}-${m}-${d}`;
1969
+ return `${y}-${m}-${d}T${h}`;
1970
+ };
1971
+ var isCostBreakdown = (value) => Boolean(value) && typeof value === "object" && typeof value.totalUsd === "number";
1972
+ var emptyBucket = (bucketKey) => ({
1973
+ bucketKey,
1974
+ callCount: 0,
1975
+ llmUsd: 0,
1976
+ sttUsd: 0,
1977
+ telephonyMinutes: 0,
1978
+ telephonyUsd: 0,
1979
+ totalUsd: 0,
1980
+ ttsUsd: 0
1981
+ });
1982
+ var accumulate = (bucket, payload) => {
1983
+ bucket.callCount += 1;
1984
+ bucket.llmUsd += payload.llm.usd;
1985
+ bucket.sttUsd += payload.stt.usd;
1986
+ bucket.ttsUsd += payload.tts.usd;
1987
+ bucket.telephonyUsd += payload.telephony.usd;
1988
+ bucket.telephonyMinutes += payload.telephony.minutes;
1989
+ bucket.totalUsd += payload.totalUsd;
1990
+ };
1991
+ var roundCurrency = (bucket) => {
1992
+ bucket.llmUsd = Math.round(bucket.llmUsd * 1e6) / 1e6;
1993
+ bucket.sttUsd = Math.round(bucket.sttUsd * 1e6) / 1e6;
1994
+ bucket.ttsUsd = Math.round(bucket.ttsUsd * 1e6) / 1e6;
1995
+ bucket.telephonyUsd = Math.round(bucket.telephonyUsd * 1e6) / 1e6;
1996
+ bucket.totalUsd = Math.round(bucket.totalUsd * 1e6) / 1e6;
1997
+ };
1998
+ var buildVoiceCostDashboardReport = (options) => {
1999
+ const bucketBy = options.bucketBy ?? "day";
2000
+ const fromMs = options.fromMs ?? Number.NEGATIVE_INFINITY;
2001
+ const toMs = options.toMs ?? Number.POSITIVE_INFINITY;
2002
+ const buckets = new Map;
2003
+ const grandTotal = emptyBucket("total");
2004
+ let minMs = Number.POSITIVE_INFINITY;
2005
+ let maxMs = Number.NEGATIVE_INFINITY;
2006
+ for (const event of options.events) {
2007
+ if (event.type !== "cost.ready")
2008
+ continue;
2009
+ if (event.at < fromMs || event.at > toMs)
2010
+ continue;
2011
+ if (!isCostBreakdown(event.payload))
2012
+ continue;
2013
+ minMs = Math.min(minMs, event.at);
2014
+ maxMs = Math.max(maxMs, event.at);
2015
+ const bucketKey = formatBucketKey(event.at, bucketBy);
2016
+ let bucket = buckets.get(bucketKey);
2017
+ if (!bucket) {
2018
+ bucket = emptyBucket(bucketKey);
2019
+ buckets.set(bucketKey, bucket);
2020
+ }
2021
+ accumulate(bucket, event.payload);
2022
+ accumulate(grandTotal, event.payload);
2023
+ }
2024
+ for (const bucket of buckets.values()) {
2025
+ roundCurrency(bucket);
2026
+ }
2027
+ roundCurrency(grandTotal);
2028
+ return {
2029
+ buckets: Array.from(buckets.values()).sort((a, b) => a.bucketKey.localeCompare(b.bucketKey)),
2030
+ generatedAt: Date.now(),
2031
+ grandTotal,
2032
+ windowEndMs: Number.isFinite(maxMs) ? maxMs : 0,
2033
+ windowStartMs: Number.isFinite(minMs) ? minMs : 0
2034
+ };
2035
+ };
2036
+
2037
+ // src/angular/voice-cost-dashboard.service.ts
2038
+ var _dec = [
2039
+ Injectable4({ providedIn: "root" })
2040
+ ];
2041
+ var _init = __decoratorStart(undefined);
2042
+
2043
+ class VoiceCostDashboardService {
2044
+ build(options) {
2045
+ const events = signal4(options.events);
2046
+ const filters = signal4({
2047
+ bucketBy: options.bucketBy,
2048
+ fromMs: options.fromMs,
2049
+ toMs: options.toMs
2050
+ });
2051
+ const report = computed4(() => {
2052
+ const f = filters();
2053
+ return buildVoiceCostDashboardReport({
2054
+ bucketBy: f.bucketBy,
2055
+ events: events(),
2056
+ fromMs: f.fromMs,
2057
+ toMs: f.toMs
2058
+ });
2059
+ });
2060
+ return {
2061
+ currency: options.currency ?? "USD",
2062
+ report,
2063
+ setEvents: (next) => events.set(next),
2064
+ setFilters: (next) => filters.update((current) => ({
2065
+ ...current,
2066
+ bucketBy: next.bucketBy ?? current.bucketBy,
2067
+ fromMs: next.fromMs ?? current.fromMs,
2068
+ toMs: next.toMs ?? current.toMs
2069
+ })),
2070
+ title: options.title ?? "Voice cost dashboard"
2071
+ };
2072
+ }
2073
+ }
2074
+ VoiceCostDashboardService = __decorateElement(_init, 0, "VoiceCostDashboardService", _dec, VoiceCostDashboardService);
2075
+ __runInitializers(_init, 1, VoiceCostDashboardService);
2076
+ __decoratorMetadata(_init, VoiceCostDashboardService);
2077
+ let _VoiceCostDashboardService = VoiceCostDashboardService;
2078
+ // src/angular/voice-live-agent-console.service.ts
2079
+ import { computed as computed5, Injectable as Injectable5, signal as signal5 } from "@angular/core";
2080
+
2081
+ // src/client/liveCallViewer.ts
2082
+ var EVENT_BUFFER_LIMIT = 200;
2083
+ var createLiveCallViewer = (options) => {
2084
+ const bufferLimit = options.bufferLimit ?? EVENT_BUFFER_LIMIT;
2085
+ const subscribers = new Set;
2086
+ let state = {
2087
+ agentState: "idle",
2088
+ callDurationMs: 0,
2089
+ events: [],
2090
+ isConnected: true,
2091
+ isLiveListening: true,
2092
+ partialTranscript: "",
2093
+ sessionId: options.sessionId
2094
+ };
2095
+ const startedAt = options.startedAt ?? Date.now();
2096
+ const notify = () => {
2097
+ for (const subscriber of subscribers)
2098
+ subscriber();
2099
+ };
2100
+ const update = (next) => {
2101
+ state = { ...state, ...next };
2102
+ state.callDurationMs = Math.max(0, Date.now() - startedAt);
2103
+ state.agentState = deriveVoiceAgentUIState({
2104
+ hasActivePartial: state.partialTranscript.length > 0,
2105
+ isConnected: state.isConnected,
2106
+ isPlaying: false,
2107
+ isRecording: state.isLiveListening,
2108
+ lastAssistantAt: state.lastAssistantAt,
2109
+ lastTranscriptAt: state.lastTranscriptAt
2110
+ });
2111
+ notify();
2112
+ };
2113
+ const pushEvent = (event) => {
2114
+ const next = state.events.concat(event);
2115
+ if (next.length > bufferLimit) {
2116
+ next.splice(0, next.length - bufferLimit);
2117
+ }
2118
+ update({ events: next });
2119
+ };
2120
+ return {
2121
+ applyControl: (control) => {
2122
+ pushEvent({
2123
+ at: Date.now(),
2124
+ detail: control.reason,
2125
+ kind: "lifecycle",
2126
+ title: `control:${control.type}`
2127
+ });
2128
+ },
2129
+ applyEvent: pushEvent,
2130
+ applyMonitorEvent: ({ payload, type }) => {
2131
+ pushEvent({
2132
+ at: Date.now(),
2133
+ detail: JSON.stringify(payload).slice(0, 240),
2134
+ kind: type === "call.lifecycle" ? "lifecycle" : "lifecycle",
2135
+ title: type
2136
+ });
2137
+ },
2138
+ getState: () => state,
2139
+ noteAgentAudio: (at) => {
2140
+ const ts = at ?? Date.now();
2141
+ update({ lastAssistantAt: ts });
2142
+ pushEvent({
2143
+ at: ts,
2144
+ kind: "agent_audio",
2145
+ title: "Agent audio frame"
2146
+ });
2147
+ },
2148
+ notePartial: (text, at) => {
2149
+ update({ partialTranscript: text });
2150
+ if (text) {
2151
+ pushEvent({
2152
+ at: at ?? Date.now(),
2153
+ detail: text,
2154
+ kind: "transcript",
2155
+ title: "Partial"
2156
+ });
2157
+ }
2158
+ },
2159
+ noteTranscript: (text, at) => {
2160
+ const ts = at ?? Date.now();
2161
+ update({ lastTranscriptAt: ts, partialTranscript: "" });
2162
+ pushEvent({
2163
+ at: ts,
2164
+ detail: text,
2165
+ kind: "transcript",
2166
+ title: "Final transcript"
2167
+ });
2168
+ },
2169
+ reset: (sessionId, startedAtOverride) => {
2170
+ state = {
2171
+ agentState: "idle",
2172
+ callDurationMs: 0,
2173
+ events: [],
2174
+ isConnected: true,
2175
+ isLiveListening: true,
2176
+ partialTranscript: "",
2177
+ sessionId
2178
+ };
2179
+ if (typeof startedAtOverride === "number") {}
2180
+ notify();
2181
+ },
2182
+ subscribe: (subscriber) => {
2183
+ subscribers.add(subscriber);
2184
+ return () => subscribers.delete(subscriber);
2185
+ }
2186
+ };
2187
+ };
2188
+
2189
+ // src/client/liveAgentConsole.ts
2190
+ var createLiveAgentConsole = (options) => {
2191
+ const viewer = createLiveCallViewer(options);
2192
+ const recentLimit = Math.max(1, options.recentLimit ?? 12);
2193
+ let caller;
2194
+ let hasTakeover = false;
2195
+ let takeoverAt;
2196
+ let takeoverReason;
2197
+ const subscribers = new Set;
2198
+ const buildState = () => {
2199
+ const view = viewer.getState();
2200
+ return {
2201
+ caller,
2202
+ hasTakeover,
2203
+ recentTimeline: view.events.slice(-recentLimit),
2204
+ takeoverAt,
2205
+ takeoverReason,
2206
+ view
2207
+ };
2208
+ };
2209
+ const notify = () => {
2210
+ for (const subscriber of subscribers)
2211
+ subscriber();
2212
+ };
2213
+ const unsubscribeViewer = viewer.subscribe(() => {
2214
+ notify();
2215
+ });
2216
+ if (options.resolveCaller) {
2217
+ Promise.resolve(options.resolveCaller()).then((snapshot) => {
2218
+ caller = snapshot;
2219
+ notify();
2220
+ });
2221
+ }
2222
+ return {
2223
+ getState: buildState,
2224
+ noteAgentAudio: (at) => viewer.noteAgentAudio(at),
2225
+ notePartial: (text, at) => viewer.notePartial(text, at),
2226
+ noteTranscript: (text, at) => viewer.noteTranscript(text, at),
2227
+ releaseTakeover: () => {
2228
+ if (!hasTakeover)
2229
+ return;
2230
+ hasTakeover = false;
2231
+ takeoverAt = undefined;
2232
+ takeoverReason = undefined;
2233
+ viewer.applyControl({ reason: "released", type: "takeover.release" });
2234
+ notify();
2235
+ },
2236
+ setCaller: (snapshot) => {
2237
+ caller = snapshot;
2238
+ notify();
2239
+ },
2240
+ subscribe: (listener) => {
2241
+ subscribers.add(listener);
2242
+ return () => {
2243
+ subscribers.delete(listener);
2244
+ if (subscribers.size === 0)
2245
+ unsubscribeViewer();
2246
+ };
2247
+ },
2248
+ takeover: (reason) => {
2249
+ if (hasTakeover)
2250
+ return;
2251
+ hasTakeover = true;
2252
+ takeoverAt = Date.now();
2253
+ takeoverReason = reason;
2254
+ viewer.applyControl({ reason, type: "takeover.engaged" });
2255
+ notify();
2256
+ },
2257
+ viewer
2258
+ };
2259
+ };
2260
+
2261
+ // src/angular/voice-live-agent-console.service.ts
2262
+ var _dec = [
2263
+ Injectable5({ providedIn: "root" })
2264
+ ];
2265
+ var _init = __decoratorStart(undefined);
2266
+
2267
+ class VoiceLiveAgentConsoleService {
2268
+ build(options) {
2269
+ const console = createLiveAgentConsole(options);
2270
+ const stateSignal = signal5(console.getState());
2271
+ const unsubscribe = console.subscribe(() => {
2272
+ stateSignal.set(console.getState());
2273
+ });
2274
+ return {
2275
+ releaseTakeover: () => console.releaseTakeover(),
2276
+ setCaller: (caller) => console.setCaller(caller),
2277
+ state: computed5(() => stateSignal()),
2278
+ stop: () => unsubscribe(),
2279
+ takeover: (reason) => console.takeover(reason),
2280
+ takeoverButtonLabel: options.takeoverButtonLabel ?? "Take over",
2281
+ title: options.title ?? "Live agent console"
2282
+ };
2283
+ }
2284
+ }
2285
+ VoiceLiveAgentConsoleService = __decorateElement(_init, 0, "VoiceLiveAgentConsoleService", _dec, VoiceLiveAgentConsoleService);
2286
+ __runInitializers(_init, 1, VoiceLiveAgentConsoleService);
2287
+ __decoratorMetadata(_init, VoiceLiveAgentConsoleService);
2288
+ let _VoiceLiveAgentConsoleService = VoiceLiveAgentConsoleService;
2289
+ // src/angular/voice-live-call-viewer.service.ts
2290
+ import { computed as computed6, Injectable as Injectable6, signal as signal6 } from "@angular/core";
2291
+ var _dec = [
2292
+ Injectable6({ providedIn: "root" })
2293
+ ];
2294
+ var _init = __decoratorStart(undefined);
2295
+
2296
+ class VoiceLiveCallViewerService {
2297
+ build(options) {
2298
+ const viewer = options.viewer ?? createLiveCallViewer(options);
2299
+ const stateSignal = signal6(viewer.getState());
2300
+ const unsubscribe = viewer.subscribe(() => {
2301
+ stateSignal.set(viewer.getState());
2302
+ });
2303
+ return {
2304
+ noteAgentAudio: (at) => viewer.noteAgentAudio(at),
2305
+ notePartial: (text, at) => viewer.notePartial(text, at),
2306
+ noteTranscript: (text, at) => viewer.noteTranscript(text, at),
2307
+ reset: (sessionId, startedAt) => viewer.reset(sessionId, startedAt),
2308
+ state: computed6(() => stateSignal()),
2309
+ stop: () => unsubscribe(),
2310
+ title: options.title ?? "Live call"
2311
+ };
2312
+ }
2313
+ }
2314
+ VoiceLiveCallViewerService = __decorateElement(_init, 0, "VoiceLiveCallViewerService", _dec, VoiceLiveCallViewerService);
2315
+ __runInitializers(_init, 1, VoiceLiveCallViewerService);
2316
+ __decoratorMetadata(_init, VoiceLiveCallViewerService);
2317
+ let _VoiceLiveCallViewerService = VoiceLiveCallViewerService;
2318
+ // src/angular/voice-replay-timeline.service.ts
2319
+ import { computed as computed7, Injectable as Injectable7, signal as signal7 } from "@angular/core";
2320
+
2321
+ // src/client/replayTimeline.ts
2322
+ var categorize = (entry) => {
2323
+ const event = entry.event.toLowerCase();
2324
+ if (event.startsWith("stt.") || event.includes("user"))
2325
+ return "user";
2326
+ if (event.startsWith("tts.") || event.includes("assistant") || event.includes("agent"))
2327
+ return "agent";
2328
+ if (event.startsWith("tool.") || event.includes("tool"))
2329
+ return "tool";
2330
+ return "lifecycle";
2331
+ };
2332
+ var buildReplayTimelineReport = (input) => {
2333
+ const events = [];
2334
+ let summaryAgentTurns = 0;
2335
+ let summaryUserTurns = 0;
2336
+ let summaryToolCalls = 0;
2337
+ for (const entry of input.artifact.timeline ?? []) {
2338
+ const category = categorize(entry);
2339
+ if (category === "user")
2340
+ summaryUserTurns += 1;
2341
+ if (category === "agent")
2342
+ summaryAgentTurns += 1;
2343
+ if (category === "tool")
2344
+ summaryToolCalls += 1;
2345
+ events.push({
2346
+ at: entry.atMs,
2347
+ category,
2348
+ detail: entry.text ?? entry.reason,
2349
+ durationMs: entry.chunkDurationMs,
2350
+ label: entry.event
2351
+ });
2352
+ }
2353
+ events.sort((a, b) => a.at - b.at);
2354
+ const first = events[0]?.at ?? 0;
2355
+ const last = events.at(-1)?.at ?? first;
2356
+ return {
2357
+ duration: last - first,
2358
+ events,
2359
+ metadata: {
2360
+ artifactId: input.artifact.id ?? "",
2361
+ title: input.artifact.title
2362
+ },
2363
+ startedAt: first,
2364
+ summary: {
2365
+ agentTurns: summaryAgentTurns,
2366
+ toolCalls: summaryToolCalls,
2367
+ userTurns: summaryUserTurns
2368
+ }
2369
+ };
2370
+ };
2371
+
2372
+ // src/angular/voice-replay-timeline.service.ts
2373
+ var _dec = [
2374
+ Injectable7({ providedIn: "root" })
2375
+ ];
2376
+ var _init = __decoratorStart(undefined);
2377
+
2378
+ class VoiceReplayTimelineService {
2379
+ build(options) {
2380
+ const artifact = signal7(options.artifact);
2381
+ const report = computed7(() => buildReplayTimelineReport({ artifact: artifact() }));
2382
+ return {
2383
+ report,
2384
+ setArtifact: (next) => artifact.set(next),
2385
+ title: options.title
2386
+ };
2387
+ }
2388
+ }
2389
+ VoiceReplayTimelineService = __decorateElement(_init, 0, "VoiceReplayTimelineService", _dec, VoiceReplayTimelineService);
2390
+ __runInitializers(_init, 1, VoiceReplayTimelineService);
2391
+ __decoratorMetadata(_init, VoiceReplayTimelineService);
2392
+ let _VoiceReplayTimelineService = VoiceReplayTimelineService;
2393
+ // src/angular/voice-platform-coverage.service.ts
2394
+ import { computed as computed8, Injectable as Injectable8, signal as signal8 } from "@angular/core";
2395
+
2396
+ // src/client/platformCoverage.ts
2397
+ var fetchVoicePlatformCoverage = async (path = "/api/voice/platform-coverage", options = {}) => {
2398
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2399
+ const response = await fetchImpl(path);
2400
+ if (!response.ok) {
2401
+ throw new Error(`Voice platform coverage failed: HTTP ${response.status}`);
2402
+ }
2403
+ return await response.json();
2404
+ };
2405
+ var createVoicePlatformCoverageStore = (path = "/api/voice/platform-coverage", options = {}) => {
2406
+ const listeners = new Set;
2407
+ let closed = false;
2408
+ let timer;
2409
+ let snapshot = {
2410
+ error: null,
2411
+ isLoading: false
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 fetchVoicePlatformCoverage(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 (typeof window !== "undefined" && 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-platform-coverage.service.ts
2476
+ var _dec = [
2477
+ Injectable8({ providedIn: "root" })
2478
+ ];
2479
+ var _init = __decoratorStart(undefined);
2480
+
2481
+ class VoicePlatformCoverageService {
2482
+ connect(path = "/api/voice/platform-coverage", options = {}) {
2483
+ const store = createVoicePlatformCoverageStore(path, options);
2484
+ const errorSignal = signal8(null);
2485
+ const isLoadingSignal = signal8(false);
2486
+ const reportSignal = signal8(undefined);
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
+ if (typeof window !== "undefined") {
2498
+ store.refresh().catch(() => {});
2499
+ }
2500
+ return {
2501
+ close: () => {
2502
+ unsubscribe();
2503
+ store.close();
2504
+ },
2505
+ error: computed8(() => errorSignal()),
2506
+ isLoading: computed8(() => isLoadingSignal()),
2507
+ refresh: store.refresh,
2508
+ report: computed8(() => reportSignal()),
2509
+ updatedAt: computed8(() => updatedAtSignal())
2510
+ };
2511
+ }
2512
+ }
2513
+ VoicePlatformCoverageService = __decorateElement(_init, 0, "VoicePlatformCoverageService", _dec, VoicePlatformCoverageService);
2514
+ __runInitializers(_init, 1, VoicePlatformCoverageService);
2515
+ __decoratorMetadata(_init, VoicePlatformCoverageService);
2516
+ let _VoicePlatformCoverageService = VoicePlatformCoverageService;
2517
+ // src/angular/voice-proof-trends.service.ts
2518
+ import { computed as computed9, Injectable as Injectable9, signal as signal9 } from "@angular/core";
2519
+
2520
+ // src/client/proofTrends.ts
2521
+ var fetchVoiceProofTrends = async (path = "/api/voice/proof-trends", options = {}) => {
2522
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2523
+ const response = await fetchImpl(path);
2524
+ if (!response.ok) {
2525
+ throw new Error(`Voice proof trends failed: HTTP ${response.status}`);
2526
+ }
2527
+ return await response.json();
2528
+ };
2529
+ var createVoiceProofTrendsStore = (path = "/api/voice/proof-trends", options = {}) => {
2530
+ const listeners = new Set;
2531
+ let closed = false;
2532
+ let timer;
2533
+ let snapshot = {
2534
+ error: null,
2535
+ isLoading: false
2536
+ };
2537
+ const emit = () => {
2538
+ for (const listener of listeners) {
2539
+ listener();
2540
+ }
2541
+ };
2542
+ const refresh = async () => {
2543
+ if (closed) {
2544
+ return snapshot.report;
2545
+ }
2546
+ snapshot = {
2547
+ ...snapshot,
2548
+ error: null,
2549
+ isLoading: true
2550
+ };
2551
+ emit();
2552
+ try {
2553
+ const report = await fetchVoiceProofTrends(path, options);
2554
+ snapshot = {
2555
+ error: null,
2556
+ isLoading: false,
2557
+ report,
2558
+ updatedAt: Date.now()
2559
+ };
2560
+ emit();
2561
+ return report;
2562
+ } catch (error) {
2563
+ snapshot = {
2564
+ ...snapshot,
2565
+ error: error instanceof Error ? error.message : String(error),
2566
+ isLoading: false
2567
+ };
2568
+ emit();
2569
+ throw error;
2570
+ }
2571
+ };
2572
+ const close = () => {
2573
+ closed = true;
2574
+ if (timer) {
2575
+ clearInterval(timer);
2576
+ timer = undefined;
2577
+ }
2578
+ listeners.clear();
2579
+ };
2580
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2581
+ timer = setInterval(() => {
2582
+ refresh().catch(() => {});
2583
+ }, options.intervalMs);
2584
+ }
2585
+ return {
2586
+ close,
2587
+ getServerSnapshot: () => snapshot,
2588
+ getSnapshot: () => snapshot,
2589
+ refresh,
2590
+ subscribe: (listener) => {
2591
+ listeners.add(listener);
2592
+ return () => {
2593
+ listeners.delete(listener);
2594
+ };
2595
+ }
2596
+ };
2597
+ };
2598
+
2599
+ // src/angular/voice-proof-trends.service.ts
2600
+ var _dec = [
2601
+ Injectable9({ providedIn: "root" })
2602
+ ];
2603
+ var _init = __decoratorStart(undefined);
2604
+
2605
+ class VoiceProofTrendsService {
2606
+ connect(path = "/api/voice/proof-trends", options = {}) {
2607
+ const store = createVoiceProofTrendsStore(path, options);
2608
+ const errorSignal = signal9(null);
2609
+ const isLoadingSignal = signal9(false);
2610
+ const reportSignal = signal9(undefined);
2611
+ const updatedAtSignal = signal9(undefined);
2612
+ const sync = () => {
2613
+ const snapshot = store.getSnapshot();
2614
+ errorSignal.set(snapshot.error);
2615
+ isLoadingSignal.set(snapshot.isLoading);
2616
+ reportSignal.set(snapshot.report);
2617
+ updatedAtSignal.set(snapshot.updatedAt);
2618
+ };
2619
+ const unsubscribe = store.subscribe(sync);
2620
+ sync();
2621
+ if (typeof window !== "undefined") {
2622
+ store.refresh().catch(() => {});
2623
+ }
2624
+ return {
2625
+ close: () => {
2626
+ unsubscribe();
2627
+ store.close();
2628
+ },
2629
+ error: computed9(() => errorSignal()),
2630
+ isLoading: computed9(() => isLoadingSignal()),
2631
+ refresh: store.refresh,
2632
+ report: computed9(() => reportSignal()),
2633
+ updatedAt: computed9(() => updatedAtSignal())
2634
+ };
2635
+ }
2636
+ }
2637
+ VoiceProofTrendsService = __decorateElement(_init, 0, "VoiceProofTrendsService", _dec, VoiceProofTrendsService);
2638
+ __runInitializers(_init, 1, VoiceProofTrendsService);
2639
+ __decoratorMetadata(_init, VoiceProofTrendsService);
2640
+ let _VoiceProofTrendsService = VoiceProofTrendsService;
2641
+ // src/angular/voice-reconnect-profile-evidence.service.ts
2642
+ import { computed as computed10, Injectable as Injectable10, signal as signal10 } from "@angular/core";
2643
+
2644
+ // src/client/reconnectProfileEvidence.ts
2645
+ var fetchVoiceReconnectProfileEvidence = async (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
2646
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2647
+ const response = await fetchImpl(path);
2648
+ if (!response.ok) {
2649
+ throw new Error(`Voice reconnect profile evidence failed: HTTP ${response.status}`);
2650
+ }
2651
+ return await response.json();
2652
+ };
2653
+ var createVoiceReconnectProfileEvidenceStore = (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
2654
+ const listeners = new Set;
2655
+ let closed = false;
2656
+ let timer;
2657
+ let snapshot = {
2658
+ error: null,
2659
+ isLoading: false
2660
+ };
2661
+ const emit = () => {
2662
+ for (const listener of listeners) {
2663
+ listener();
2664
+ }
2665
+ };
2666
+ const refresh = async () => {
2667
+ if (closed) {
2668
+ return snapshot.report;
2669
+ }
2670
+ snapshot = { ...snapshot, error: null, isLoading: true };
2671
+ emit();
2672
+ try {
2673
+ const report = await fetchVoiceReconnectProfileEvidence(path, options);
2674
+ snapshot = {
2675
+ error: null,
2676
+ isLoading: false,
2677
+ report,
2678
+ updatedAt: Date.now()
2679
+ };
2680
+ emit();
2681
+ return report;
2682
+ } catch (error) {
2683
+ snapshot = {
2684
+ ...snapshot,
2685
+ error: error instanceof Error ? error.message : String(error),
2686
+ isLoading: false
2687
+ };
2688
+ emit();
2689
+ throw error;
2690
+ }
2691
+ };
2692
+ const close = () => {
2693
+ closed = true;
2694
+ if (timer) {
2695
+ clearInterval(timer);
2696
+ timer = undefined;
2697
+ }
2698
+ listeners.clear();
2699
+ };
2700
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2701
+ timer = setInterval(() => {
2702
+ refresh().catch(() => {});
2703
+ }, options.intervalMs);
2704
+ }
2705
+ return {
2706
+ close,
2707
+ getServerSnapshot: () => snapshot,
2708
+ getSnapshot: () => snapshot,
2709
+ refresh,
2710
+ subscribe: (listener) => {
2711
+ listeners.add(listener);
2712
+ return () => {
2713
+ listeners.delete(listener);
2714
+ };
2715
+ }
2716
+ };
2717
+ };
2718
+
2719
+ // src/angular/voice-reconnect-profile-evidence.service.ts
2720
+ var _dec = [
2721
+ Injectable10({ providedIn: "root" })
2722
+ ];
2723
+ var _init = __decoratorStart(undefined);
2724
+
2725
+ class VoiceReconnectProfileEvidenceService {
2726
+ connect(path = "/api/voice/reconnect-profile-evidence", options = {}) {
2727
+ const store = createVoiceReconnectProfileEvidenceStore(path, options);
2728
+ const errorSignal = signal10(null);
2729
+ const isLoadingSignal = signal10(false);
2730
+ const reportSignal = signal10(undefined);
2731
+ const updatedAtSignal = signal10(undefined);
2732
+ const sync = () => {
2733
+ const snapshot = store.getSnapshot();
2734
+ errorSignal.set(snapshot.error);
2735
+ isLoadingSignal.set(snapshot.isLoading);
2736
+ reportSignal.set(snapshot.report);
2737
+ updatedAtSignal.set(snapshot.updatedAt);
2738
+ };
2739
+ const unsubscribe = store.subscribe(sync);
2740
+ sync();
2741
+ if (typeof window !== "undefined") {
2742
+ store.refresh().catch(() => {});
2743
+ }
2744
+ return {
2745
+ close: () => {
2746
+ unsubscribe();
2747
+ store.close();
2748
+ },
2749
+ error: computed10(() => errorSignal()),
2750
+ isLoading: computed10(() => isLoadingSignal()),
2751
+ refresh: store.refresh,
2752
+ report: computed10(() => reportSignal()),
2753
+ updatedAt: computed10(() => updatedAtSignal())
2754
+ };
2755
+ }
2756
+ }
2757
+ VoiceReconnectProfileEvidenceService = __decorateElement(_init, 0, "VoiceReconnectProfileEvidenceService", _dec, VoiceReconnectProfileEvidenceService);
2758
+ __runInitializers(_init, 1, VoiceReconnectProfileEvidenceService);
2759
+ __decoratorMetadata(_init, VoiceReconnectProfileEvidenceService);
2760
+ let _VoiceReconnectProfileEvidenceService = VoiceReconnectProfileEvidenceService;
2761
+ // src/angular/voice-call-debugger.service.ts
2762
+ import { computed as computed11, Injectable as Injectable11, signal as signal11 } from "@angular/core";
2763
+
2764
+ // src/client/callDebugger.ts
2765
+ var fetchVoiceCallDebugger = async (path, options = {}) => {
2766
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2767
+ const response = await fetchImpl(path);
2768
+ if (!response.ok) {
2769
+ throw new Error(`Voice call debugger failed: HTTP ${response.status}`);
2770
+ }
2771
+ return await response.json();
2772
+ };
2773
+ var createVoiceCallDebuggerStore = (path, options = {}) => {
2774
+ const listeners = new Set;
2775
+ let closed = false;
2776
+ let timer;
2777
+ let snapshot = {
2778
+ error: null,
2779
+ isLoading: false
2780
+ };
2781
+ const emit = () => {
2782
+ for (const listener of listeners) {
2783
+ listener();
2784
+ }
2785
+ };
2786
+ const refresh = async () => {
2787
+ if (closed) {
2788
+ return snapshot.report;
2789
+ }
2790
+ snapshot = { ...snapshot, error: null, isLoading: true };
2791
+ emit();
2792
+ try {
2793
+ const report = await fetchVoiceCallDebugger(path, options);
2794
+ snapshot = {
2795
+ error: null,
2796
+ isLoading: false,
2797
+ report,
2798
+ updatedAt: Date.now()
2799
+ };
2800
+ emit();
2801
+ return report;
2802
+ } catch (error) {
2803
+ snapshot = {
2804
+ ...snapshot,
2805
+ error: error instanceof Error ? error.message : String(error),
2806
+ isLoading: false
2807
+ };
2808
+ emit();
2809
+ throw error;
2810
+ }
2811
+ };
2812
+ const close = () => {
2813
+ closed = true;
2814
+ if (timer) {
2815
+ clearInterval(timer);
2816
+ timer = undefined;
2817
+ }
2818
+ listeners.clear();
2819
+ };
2820
+ if (options.intervalMs && options.intervalMs > 0) {
2821
+ timer = setInterval(() => {
2822
+ refresh().catch(() => {});
2823
+ }, options.intervalMs);
2824
+ }
2825
+ return {
2826
+ close,
2827
+ getServerSnapshot: () => snapshot,
2828
+ getSnapshot: () => snapshot,
2829
+ refresh,
2830
+ subscribe: (listener) => {
2831
+ listeners.add(listener);
2832
+ return () => {
2833
+ listeners.delete(listener);
2834
+ };
2835
+ }
2836
+ };
2837
+ };
2838
+
2839
+ // src/angular/voice-call-debugger.service.ts
2840
+ var _dec = [
2841
+ Injectable11({ providedIn: "root" })
2842
+ ];
2843
+ var _init = __decoratorStart(undefined);
2844
+
2845
+ class VoiceCallDebuggerService {
2846
+ connect(path, options = {}) {
2847
+ const store = createVoiceCallDebuggerStore(path, options);
2848
+ const errorSignal = signal11(null);
2849
+ const isLoadingSignal = signal11(false);
2850
+ const reportSignal = signal11(undefined);
2851
+ const updatedAtSignal = signal11(undefined);
2852
+ const sync = () => {
2853
+ const state = store.getSnapshot();
2854
+ errorSignal.set(state.error);
2855
+ isLoadingSignal.set(state.isLoading);
2856
+ reportSignal.set(state.report);
2857
+ updatedAtSignal.set(state.updatedAt);
2858
+ };
2859
+ const unsubscribe = store.subscribe(sync);
2860
+ sync();
2861
+ store.refresh().catch(() => {});
2862
+ return {
2863
+ close: () => {
2864
+ unsubscribe();
2865
+ store.close();
2866
+ },
2867
+ error: computed11(() => errorSignal()),
2868
+ isLoading: computed11(() => isLoadingSignal()),
2869
+ refresh: store.refresh,
2870
+ report: computed11(() => reportSignal()),
2871
+ updatedAt: computed11(() => updatedAtSignal())
2872
+ };
2873
+ }
2874
+ }
2875
+ VoiceCallDebuggerService = __decorateElement(_init, 0, "VoiceCallDebuggerService", _dec, VoiceCallDebuggerService);
2876
+ __runInitializers(_init, 1, VoiceCallDebuggerService);
2877
+ __decoratorMetadata(_init, VoiceCallDebuggerService);
2878
+ let _VoiceCallDebuggerService = VoiceCallDebuggerService;
2879
+ // src/angular/voice-session-snapshot.service.ts
2880
+ import { computed as computed12, Injectable as Injectable12, signal as signal12 } from "@angular/core";
2881
+
2882
+ // src/client/sessionSnapshot.ts
2883
+ var withTurnId = (path, turnId) => {
2884
+ if (!turnId) {
2885
+ return path;
2886
+ }
2887
+ const url = new URL(path, "http://absolutejs.local");
2888
+ url.searchParams.set("turnId", turnId);
2889
+ return `${url.pathname}${url.search}`;
2890
+ };
2891
+ var fetchVoiceSessionSnapshot = async (path, options = {}) => {
2892
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2893
+ const response = await fetchImpl(withTurnId(path, options.turnId));
2894
+ if (!response.ok) {
2895
+ throw new Error(`Voice session snapshot failed: HTTP ${response.status}`);
2896
+ }
2897
+ return await response.json();
2898
+ };
2899
+ var createVoiceSessionSnapshotStore = (path, options = {}) => {
2900
+ const listeners = new Set;
2901
+ let closed = false;
2902
+ let timer;
2903
+ let snapshot = {
2904
+ error: null,
2905
+ isLoading: false
2906
+ };
2907
+ const emit = () => {
2908
+ for (const listener of listeners) {
2909
+ listener();
2910
+ }
2911
+ };
2912
+ const refresh = async () => {
2913
+ if (closed) {
2914
+ return snapshot.snapshot;
2915
+ }
2916
+ snapshot = { ...snapshot, error: null, isLoading: true };
2917
+ emit();
2918
+ try {
2919
+ const next = await fetchVoiceSessionSnapshot(path, options);
2920
+ snapshot = {
2921
+ error: null,
2922
+ isLoading: false,
2923
+ snapshot: next,
2924
+ updatedAt: Date.now()
2925
+ };
2926
+ emit();
2927
+ return next;
2928
+ } catch (error) {
2929
+ snapshot = {
2930
+ ...snapshot,
2931
+ error: error instanceof Error ? error.message : String(error),
2932
+ isLoading: false
2933
+ };
2934
+ emit();
2935
+ throw error;
2936
+ }
2937
+ };
2938
+ const download = () => {
2939
+ const current = snapshot.snapshot;
2940
+ if (current === undefined) {
2941
+ throw new Error("Voice session snapshot has not been loaded.");
2942
+ }
2943
+ return new Blob([JSON.stringify(current, null, 2)], {
2944
+ type: "application/json"
2945
+ });
2946
+ };
2947
+ const close = () => {
2948
+ closed = true;
2949
+ if (timer) {
2950
+ clearInterval(timer);
2951
+ timer = undefined;
2952
+ }
2953
+ listeners.clear();
2954
+ };
2955
+ if (options.intervalMs && options.intervalMs > 0) {
2956
+ timer = setInterval(() => {
2957
+ refresh().catch(() => {});
2958
+ }, options.intervalMs);
2959
+ }
2960
+ return {
2961
+ close,
2962
+ download,
2963
+ getServerSnapshot: () => snapshot,
2964
+ getSnapshot: () => snapshot,
2965
+ refresh,
2966
+ subscribe: (listener) => {
2967
+ listeners.add(listener);
2968
+ return () => {
2969
+ listeners.delete(listener);
2970
+ };
2971
+ }
2972
+ };
2973
+ };
2974
+
2975
+ // src/angular/voice-session-snapshot.service.ts
2976
+ var _dec = [
2977
+ Injectable12({ providedIn: "root" })
2978
+ ];
2979
+ var _init = __decoratorStart(undefined);
2980
+
2981
+ class VoiceSessionSnapshotService {
2982
+ connect(path, options = {}) {
2983
+ const store = createVoiceSessionSnapshotStore(path, options);
2984
+ const errorSignal = signal12(null);
2985
+ const isLoadingSignal = signal12(false);
2986
+ const snapshotSignal = signal12(undefined);
2987
+ const updatedAtSignal = signal12(undefined);
2988
+ const sync = () => {
2989
+ const state = store.getSnapshot();
2990
+ errorSignal.set(state.error);
2991
+ isLoadingSignal.set(state.isLoading);
2992
+ snapshotSignal.set(state.snapshot);
2993
+ updatedAtSignal.set(state.updatedAt);
2994
+ };
2995
+ const unsubscribe = store.subscribe(sync);
2996
+ sync();
2997
+ store.refresh().catch(() => {});
2998
+ return {
2999
+ close: () => {
3000
+ unsubscribe();
3001
+ store.close();
3002
+ },
3003
+ download: store.download,
3004
+ error: computed12(() => errorSignal()),
3005
+ isLoading: computed12(() => isLoadingSignal()),
3006
+ refresh: store.refresh,
3007
+ snapshot: computed12(() => snapshotSignal()),
3008
+ updatedAt: computed12(() => updatedAtSignal())
3009
+ };
3010
+ }
3011
+ }
3012
+ VoiceSessionSnapshotService = __decorateElement(_init, 0, "VoiceSessionSnapshotService", _dec, VoiceSessionSnapshotService);
3013
+ __runInitializers(_init, 1, VoiceSessionSnapshotService);
3014
+ __decoratorMetadata(_init, VoiceSessionSnapshotService);
3015
+ let _VoiceSessionSnapshotService = VoiceSessionSnapshotService;
3016
+ // src/angular/voice-session-observability.service.ts
3017
+ import { computed as computed13, Injectable as Injectable13, signal as signal13 } from "@angular/core";
3018
+
3019
+ // src/client/sessionObservability.ts
3020
+ var fetchVoiceSessionObservability = async (path, options = {}) => {
3021
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3022
+ const response = await fetchImpl(path);
3023
+ if (!response.ok) {
3024
+ throw new Error(`Voice session observability failed: HTTP ${response.status}`);
3025
+ }
3026
+ return await response.json();
3027
+ };
3028
+ var createVoiceSessionObservabilityStore = (path, options = {}) => {
3029
+ const listeners = new Set;
3030
+ let closed = false;
3031
+ let timer;
3032
+ let snapshot = {
3033
+ error: null,
3034
+ isLoading: false,
3035
+ report: null
3036
+ };
3037
+ const emit = () => {
3038
+ for (const listener of listeners) {
3039
+ listener();
3040
+ }
3041
+ };
3042
+ const refresh = async () => {
3043
+ if (closed) {
3044
+ return snapshot.report;
3045
+ }
3046
+ snapshot = {
3047
+ ...snapshot,
3048
+ error: null,
3049
+ isLoading: true
3050
+ };
3051
+ emit();
3052
+ try {
3053
+ const report = await fetchVoiceSessionObservability(path, options);
3054
+ snapshot = {
3055
+ error: null,
3056
+ isLoading: false,
3057
+ report,
3058
+ updatedAt: Date.now()
3059
+ };
3060
+ emit();
3061
+ return report;
3062
+ } catch (error) {
3063
+ snapshot = {
3064
+ ...snapshot,
3065
+ error: error instanceof Error ? error.message : String(error),
3066
+ isLoading: false
3067
+ };
3068
+ emit();
3069
+ throw error;
3070
+ }
3071
+ };
3072
+ const close = () => {
3073
+ closed = true;
3074
+ if (timer) {
3075
+ clearInterval(timer);
3076
+ timer = undefined;
3077
+ }
3078
+ listeners.clear();
3079
+ };
3080
+ if (options.intervalMs && options.intervalMs > 0) {
3081
+ timer = setInterval(() => {
3082
+ refresh().catch(() => {});
3083
+ }, options.intervalMs);
3084
+ }
3085
+ return {
3086
+ close,
3087
+ getServerSnapshot: () => snapshot,
3088
+ getSnapshot: () => snapshot,
3089
+ refresh,
3090
+ subscribe: (listener) => {
3091
+ listeners.add(listener);
3092
+ return () => {
3093
+ listeners.delete(listener);
3094
+ };
3095
+ }
3096
+ };
3097
+ };
3098
+
3099
+ // src/angular/voice-session-observability.service.ts
3100
+ var _dec = [
3101
+ Injectable13({ providedIn: "root" })
3102
+ ];
3103
+ var _init = __decoratorStart(undefined);
3104
+
3105
+ class VoiceSessionObservabilityService {
3106
+ connect(path = "/api/voice/session-observability/latest", options = {}) {
3107
+ const store = createVoiceSessionObservabilityStore(path, options);
3108
+ const errorSignal = signal13(null);
3109
+ const isLoadingSignal = signal13(false);
3110
+ const reportSignal = signal13(null);
3111
+ const updatedAtSignal = signal13(undefined);
3112
+ const sync = () => {
3113
+ const snapshot = store.getSnapshot();
3114
+ errorSignal.set(snapshot.error);
3115
+ isLoadingSignal.set(snapshot.isLoading);
3116
+ reportSignal.set(snapshot.report);
3117
+ updatedAtSignal.set(snapshot.updatedAt);
3118
+ };
3119
+ const unsubscribe = store.subscribe(sync);
3120
+ sync();
3121
+ store.refresh().catch(() => {});
3122
+ return {
3123
+ close: () => {
3124
+ unsubscribe();
3125
+ store.close();
3126
+ },
3127
+ error: computed13(() => errorSignal()),
3128
+ isLoading: computed13(() => isLoadingSignal()),
3129
+ refresh: store.refresh,
3130
+ report: computed13(() => reportSignal()),
3131
+ updatedAt: computed13(() => updatedAtSignal())
3132
+ };
3133
+ }
3134
+ }
3135
+ VoiceSessionObservabilityService = __decorateElement(_init, 0, "VoiceSessionObservabilityService", _dec, VoiceSessionObservabilityService);
3136
+ __runInitializers(_init, 1, VoiceSessionObservabilityService);
3137
+ __decoratorMetadata(_init, VoiceSessionObservabilityService);
3138
+ let _VoiceSessionObservabilityService = VoiceSessionObservabilityService;
3139
+ // src/angular/voice-profile-comparison.service.ts
3140
+ import { computed as computed14, Injectable as Injectable14, signal as signal14 } from "@angular/core";
3141
+
3142
+ // src/client/profileComparison.ts
3143
+ var fetchVoiceProfileComparison = async (path = "/api/voice/real-call-profile-history", options = {}) => {
3144
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3145
+ const response = await fetchImpl(path);
3146
+ if (!response.ok) {
3147
+ throw new Error(`Voice profile comparison failed: HTTP ${response.status}`);
3148
+ }
3149
+ return await response.json();
3150
+ };
3151
+ var createVoiceProfileComparisonStore = (path = "/api/voice/real-call-profile-history", options = {}) => {
3152
+ const listeners = new Set;
3153
+ let closed = false;
3154
+ let timer;
3155
+ let snapshot = {
3156
+ error: null,
3157
+ isLoading: false
3158
+ };
3159
+ const emit = () => {
3160
+ for (const listener of listeners) {
3161
+ listener();
3162
+ }
3163
+ };
3164
+ const refresh = async () => {
3165
+ if (closed) {
3166
+ return snapshot.report;
3167
+ }
3168
+ snapshot = { ...snapshot, error: null, isLoading: true };
3169
+ emit();
3170
+ try {
3171
+ const report = await fetchVoiceProfileComparison(path, options);
3172
+ snapshot = {
3173
+ error: null,
3174
+ isLoading: false,
3175
+ report,
3176
+ updatedAt: Date.now()
3177
+ };
3178
+ emit();
3179
+ return report;
3180
+ } catch (error) {
3181
+ snapshot = {
3182
+ ...snapshot,
3183
+ error: error instanceof Error ? error.message : String(error),
3184
+ isLoading: false
3185
+ };
3186
+ emit();
3187
+ throw error;
3188
+ }
3189
+ };
3190
+ const close = () => {
3191
+ closed = true;
3192
+ if (timer) {
3193
+ clearInterval(timer);
3194
+ timer = undefined;
3195
+ }
3196
+ listeners.clear();
3197
+ };
3198
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
3199
+ timer = setInterval(() => {
3200
+ refresh().catch(() => {});
3201
+ }, options.intervalMs);
3202
+ }
3203
+ return {
3204
+ close,
3205
+ getServerSnapshot: () => snapshot,
3206
+ getSnapshot: () => snapshot,
3207
+ refresh,
3208
+ subscribe: (listener) => {
3209
+ listeners.add(listener);
3210
+ return () => {
3211
+ listeners.delete(listener);
3212
+ };
3213
+ }
3214
+ };
3215
+ };
3216
+
3217
+ // src/angular/voice-profile-comparison.service.ts
3218
+ var _dec = [
3219
+ Injectable14({ providedIn: "root" })
3220
+ ];
3221
+ var _init = __decoratorStart(undefined);
3222
+
3223
+ class VoiceProfileComparisonService {
3224
+ connect(path = "/api/voice/real-call-profile-history", options = {}) {
3225
+ const store = createVoiceProfileComparisonStore(path, options);
3226
+ const errorSignal = signal14(null);
3227
+ const isLoadingSignal = signal14(false);
3228
+ const reportSignal = signal14(undefined);
3229
+ const updatedAtSignal = signal14(undefined);
3230
+ const sync = () => {
3231
+ const snapshot = store.getSnapshot();
3232
+ errorSignal.set(snapshot.error);
3233
+ isLoadingSignal.set(snapshot.isLoading);
3234
+ reportSignal.set(snapshot.report);
3235
+ updatedAtSignal.set(snapshot.updatedAt);
3236
+ };
3237
+ const unsubscribe = store.subscribe(sync);
3238
+ sync();
3239
+ if (typeof window !== "undefined") {
3240
+ store.refresh().catch(() => {});
3241
+ }
3242
+ return {
3243
+ close: () => {
3244
+ unsubscribe();
3245
+ store.close();
3246
+ },
3247
+ error: computed14(() => errorSignal()),
3248
+ isLoading: computed14(() => isLoadingSignal()),
3249
+ refresh: store.refresh,
3250
+ report: computed14(() => reportSignal()),
3251
+ updatedAt: computed14(() => updatedAtSignal())
3252
+ };
3253
+ }
3254
+ }
3255
+ VoiceProfileComparisonService = __decorateElement(_init, 0, "VoiceProfileComparisonService", _dec, VoiceProfileComparisonService);
3256
+ __runInitializers(_init, 1, VoiceProfileComparisonService);
3257
+ __decoratorMetadata(_init, VoiceProfileComparisonService);
3258
+ let _VoiceProfileComparisonService = VoiceProfileComparisonService;
3259
+ // src/angular/voice-readiness-failures.service.ts
3260
+ import { computed as computed15, Injectable as Injectable15, signal as signal15 } from "@angular/core";
3261
+
3262
+ // src/client/readinessFailures.ts
3263
+ var fetchVoiceReadinessFailures = async (path = "/api/production-readiness", options = {}) => {
3264
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3265
+ const response = await fetchImpl(path);
3266
+ if (!response.ok) {
3267
+ throw new Error(`Voice readiness failed: HTTP ${response.status}`);
3268
+ }
3269
+ return await response.json();
3270
+ };
3271
+ var createVoiceReadinessFailuresStore = (path = "/api/production-readiness", options = {}) => {
3272
+ const listeners = new Set;
3273
+ let closed = false;
3274
+ let timer;
3275
+ let snapshot = {
3276
+ error: null,
3277
+ isLoading: false
3278
+ };
3279
+ const emit = () => {
3280
+ for (const listener of listeners) {
3281
+ listener();
3282
+ }
3283
+ };
3284
+ const refresh = async () => {
3285
+ if (closed) {
3286
+ return snapshot.report;
3287
+ }
3288
+ snapshot = { ...snapshot, error: null, isLoading: true };
3289
+ emit();
3290
+ try {
3291
+ const report = await fetchVoiceReadinessFailures(path, options);
3292
+ snapshot = {
3293
+ error: null,
3294
+ isLoading: false,
3295
+ report,
3296
+ updatedAt: Date.now()
3297
+ };
3298
+ emit();
3299
+ return report;
3300
+ } catch (error) {
3301
+ snapshot = {
3302
+ ...snapshot,
3303
+ error: error instanceof Error ? error.message : String(error),
3304
+ isLoading: false
3305
+ };
3306
+ emit();
3307
+ throw error;
3308
+ }
3309
+ };
3310
+ const close = () => {
3311
+ closed = true;
3312
+ if (timer) {
3313
+ clearInterval(timer);
3314
+ timer = undefined;
3315
+ }
3316
+ listeners.clear();
3317
+ };
3318
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
3319
+ timer = setInterval(() => {
3320
+ refresh().catch(() => {});
3321
+ }, options.intervalMs);
3322
+ }
3323
+ return {
3324
+ close,
3325
+ getServerSnapshot: () => snapshot,
3326
+ getSnapshot: () => snapshot,
3327
+ refresh,
3328
+ subscribe: (listener) => {
3329
+ listeners.add(listener);
3330
+ return () => {
3331
+ listeners.delete(listener);
3332
+ };
3333
+ }
3334
+ };
3335
+ };
3336
+
3337
+ // src/angular/voice-readiness-failures.service.ts
3338
+ var _dec = [
3339
+ Injectable15({ providedIn: "root" })
3340
+ ];
3341
+ var _init = __decoratorStart(undefined);
3342
+
3343
+ class VoiceReadinessFailuresService {
3344
+ connect(path = "/api/production-readiness", options = {}) {
3345
+ const store = createVoiceReadinessFailuresStore(path, options);
3346
+ const errorSignal = signal15(null);
3347
+ const isLoadingSignal = signal15(false);
3348
+ const reportSignal = signal15(undefined);
3349
+ const updatedAtSignal = signal15(undefined);
3350
+ const sync = () => {
3351
+ const snapshot = store.getSnapshot();
3352
+ errorSignal.set(snapshot.error);
3353
+ isLoadingSignal.set(snapshot.isLoading);
3354
+ reportSignal.set(snapshot.report);
3355
+ updatedAtSignal.set(snapshot.updatedAt);
3356
+ };
3357
+ const unsubscribe = store.subscribe(sync);
3358
+ sync();
3359
+ if (typeof window !== "undefined") {
3360
+ store.refresh().catch(() => {});
3361
+ }
3362
+ return {
3363
+ close: () => {
3364
+ unsubscribe();
3365
+ store.close();
3366
+ },
3367
+ error: computed15(() => errorSignal()),
3368
+ explanations: computed15(() => reportSignal()?.checks.filter((check) => check.status !== "pass" && !!check.gateExplanation) ?? []),
3369
+ isLoading: computed15(() => isLoadingSignal()),
3370
+ refresh: store.refresh,
3371
+ report: computed15(() => reportSignal()),
3372
+ updatedAt: computed15(() => updatedAtSignal())
3373
+ };
3374
+ }
3375
+ }
3376
+ VoiceReadinessFailuresService = __decorateElement(_init, 0, "VoiceReadinessFailuresService", _dec, VoiceReadinessFailuresService);
3377
+ __runInitializers(_init, 1, VoiceReadinessFailuresService);
3378
+ __decoratorMetadata(_init, VoiceReadinessFailuresService);
3379
+ let _VoiceReadinessFailuresService = VoiceReadinessFailuresService;
3380
+ // src/angular/voice-ops-action-center.service.ts
3381
+ import { computed as computed16, Injectable as Injectable16, signal as signal16 } from "@angular/core";
3382
+
3383
+ // src/client/opsActionCenter.ts
3384
+ var recordVoiceOpsActionResult = async (result, options = {}) => {
3385
+ if (options.auditPath === false) {
3386
+ return;
3387
+ }
3388
+ const path = options.auditPath ?? "/api/voice/ops-actions/audit";
3389
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3390
+ const response = await fetchImpl(path, {
3391
+ body: JSON.stringify(result),
3392
+ headers: {
3393
+ "Content-Type": "application/json"
3394
+ },
3395
+ method: "POST"
3396
+ });
3397
+ if (!response.ok) {
3398
+ throw new Error(`Voice ops action audit failed: HTTP ${response.status}`);
3399
+ }
3400
+ };
3401
+ var createVoiceOpsActionCenterActions = (options = {}) => {
3402
+ const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
3403
+ const actions = [];
3404
+ if (options.includeProductionReadiness !== false) {
3405
+ actions.push({
3406
+ description: "Refresh the production readiness report.",
3407
+ id: "production-readiness",
3408
+ label: "Refresh readiness",
3409
+ method: "GET",
3410
+ path: options.productionReadinessPath ?? "/api/production-readiness"
3411
+ });
3412
+ }
3413
+ if (options.includeDeliveryRuntime !== false) {
3414
+ actions.push({
3415
+ description: "Drain pending and failed audit/trace deliveries.",
3416
+ id: "delivery-runtime.tick",
3417
+ label: "Tick delivery workers",
3418
+ method: "POST",
3419
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
3420
+ }, {
3421
+ description: "Move reviewed dead letters back to live delivery queues.",
3422
+ id: "delivery-runtime.requeue-dead-letters",
3423
+ label: "Requeue dead letters",
3424
+ method: "POST",
3425
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
3426
+ });
3427
+ }
3428
+ if (options.includeTurnLatencyProof !== false) {
3429
+ actions.push({
3430
+ description: "Run the synthetic turn latency proof.",
3431
+ id: "turn-latency.proof",
3432
+ label: "Run latency proof",
3433
+ method: "POST",
3434
+ path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
3435
+ });
3436
+ }
3437
+ if (options.includeProviderSimulation !== false) {
3438
+ const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
3439
+ for (const provider of options.providers ?? []) {
3440
+ actions.push({
3441
+ description: `Simulate ${provider} provider failure.`,
3442
+ id: `provider.${provider}.failure`,
3443
+ label: `Simulate ${provider} failure`,
3444
+ method: "POST",
3445
+ path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
3446
+ }, {
3447
+ description: `Mark ${provider} provider recovered.`,
3448
+ id: `provider.${provider}.recovery`,
3449
+ label: `Recover ${provider}`,
3450
+ method: "POST",
3451
+ path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
3452
+ });
3453
+ }
3454
+ }
3455
+ return actions;
3456
+ };
3457
+ var runVoiceOpsAction = async (action, options = {}) => {
3458
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3459
+ const response = await fetchImpl(action.path, {
3460
+ method: action.method ?? "POST"
3461
+ });
3462
+ const body = await response.json().catch(() => null);
3463
+ if (!response.ok) {
3464
+ const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
3465
+ throw new Error(message);
3466
+ }
3467
+ return {
3468
+ actionId: action.id,
3469
+ body,
3470
+ ok: response.ok,
3471
+ ranAt: Date.now(),
3472
+ status: response.status
3473
+ };
3474
+ };
3475
+ var createVoiceOpsActionCenterStore = (options = {}) => {
3476
+ const listeners = new Set;
3477
+ let closed = false;
3478
+ let timer;
3479
+ let snapshot = {
3480
+ actions: options.actions ?? createVoiceOpsActionCenterActions(),
3481
+ error: null,
3482
+ isRunning: false
3483
+ };
3484
+ const emit = () => {
3485
+ for (const listener of listeners) {
3486
+ listener();
3487
+ }
3488
+ };
3489
+ const setActions = (actions) => {
3490
+ snapshot = { ...snapshot, actions, updatedAt: Date.now() };
3491
+ emit();
3492
+ };
3493
+ const run = async (actionId) => {
3494
+ if (closed) {
3495
+ return snapshot.lastResult;
3496
+ }
3497
+ const action = snapshot.actions.find((item) => item.id === actionId);
3498
+ if (!action) {
3499
+ throw new Error(`Voice ops action "${actionId}" is not configured.`);
3500
+ }
3501
+ if (action.disabled) {
3502
+ throw new Error(`Voice ops action "${actionId}" is disabled.`);
3503
+ }
3504
+ snapshot = {
3505
+ ...snapshot,
3506
+ error: null,
3507
+ isRunning: true,
3508
+ runningActionId: action.id
3509
+ };
3510
+ emit();
3511
+ try {
3512
+ const result = await runVoiceOpsAction(action, options);
3513
+ await options.onActionResult?.(result);
3514
+ await recordVoiceOpsActionResult(result, options);
3515
+ snapshot = {
3516
+ ...snapshot,
3517
+ error: null,
3518
+ isRunning: false,
3519
+ lastResult: result,
3520
+ runningActionId: undefined,
3521
+ updatedAt: Date.now()
3522
+ };
3523
+ emit();
3524
+ return result;
3525
+ } catch (error) {
3526
+ const result = {
3527
+ actionId: action.id,
3528
+ body: null,
3529
+ error: error instanceof Error ? error.message : String(error),
3530
+ ok: false,
3531
+ ranAt: Date.now(),
3532
+ status: 0
3533
+ };
3534
+ await options.onActionResult?.(result);
3535
+ await recordVoiceOpsActionResult(result, options).catch(() => {});
3536
+ snapshot = {
3537
+ ...snapshot,
3538
+ error: error instanceof Error ? error.message : String(error),
3539
+ isRunning: false,
3540
+ runningActionId: undefined
3541
+ };
3542
+ emit();
3543
+ throw error;
3544
+ }
3545
+ };
3546
+ const close = () => {
3547
+ closed = true;
3548
+ if (timer) {
3549
+ clearInterval(timer);
3550
+ timer = undefined;
3551
+ }
3552
+ listeners.clear();
3553
+ };
3554
+ if (options.intervalMs && options.intervalMs > 0) {
3555
+ timer = setInterval(() => {
3556
+ emit();
3557
+ }, options.intervalMs);
3558
+ }
3559
+ return {
3560
+ close,
3561
+ getServerSnapshot: () => snapshot,
3562
+ getSnapshot: () => snapshot,
3563
+ run,
3564
+ setActions,
3565
+ subscribe: (listener) => {
3566
+ listeners.add(listener);
3567
+ return () => {
3568
+ listeners.delete(listener);
3569
+ };
3570
+ }
3571
+ };
3572
+ };
3573
+
3574
+ // src/angular/voice-ops-action-center.service.ts
3575
+ var _dec = [
3576
+ Injectable16({ providedIn: "root" })
3577
+ ];
3578
+ var _init = __decoratorStart(undefined);
3579
+
3580
+ class VoiceOpsActionCenterService {
3581
+ connect(options = {}) {
3582
+ const store = createVoiceOpsActionCenterStore(options);
3583
+ const actionsSignal = signal16([]);
3584
+ const errorSignal = signal16(null);
3585
+ const isRunningSignal = signal16(false);
3586
+ const lastResultSignal = signal16(undefined);
3587
+ const runningActionIdSignal = signal16(undefined);
3588
+ const sync = () => {
3589
+ const snapshot = store.getSnapshot();
3590
+ actionsSignal.set(snapshot.actions);
3591
+ errorSignal.set(snapshot.error);
3592
+ isRunningSignal.set(snapshot.isRunning);
3593
+ lastResultSignal.set(snapshot.lastResult);
3594
+ runningActionIdSignal.set(snapshot.runningActionId);
3595
+ };
3596
+ const unsubscribe = store.subscribe(sync);
3597
+ sync();
3598
+ return {
3599
+ actions: computed16(() => actionsSignal()),
3600
+ close: () => {
3601
+ unsubscribe();
3602
+ store.close();
3603
+ },
3604
+ error: computed16(() => errorSignal()),
3605
+ isRunning: computed16(() => isRunningSignal()),
3606
+ lastResult: computed16(() => lastResultSignal()),
3607
+ run: store.run,
3608
+ runningActionId: computed16(() => runningActionIdSignal()),
3609
+ setActions: store.setActions
3610
+ };
3611
+ }
3612
+ }
3613
+ VoiceOpsActionCenterService = __decorateElement(_init, 0, "VoiceOpsActionCenterService", _dec, VoiceOpsActionCenterService);
3614
+ __runInitializers(_init, 1, VoiceOpsActionCenterService);
3615
+ __decoratorMetadata(_init, VoiceOpsActionCenterService);
3616
+ let _VoiceOpsActionCenterService = VoiceOpsActionCenterService;
3617
+ // src/angular/voice-live-ops.service.ts
3618
+ import { computed as computed17, Injectable as Injectable17, signal as signal17 } from "@angular/core";
3619
+
3620
+ // src/client/liveOps.ts
3621
+ var postVoiceLiveOpsAction = async (input, options = {}) => {
3622
+ if (!input.sessionId) {
3623
+ throw new Error("Start a voice session before running live ops actions.");
3624
+ }
3625
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3626
+ const response = await fetchImpl(options.actionPath ?? "/api/voice/live-ops/action", {
3627
+ body: JSON.stringify(input),
3628
+ headers: {
3629
+ "Content-Type": "application/json"
3630
+ },
3631
+ method: "POST"
3632
+ });
3633
+ const payload = await response.json().catch(() => null);
3634
+ if (!response.ok || !payload?.ok) {
3635
+ const message = payload && typeof payload === "object" && "error" in payload ? String(payload.error) : `Voice live ops action failed: HTTP ${response.status}`;
3636
+ throw new Error(message);
3637
+ }
3638
+ return payload;
3639
+ };
3640
+ var createVoiceLiveOpsStore = (options = {}) => {
3641
+ const listeners = new Set;
3642
+ let closed = false;
3643
+ let snapshot = {
3644
+ error: null,
3645
+ isRunning: false
3646
+ };
3647
+ const emit = () => {
3648
+ for (const listener of listeners) {
3649
+ listener();
3650
+ }
3651
+ };
3652
+ const run = async (input) => {
3653
+ if (closed) {
3654
+ return snapshot.lastResult;
3655
+ }
3656
+ snapshot = {
3657
+ ...snapshot,
3658
+ error: null,
3659
+ isRunning: true,
3660
+ runningAction: input.action
3661
+ };
3662
+ emit();
3663
+ try {
3664
+ const result = await postVoiceLiveOpsAction(input, options);
3665
+ await options.onControl?.(result);
3666
+ snapshot = {
3667
+ ...snapshot,
3668
+ error: null,
3669
+ isRunning: false,
3670
+ lastResult: result,
3671
+ runningAction: undefined,
3672
+ updatedAt: Date.now()
3673
+ };
3674
+ emit();
3675
+ return result;
3676
+ } catch (error) {
3677
+ snapshot = {
3678
+ ...snapshot,
3679
+ error: error instanceof Error ? error.message : String(error),
3680
+ isRunning: false,
3681
+ runningAction: undefined,
3682
+ updatedAt: Date.now()
3683
+ };
3684
+ emit();
3685
+ throw error;
3686
+ }
3687
+ };
3688
+ const close = () => {
3689
+ closed = true;
3690
+ listeners.clear();
3691
+ };
3692
+ return {
3693
+ close,
3694
+ getServerSnapshot: () => snapshot,
3695
+ getSnapshot: () => snapshot,
3696
+ run,
3697
+ subscribe: (listener) => {
3698
+ listeners.add(listener);
3699
+ return () => {
3700
+ listeners.delete(listener);
3701
+ };
3702
+ }
3703
+ };
3704
+ };
3705
+
3706
+ // src/angular/voice-live-ops.service.ts
3707
+ var _dec = [
3708
+ Injectable17({ providedIn: "root" })
3709
+ ];
3710
+ var _init = __decoratorStart(undefined);
3711
+
3712
+ class VoiceLiveOpsService {
3713
+ connect(options = {}) {
3714
+ const store = createVoiceLiveOpsStore(options);
3715
+ const errorSignal = signal17(null);
3716
+ const isRunningSignal = signal17(false);
3717
+ const lastResultSignal = signal17(undefined);
3718
+ const runningActionSignal = signal17(undefined);
3719
+ const sync = () => {
3720
+ const snapshot = store.getSnapshot();
3721
+ errorSignal.set(snapshot.error);
3722
+ isRunningSignal.set(snapshot.isRunning);
3723
+ lastResultSignal.set(snapshot.lastResult);
3724
+ runningActionSignal.set(snapshot.runningAction);
3725
+ };
3726
+ const unsubscribe = store.subscribe(sync);
3727
+ sync();
3728
+ return {
3729
+ close: () => {
3730
+ unsubscribe();
3731
+ store.close();
3732
+ },
3733
+ error: computed17(() => errorSignal()),
3734
+ isRunning: computed17(() => isRunningSignal()),
3735
+ lastResult: computed17(() => lastResultSignal()),
3736
+ run: store.run,
3737
+ runningAction: computed17(() => runningActionSignal())
3738
+ };
3739
+ }
3740
+ }
3741
+ VoiceLiveOpsService = __decorateElement(_init, 0, "VoiceLiveOpsService", _dec, VoiceLiveOpsService);
3742
+ __runInitializers(_init, 1, VoiceLiveOpsService);
3743
+ __decoratorMetadata(_init, VoiceLiveOpsService);
3744
+ let _VoiceLiveOpsService = VoiceLiveOpsService;
3745
+ // src/angular/voice-delivery-runtime.service.ts
3746
+ import { computed as computed18, Injectable as Injectable18, signal as signal18 } from "@angular/core";
3747
+
3748
+ // src/client/deliveryRuntime.ts
3749
+ var getDefaultActionPath = (path, action, options) => {
3750
+ if (action === "tick") {
3751
+ return options.tickPath ?? `${path.replace(/\/$/, "")}/tick`;
3752
+ }
3753
+ return options.requeueDeadLettersPath ?? `${path.replace(/\/$/, "")}/requeue-dead-letters`;
3754
+ };
3755
+ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
3756
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3757
+ const response = await fetchImpl(path);
3758
+ if (!response.ok) {
3759
+ throw new Error(`Voice delivery runtime failed: HTTP ${response.status}`);
3760
+ }
3761
+ return await response.json();
3762
+ };
3763
+ var runVoiceDeliveryRuntimeAction = async (action, path = "/api/voice-delivery-runtime", options = {}) => {
3764
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3765
+ const response = await fetchImpl(getDefaultActionPath(path, action, options), {
3766
+ method: "POST"
3767
+ });
3768
+ if (!response.ok) {
3769
+ throw new Error(`Voice delivery runtime ${action} failed: HTTP ${response.status}`);
3770
+ }
3771
+ const body = await response.json();
3772
+ return {
3773
+ action,
3774
+ result: body.result,
3775
+ summary: body.summary,
3776
+ updatedAt: Date.now()
3777
+ };
3778
+ };
3779
+ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
3780
+ const listeners = new Set;
3781
+ let closed = false;
3782
+ let timer;
3783
+ let snapshot = {
3784
+ actionError: null,
3785
+ actionStatus: "idle",
3786
+ error: null,
3787
+ isLoading: false
3788
+ };
3789
+ const emit = () => {
3790
+ for (const listener of listeners) {
3791
+ listener();
3792
+ }
3793
+ };
3794
+ const refresh = async () => {
3795
+ if (closed) {
3796
+ return snapshot.report;
3797
+ }
3798
+ snapshot = {
3799
+ ...snapshot,
3800
+ error: null,
3801
+ isLoading: true
3802
+ };
3803
+ emit();
3804
+ try {
3805
+ const report = await fetchVoiceDeliveryRuntime(path, options);
3806
+ snapshot = {
3807
+ ...snapshot,
3808
+ error: null,
3809
+ isLoading: false,
3810
+ report,
3811
+ updatedAt: Date.now()
3812
+ };
3813
+ emit();
3814
+ return report;
3815
+ } catch (error) {
3816
+ snapshot = {
3817
+ ...snapshot,
3818
+ error: error instanceof Error ? error.message : String(error),
3819
+ isLoading: false
3820
+ };
3821
+ emit();
3822
+ throw error;
3823
+ }
3824
+ };
3825
+ const runAction = async (action) => {
3826
+ if (closed) {
3827
+ return snapshot.lastAction;
3828
+ }
3829
+ snapshot = {
3830
+ ...snapshot,
3831
+ actionError: null,
3832
+ actionStatus: "running"
3833
+ };
3834
+ emit();
3835
+ try {
3836
+ const result = await runVoiceDeliveryRuntimeAction(action, path, options);
3837
+ snapshot = {
3838
+ ...snapshot,
3839
+ actionError: null,
3840
+ actionStatus: "completed",
3841
+ lastAction: result
3842
+ };
3843
+ emit();
3844
+ await refresh();
3845
+ return result;
3846
+ } catch (error) {
3847
+ snapshot = {
3848
+ ...snapshot,
3849
+ actionError: error instanceof Error ? error.message : String(error),
3850
+ actionStatus: "failed"
3851
+ };
3852
+ emit();
3853
+ throw error;
3854
+ }
3855
+ };
3856
+ const close = () => {
3857
+ closed = true;
3858
+ if (timer) {
3859
+ clearInterval(timer);
3860
+ timer = undefined;
3861
+ }
3862
+ listeners.clear();
3863
+ };
3864
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
3865
+ timer = setInterval(() => {
3866
+ refresh().catch(() => {});
3867
+ }, options.intervalMs);
3868
+ }
3869
+ return {
3870
+ close,
3871
+ getServerSnapshot: () => snapshot,
3872
+ getSnapshot: () => snapshot,
3873
+ requeueDeadLetters: () => runAction("requeue-dead-letters"),
3874
+ refresh,
3875
+ tick: () => runAction("tick"),
3876
+ subscribe: (listener) => {
3877
+ listeners.add(listener);
3878
+ return () => {
3879
+ listeners.delete(listener);
3880
+ };
3881
+ }
3882
+ };
3883
+ };
3884
+
3885
+ // src/angular/voice-delivery-runtime.service.ts
3886
+ var _dec = [
3887
+ Injectable18({ providedIn: "root" })
3888
+ ];
3889
+ var _init = __decoratorStart(undefined);
3890
+
3891
+ class VoiceDeliveryRuntimeService {
3892
+ connect(path = "/api/voice-delivery-runtime", options = {}) {
3893
+ const store = createVoiceDeliveryRuntimeStore(path, options);
3894
+ const actionErrorSignal = signal18(null);
3895
+ const actionStatusSignal = signal18("idle");
3896
+ const errorSignal = signal18(null);
3897
+ const isLoadingSignal = signal18(false);
3898
+ const reportSignal = signal18(undefined);
3899
+ const updatedAtSignal = signal18(undefined);
3900
+ const sync = () => {
3901
+ const snapshot = store.getSnapshot();
3902
+ actionErrorSignal.set(snapshot.actionError);
3903
+ actionStatusSignal.set(snapshot.actionStatus);
3904
+ errorSignal.set(snapshot.error);
3905
+ isLoadingSignal.set(snapshot.isLoading);
3906
+ reportSignal.set(snapshot.report);
3907
+ updatedAtSignal.set(snapshot.updatedAt);
3908
+ };
3909
+ const unsubscribe = store.subscribe(sync);
3910
+ sync();
3911
+ if (typeof window !== "undefined") {
3912
+ store.refresh().catch(() => {});
3913
+ }
3914
+ return {
3915
+ close: () => {
3916
+ unsubscribe();
3917
+ store.close();
3918
+ },
3919
+ error: computed18(() => errorSignal()),
3920
+ actionError: computed18(() => actionErrorSignal()),
3921
+ actionStatus: computed18(() => actionStatusSignal()),
3922
+ isLoading: computed18(() => isLoadingSignal()),
3923
+ requeueDeadLetters: store.requeueDeadLetters,
3924
+ refresh: store.refresh,
3925
+ report: computed18(() => reportSignal()),
3926
+ tick: store.tick,
3927
+ updatedAt: computed18(() => updatedAtSignal())
3928
+ };
3929
+ }
3930
+ }
3931
+ VoiceDeliveryRuntimeService = __decorateElement(_init, 0, "VoiceDeliveryRuntimeService", _dec, VoiceDeliveryRuntimeService);
3932
+ __runInitializers(_init, 1, VoiceDeliveryRuntimeService);
3933
+ __decoratorMetadata(_init, VoiceDeliveryRuntimeService);
3934
+ let _VoiceDeliveryRuntimeService = VoiceDeliveryRuntimeService;
3935
+ // src/angular/voice-campaign-dialer-proof.service.ts
3936
+ import { computed as computed19, Injectable as Injectable19, signal as signal19 } from "@angular/core";
3937
+
3938
+ // src/client/campaignDialerProof.ts
3939
+ var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3940
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3941
+ const response = await fetchImpl(path);
3942
+ if (!response.ok) {
3943
+ throw new Error(`Voice campaign dialer proof status failed: HTTP ${response.status}`);
3944
+ }
3945
+ return await response.json();
3946
+ };
3947
+ var runVoiceCampaignDialerProofAction = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3948
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3949
+ const response = await fetchImpl(path, { method: "POST" });
3950
+ if (!response.ok) {
3951
+ throw new Error(`Voice campaign dialer proof failed: HTTP ${response.status}`);
3952
+ }
3953
+ return await response.json();
3954
+ };
3955
+ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3956
+ const listeners = new Set;
3957
+ let closed = false;
3958
+ let timer;
3959
+ let snapshot = {
3960
+ error: null,
3961
+ isLoading: false
3962
+ };
3963
+ const emit = () => {
3964
+ for (const listener of listeners) {
3965
+ listener();
3966
+ }
3967
+ };
3968
+ const refresh = async () => {
3969
+ if (closed) {
3970
+ return snapshot.status;
3971
+ }
3972
+ snapshot = { ...snapshot, error: null, isLoading: true };
3973
+ emit();
3974
+ try {
3975
+ const status = await fetchVoiceCampaignDialerProofStatus(path, options);
3976
+ snapshot = {
3977
+ ...snapshot,
3978
+ error: null,
3979
+ isLoading: false,
3980
+ status,
3981
+ updatedAt: Date.now()
3982
+ };
3983
+ emit();
3984
+ return status;
3985
+ } catch (error) {
3986
+ snapshot = {
3987
+ ...snapshot,
3988
+ error: error instanceof Error ? error.message : String(error),
3989
+ isLoading: false
3990
+ };
3991
+ emit();
3992
+ throw error;
3993
+ }
3994
+ };
3995
+ const runProof = async () => {
3996
+ const runPath = options.runPath ?? snapshot.status?.runPath ?? path;
3997
+ snapshot = { ...snapshot, error: null, isLoading: true };
3998
+ emit();
3999
+ try {
4000
+ const report = await runVoiceCampaignDialerProofAction(runPath, options);
4001
+ snapshot = {
4002
+ ...snapshot,
4003
+ error: null,
4004
+ isLoading: false,
4005
+ report,
4006
+ status: {
4007
+ generatedAt: Date.now(),
4008
+ mode: report.mode,
4009
+ ok: report.ok,
4010
+ providers: report.providers.map((provider) => provider.provider),
4011
+ runPath,
4012
+ safe: true
4013
+ },
4014
+ updatedAt: Date.now()
4015
+ };
4016
+ emit();
4017
+ return report;
4018
+ } catch (error) {
4019
+ snapshot = {
4020
+ ...snapshot,
4021
+ error: error instanceof Error ? error.message : String(error),
4022
+ isLoading: false
4023
+ };
4024
+ emit();
4025
+ throw error;
4026
+ }
4027
+ };
4028
+ const close = () => {
4029
+ closed = true;
4030
+ if (timer) {
4031
+ clearInterval(timer);
4032
+ timer = undefined;
4033
+ }
4034
+ listeners.clear();
4035
+ };
4036
+ if (options.intervalMs && options.intervalMs > 0) {
4037
+ timer = setInterval(() => {
4038
+ refresh().catch(() => {});
4039
+ }, options.intervalMs);
4040
+ }
4041
+ return {
4042
+ close,
4043
+ getServerSnapshot: () => snapshot,
4044
+ getSnapshot: () => snapshot,
4045
+ refresh,
4046
+ runProof,
4047
+ subscribe: (listener) => {
4048
+ listeners.add(listener);
4049
+ return () => {
4050
+ listeners.delete(listener);
4051
+ };
4052
+ }
4053
+ };
4054
+ };
4055
+
4056
+ // src/angular/voice-campaign-dialer-proof.service.ts
4057
+ var _dec = [
4058
+ Injectable19({ providedIn: "root" })
4059
+ ];
4060
+ var _init = __decoratorStart(undefined);
4061
+
4062
+ class VoiceCampaignDialerProofService {
4063
+ connect(path = "/api/voice/campaigns/dialer-proof", options = {}) {
4064
+ const store = createVoiceCampaignDialerProofStore(path, options);
4065
+ const errorSignal = signal19(null);
4066
+ const isLoadingSignal = signal19(false);
4067
+ const reportSignal = signal19(undefined);
4068
+ const statusSignal = signal19(undefined);
4069
+ const updatedAtSignal = signal19(undefined);
4070
+ const sync = () => {
4071
+ const snapshot = store.getSnapshot();
4072
+ errorSignal.set(snapshot.error);
4073
+ isLoadingSignal.set(snapshot.isLoading);
4074
+ reportSignal.set(snapshot.report);
4075
+ statusSignal.set(snapshot.status);
4076
+ updatedAtSignal.set(snapshot.updatedAt);
4077
+ };
4078
+ const unsubscribe = store.subscribe(sync);
4079
+ sync();
4080
+ store.refresh().catch(() => {});
4081
+ return {
4082
+ close: () => {
4083
+ unsubscribe();
4084
+ store.close();
4085
+ },
4086
+ error: computed19(() => errorSignal()),
4087
+ isLoading: computed19(() => isLoadingSignal()),
4088
+ refresh: store.refresh,
4089
+ report: computed19(() => reportSignal()),
4090
+ runProof: store.runProof,
4091
+ status: computed19(() => statusSignal()),
4092
+ updatedAt: computed19(() => updatedAtSignal())
4093
+ };
4094
+ }
4095
+ }
4096
+ VoiceCampaignDialerProofService = __decorateElement(_init, 0, "VoiceCampaignDialerProofService", _dec, VoiceCampaignDialerProofService);
4097
+ __runInitializers(_init, 1, VoiceCampaignDialerProofService);
4098
+ __decoratorMetadata(_init, VoiceCampaignDialerProofService);
4099
+ let _VoiceCampaignDialerProofService = VoiceCampaignDialerProofService;
4100
+ // src/angular/voice-stream.service.ts
4101
+ import { computed as computed20, Injectable as Injectable20, signal as signal20 } from "@angular/core";
4102
+ var _dec = [
4103
+ Injectable20({ providedIn: "root" })
4104
+ ];
4105
+ var _init = __decoratorStart(undefined);
4106
+
4107
+ class VoiceStreamService {
4108
+ connect(path, options = {}) {
4109
+ const stream = createVoiceStream(path, options);
4110
+ const assistantAudioSignal = signal20([]);
4111
+ const assistantTextsSignal = signal20([]);
4112
+ const callSignal = signal20(null);
4113
+ const errorSignal = signal20(null);
4114
+ const isConnectedSignal = signal20(false);
4115
+ const partialSignal = signal20("");
4116
+ const reconnectSignal = signal20(stream.reconnect);
4117
+ const sessionIdSignal = signal20(stream.sessionId);
4118
+ const sessionMetadataSignal = signal20(stream.sessionMetadata);
4119
+ const statusSignal = signal20(stream.status);
4120
+ const turnsSignal = signal20([]);
4121
+ const sync = () => {
4122
+ assistantAudioSignal.set([...stream.assistantAudio]);
4123
+ assistantTextsSignal.set([...stream.assistantTexts]);
4124
+ callSignal.set(stream.call);
4125
+ errorSignal.set(stream.error);
4126
+ isConnectedSignal.set(stream.isConnected);
4127
+ partialSignal.set(stream.partial);
4128
+ reconnectSignal.set(stream.reconnect);
4129
+ sessionIdSignal.set(stream.sessionId);
4130
+ sessionMetadataSignal.set(stream.sessionMetadata);
4131
+ statusSignal.set(stream.status);
4132
+ turnsSignal.set([...stream.turns]);
4133
+ };
4134
+ const unsubscribe = stream.subscribe(sync);
4135
+ sync();
4136
+ return {
4137
+ assistantAudio: computed20(() => assistantAudioSignal()),
4138
+ assistantTexts: computed20(() => assistantTextsSignal()),
4139
+ call: computed20(() => callSignal()),
4140
+ callControl: (message) => stream.callControl(message),
4141
+ close: () => {
4142
+ unsubscribe();
4143
+ stream.close();
4144
+ },
4145
+ endTurn: () => stream.endTurn(),
4146
+ error: computed20(() => errorSignal()),
4147
+ isConnected: computed20(() => isConnectedSignal()),
4148
+ partial: computed20(() => partialSignal()),
4149
+ reconnect: computed20(() => reconnectSignal()),
4150
+ sendAudio: (audio) => stream.sendAudio(audio),
4151
+ simulateDisconnect: () => stream.simulateDisconnect(),
4152
+ sessionId: computed20(() => sessionIdSignal()),
4153
+ sessionMetadata: computed20(() => sessionMetadataSignal()),
4154
+ status: computed20(() => statusSignal()),
4155
+ turns: computed20(() => turnsSignal())
4156
+ };
4157
+ }
4158
+ }
4159
+ VoiceStreamService = __decorateElement(_init, 0, "VoiceStreamService", _dec, VoiceStreamService);
4160
+ __runInitializers(_init, 1, VoiceStreamService);
4161
+ __decoratorMetadata(_init, VoiceStreamService);
4162
+ let _VoiceStreamService = VoiceStreamService;
4163
+ // src/angular/voice-controller.service.ts
4164
+ import { computed as computed21, Injectable as Injectable21, signal as signal21 } from "@angular/core";
4165
+ var _dec = [
4166
+ Injectable21({ providedIn: "root" })
4167
+ ];
4168
+ var _init = __decoratorStart(undefined);
4169
+
4170
+ class VoiceControllerService {
4171
+ connect(path, options = {}) {
4172
+ const controller = createVoiceController(path, options);
4173
+ const assistantAudioSignal = signal21([]);
4174
+ const assistantTextsSignal = signal21([]);
4175
+ const errorSignal = signal21(null);
4176
+ const isConnectedSignal = signal21(false);
4177
+ const isRecordingSignal = signal21(false);
4178
+ const partialSignal = signal21("");
4179
+ const reconnectSignal = signal21(controller.reconnect);
4180
+ const recordingErrorSignal = signal21(null);
4181
+ const sessionIdSignal = signal21(controller.sessionId);
4182
+ const statusSignal = signal21(controller.status);
4183
+ const turnsSignal = signal21([]);
4184
+ const sync = () => {
4185
+ assistantAudioSignal.set([...controller.assistantAudio]);
4186
+ assistantTextsSignal.set([...controller.assistantTexts]);
4187
+ errorSignal.set(controller.error);
4188
+ isConnectedSignal.set(controller.isConnected);
4189
+ isRecordingSignal.set(controller.isRecording);
4190
+ partialSignal.set(controller.partial);
4191
+ reconnectSignal.set(controller.reconnect);
4192
+ recordingErrorSignal.set(controller.recordingError);
4193
+ sessionIdSignal.set(controller.sessionId);
4194
+ statusSignal.set(controller.status);
4195
+ turnsSignal.set([...controller.turns]);
4196
+ };
4197
+ const unsubscribe = controller.subscribe(sync);
4198
+ sync();
4199
+ return {
4200
+ assistantAudio: computed21(() => assistantAudioSignal()),
4201
+ assistantTexts: computed21(() => assistantTextsSignal()),
4202
+ bindHTMX: controller.bindHTMX,
4203
+ close: () => {
4204
+ unsubscribe();
4205
+ controller.close();
4206
+ },
4207
+ endTurn: () => controller.endTurn(),
4208
+ error: computed21(() => errorSignal()),
4209
+ isConnected: computed21(() => isConnectedSignal()),
4210
+ isRecording: computed21(() => isRecordingSignal()),
4211
+ partial: computed21(() => partialSignal()),
4212
+ reconnect: computed21(() => reconnectSignal()),
4213
+ recordingError: computed21(() => recordingErrorSignal()),
4214
+ sendAudio: (audio) => controller.sendAudio(audio),
4215
+ simulateDisconnect: () => controller.simulateDisconnect(),
4216
+ sessionId: computed21(() => sessionIdSignal()),
4217
+ startRecording: () => controller.startRecording(),
4218
+ status: computed21(() => statusSignal()),
4219
+ stopRecording: () => controller.stopRecording(),
4220
+ toggleRecording: () => controller.toggleRecording(),
4221
+ turns: computed21(() => turnsSignal())
4222
+ };
4223
+ }
4224
+ }
4225
+ VoiceControllerService = __decorateElement(_init, 0, "VoiceControllerService", _dec, VoiceControllerService);
4226
+ __runInitializers(_init, 1, VoiceControllerService);
4227
+ __decoratorMetadata(_init, VoiceControllerService);
4228
+ let _VoiceControllerService = VoiceControllerService;
4229
+ // src/angular/voice-provider-capabilities.service.ts
4230
+ import { computed as computed22, Injectable as Injectable22, signal as signal22 } from "@angular/core";
4231
+
4232
+ // src/client/providerCapabilities.ts
4233
+ var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
4234
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4235
+ const response = await fetchImpl(path);
4236
+ if (!response.ok) {
4237
+ throw new Error(`Voice provider capabilities failed: HTTP ${response.status}`);
4238
+ }
4239
+ return await response.json();
4240
+ };
4241
+ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities", options = {}) => {
4242
+ const listeners = new Set;
4243
+ let closed = false;
4244
+ let timer;
4245
+ let snapshot = {
4246
+ error: null,
4247
+ isLoading: false
4248
+ };
4249
+ const emit = () => {
4250
+ for (const listener of listeners) {
4251
+ listener();
4252
+ }
4253
+ };
4254
+ const refresh = async () => {
4255
+ if (closed) {
4256
+ return snapshot.report;
4257
+ }
4258
+ snapshot = {
4259
+ ...snapshot,
4260
+ error: null,
4261
+ isLoading: true
4262
+ };
4263
+ emit();
4264
+ try {
4265
+ const report = await fetchVoiceProviderCapabilities(path, options);
4266
+ snapshot = {
4267
+ error: null,
4268
+ isLoading: false,
4269
+ report,
4270
+ updatedAt: Date.now()
4271
+ };
4272
+ emit();
4273
+ return report;
4274
+ } catch (error) {
4275
+ snapshot = {
4276
+ ...snapshot,
4277
+ error: error instanceof Error ? error.message : String(error),
4278
+ isLoading: false
4279
+ };
4280
+ emit();
4281
+ throw error;
4282
+ }
4283
+ };
4284
+ const close = () => {
4285
+ closed = true;
4286
+ if (timer) {
4287
+ clearInterval(timer);
4288
+ timer = undefined;
4289
+ }
4290
+ listeners.clear();
4291
+ };
4292
+ if (options.intervalMs && options.intervalMs > 0) {
4293
+ timer = setInterval(() => {
4294
+ refresh().catch(() => {});
4295
+ }, options.intervalMs);
4296
+ }
4297
+ return {
4298
+ close,
4299
+ getServerSnapshot: () => snapshot,
4300
+ getSnapshot: () => snapshot,
4301
+ refresh,
4302
+ subscribe: (listener) => {
4303
+ listeners.add(listener);
4304
+ return () => {
4305
+ listeners.delete(listener);
4306
+ };
4307
+ }
4308
+ };
4309
+ };
4310
+
4311
+ // src/angular/voice-provider-capabilities.service.ts
4312
+ var _dec = [
4313
+ Injectable22({ providedIn: "root" })
4314
+ ];
4315
+ var _init = __decoratorStart(undefined);
4316
+
4317
+ class VoiceProviderCapabilitiesService {
4318
+ connect(path = "/api/provider-capabilities", options = {}) {
4319
+ const store = createVoiceProviderCapabilitiesStore(path, options);
4320
+ const errorSignal = signal22(null);
4321
+ const isLoadingSignal = signal22(false);
4322
+ const reportSignal = signal22(undefined);
4323
+ const updatedAtSignal = signal22(undefined);
4324
+ const sync = () => {
4325
+ const snapshot = store.getSnapshot();
4326
+ errorSignal.set(snapshot.error);
4327
+ isLoadingSignal.set(snapshot.isLoading);
4328
+ reportSignal.set(snapshot.report);
4329
+ updatedAtSignal.set(snapshot.updatedAt);
4330
+ };
4331
+ const unsubscribe = store.subscribe(sync);
4332
+ sync();
4333
+ store.refresh().catch(() => {});
4334
+ return {
4335
+ close: () => {
4336
+ unsubscribe();
4337
+ store.close();
4338
+ },
4339
+ error: computed22(() => errorSignal()),
4340
+ isLoading: computed22(() => isLoadingSignal()),
4341
+ refresh: store.refresh,
4342
+ report: computed22(() => reportSignal()),
4343
+ updatedAt: computed22(() => updatedAtSignal())
4344
+ };
4345
+ }
4346
+ }
4347
+ VoiceProviderCapabilitiesService = __decorateElement(_init, 0, "VoiceProviderCapabilitiesService", _dec, VoiceProviderCapabilitiesService);
4348
+ __runInitializers(_init, 1, VoiceProviderCapabilitiesService);
4349
+ __decoratorMetadata(_init, VoiceProviderCapabilitiesService);
4350
+ let _VoiceProviderCapabilitiesService = VoiceProviderCapabilitiesService;
4351
+ // src/angular/voice-provider-contracts.service.ts
4352
+ import { computed as computed23, Injectable as Injectable23, signal as signal23 } from "@angular/core";
4353
+
4354
+ // src/client/providerContracts.ts
4355
+ var fetchVoiceProviderContracts = async (path = "/api/provider-contracts", options = {}) => {
4356
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4357
+ const response = await fetchImpl(path);
4358
+ if (!response.ok) {
4359
+ throw new Error(`Voice provider contracts failed: HTTP ${response.status}`);
4360
+ }
4361
+ return await response.json();
4362
+ };
4363
+ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", options = {}) => {
4364
+ const listeners = new Set;
4365
+ let closed = false;
4366
+ let timer;
4367
+ let snapshot = {
4368
+ error: null,
4369
+ isLoading: false
4370
+ };
4371
+ const emit = () => {
4372
+ for (const listener of listeners) {
4373
+ listener();
4374
+ }
4375
+ };
4376
+ const refresh = async () => {
4377
+ if (closed) {
4378
+ return snapshot.report;
4379
+ }
4380
+ snapshot = { ...snapshot, error: null, isLoading: true };
4381
+ emit();
4382
+ try {
4383
+ const report = await fetchVoiceProviderContracts(path, options);
4384
+ snapshot = {
4385
+ error: null,
4386
+ isLoading: false,
4387
+ report,
4388
+ updatedAt: Date.now()
4389
+ };
4390
+ emit();
4391
+ return report;
4392
+ } catch (error) {
4393
+ snapshot = {
4394
+ ...snapshot,
4395
+ error: error instanceof Error ? error.message : String(error),
4396
+ isLoading: false
4397
+ };
4398
+ emit();
4399
+ throw error;
4400
+ }
4401
+ };
4402
+ const close = () => {
4403
+ closed = true;
4404
+ if (timer) {
4405
+ clearInterval(timer);
4406
+ timer = undefined;
4407
+ }
4408
+ listeners.clear();
4409
+ };
4410
+ if (options.intervalMs && options.intervalMs > 0) {
4411
+ timer = setInterval(() => {
4412
+ refresh().catch(() => {});
4413
+ }, options.intervalMs);
4414
+ }
4415
+ return {
4416
+ close,
4417
+ getServerSnapshot: () => snapshot,
4418
+ getSnapshot: () => snapshot,
4419
+ refresh,
4420
+ subscribe: (listener) => {
4421
+ listeners.add(listener);
4422
+ return () => {
4423
+ listeners.delete(listener);
4424
+ };
4425
+ }
4426
+ };
4427
+ };
4428
+
4429
+ // src/angular/voice-provider-contracts.service.ts
4430
+ var _dec = [
4431
+ Injectable23({ providedIn: "root" })
4432
+ ];
4433
+ var _init = __decoratorStart(undefined);
4434
+
4435
+ class VoiceProviderContractsService {
4436
+ connect(path = "/api/provider-contracts", options = {}) {
4437
+ const store = createVoiceProviderContractsStore(path, options);
4438
+ const errorSignal = signal23(null);
4439
+ const isLoadingSignal = signal23(false);
4440
+ const reportSignal = signal23(undefined);
4441
+ const updatedAtSignal = signal23(undefined);
4442
+ const sync = () => {
4443
+ const snapshot = store.getSnapshot();
4444
+ errorSignal.set(snapshot.error);
4445
+ isLoadingSignal.set(snapshot.isLoading);
4446
+ reportSignal.set(snapshot.report);
4447
+ updatedAtSignal.set(snapshot.updatedAt);
4448
+ };
4449
+ const unsubscribe = store.subscribe(sync);
4450
+ sync();
4451
+ store.refresh().catch(() => {});
4452
+ return {
4453
+ close: () => {
4454
+ unsubscribe();
4455
+ store.close();
4456
+ },
4457
+ error: computed23(() => errorSignal()),
4458
+ isLoading: computed23(() => isLoadingSignal()),
4459
+ refresh: store.refresh,
4460
+ report: computed23(() => reportSignal()),
4461
+ updatedAt: computed23(() => updatedAtSignal())
4462
+ };
4463
+ }
4464
+ }
4465
+ VoiceProviderContractsService = __decorateElement(_init, 0, "VoiceProviderContractsService", _dec, VoiceProviderContractsService);
4466
+ __runInitializers(_init, 1, VoiceProviderContractsService);
4467
+ __decoratorMetadata(_init, VoiceProviderContractsService);
4468
+ let _VoiceProviderContractsService = VoiceProviderContractsService;
4469
+ // src/angular/voice-provider-status.service.ts
4470
+ import { computed as computed24, Injectable as Injectable24, signal as signal24 } from "@angular/core";
4471
+
4472
+ // src/client/providerStatus.ts
4473
+ var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
4474
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4475
+ const response = await fetchImpl(path);
4476
+ if (!response.ok) {
4477
+ throw new Error(`Voice provider status failed: HTTP ${response.status}`);
4478
+ }
4479
+ return await response.json();
4480
+ };
4481
+ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {}) => {
4482
+ const listeners = new Set;
4483
+ let closed = false;
4484
+ let timer;
4485
+ let snapshot = {
4486
+ error: null,
4487
+ isLoading: false,
4488
+ providers: []
4489
+ };
4490
+ const emit = () => {
4491
+ for (const listener of listeners) {
4492
+ listener();
4493
+ }
4494
+ };
4495
+ const refresh = async () => {
4496
+ if (closed) {
4497
+ return snapshot.providers;
4498
+ }
4499
+ snapshot = {
4500
+ ...snapshot,
4501
+ error: null,
4502
+ isLoading: true
4503
+ };
4504
+ emit();
4505
+ try {
4506
+ const providers = await fetchVoiceProviderStatus(path, options);
4507
+ snapshot = {
4508
+ error: null,
4509
+ isLoading: false,
4510
+ providers,
4511
+ updatedAt: Date.now()
4512
+ };
4513
+ emit();
4514
+ return providers;
4515
+ } catch (error) {
4516
+ snapshot = {
4517
+ ...snapshot,
4518
+ error: error instanceof Error ? error.message : String(error),
4519
+ isLoading: false
4520
+ };
4521
+ emit();
4522
+ throw error;
4523
+ }
4524
+ };
4525
+ const close = () => {
4526
+ closed = true;
4527
+ if (timer) {
4528
+ clearInterval(timer);
4529
+ timer = undefined;
4530
+ }
4531
+ listeners.clear();
4532
+ };
4533
+ if (options.intervalMs && options.intervalMs > 0) {
4534
+ timer = setInterval(() => {
4535
+ refresh().catch(() => {});
4536
+ }, options.intervalMs);
4537
+ }
4538
+ return {
4539
+ close,
4540
+ getServerSnapshot: () => snapshot,
4541
+ getSnapshot: () => snapshot,
4542
+ refresh,
4543
+ subscribe: (listener) => {
4544
+ listeners.add(listener);
4545
+ return () => {
4546
+ listeners.delete(listener);
4547
+ };
4548
+ }
4549
+ };
4550
+ };
4551
+
4552
+ // src/angular/voice-provider-status.service.ts
4553
+ var _dec = [
4554
+ Injectable24({ providedIn: "root" })
4555
+ ];
4556
+ var _init = __decoratorStart(undefined);
4557
+
4558
+ class VoiceProviderStatusService {
4559
+ connect(path = "/api/provider-status", options = {}) {
4560
+ const store = createVoiceProviderStatusStore(path, options);
4561
+ const errorSignal = signal24(null);
4562
+ const isLoadingSignal = signal24(false);
4563
+ const providersSignal = signal24([]);
4564
+ const updatedAtSignal = signal24(undefined);
4565
+ const sync = () => {
4566
+ const snapshot = store.getSnapshot();
4567
+ errorSignal.set(snapshot.error);
4568
+ isLoadingSignal.set(snapshot.isLoading);
4569
+ providersSignal.set([...snapshot.providers]);
4570
+ updatedAtSignal.set(snapshot.updatedAt);
4571
+ };
4572
+ const unsubscribe = store.subscribe(sync);
4573
+ sync();
4574
+ store.refresh().catch(() => {});
4575
+ return {
4576
+ close: () => {
4577
+ unsubscribe();
4578
+ store.close();
4579
+ },
4580
+ error: computed24(() => errorSignal()),
4581
+ isLoading: computed24(() => isLoadingSignal()),
4582
+ providers: computed24(() => providersSignal()),
4583
+ refresh: store.refresh,
4584
+ updatedAt: computed24(() => updatedAtSignal())
4585
+ };
4586
+ }
4587
+ }
4588
+ VoiceProviderStatusService = __decorateElement(_init, 0, "VoiceProviderStatusService", _dec, VoiceProviderStatusService);
4589
+ __runInitializers(_init, 1, VoiceProviderStatusService);
4590
+ __decoratorMetadata(_init, VoiceProviderStatusService);
4591
+ let _VoiceProviderStatusService = VoiceProviderStatusService;
4592
+ // src/angular/voice-routing-status.service.ts
4593
+ import { Injectable as Injectable25, signal as signal25 } from "@angular/core";
4594
+
4595
+ // src/client/routingStatus.ts
4596
+ var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
4597
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4598
+ const response = await fetchImpl(path);
4599
+ if (!response.ok) {
4600
+ throw new Error(`Voice routing status failed: HTTP ${response.status}`);
4601
+ }
4602
+ return await response.json();
4603
+ };
4604
+ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {}) => {
4605
+ const listeners = new Set;
4606
+ let closed = false;
4607
+ let timer;
4608
+ let snapshot = {
4609
+ decision: null,
4610
+ error: null,
4611
+ isLoading: false
4612
+ };
4613
+ const emit = () => {
4614
+ for (const listener of listeners) {
4615
+ listener();
4616
+ }
4617
+ };
4618
+ const refresh = async () => {
4619
+ if (closed) {
4620
+ return snapshot.decision;
4621
+ }
4622
+ snapshot = {
4623
+ ...snapshot,
4624
+ error: null,
4625
+ isLoading: true
4626
+ };
4627
+ emit();
4628
+ try {
4629
+ const decision = await fetchVoiceRoutingStatus(path, options);
4630
+ snapshot = {
4631
+ decision,
4632
+ error: null,
4633
+ isLoading: false,
4634
+ updatedAt: Date.now()
4635
+ };
4636
+ emit();
4637
+ return decision;
4638
+ } catch (error) {
4639
+ snapshot = {
4640
+ ...snapshot,
4641
+ error: error instanceof Error ? error.message : String(error),
4642
+ isLoading: false
4643
+ };
4644
+ emit();
4645
+ throw error;
4646
+ }
4647
+ };
4648
+ const close = () => {
4649
+ closed = true;
4650
+ if (timer) {
4651
+ clearInterval(timer);
4652
+ timer = undefined;
4653
+ }
4654
+ listeners.clear();
4655
+ };
4656
+ if (options.intervalMs && options.intervalMs > 0) {
4657
+ timer = setInterval(() => {
4658
+ refresh().catch(() => {});
4659
+ }, options.intervalMs);
4660
+ }
4661
+ return {
4662
+ close,
4663
+ getServerSnapshot: () => snapshot,
4664
+ getSnapshot: () => snapshot,
4665
+ refresh,
4666
+ subscribe: (listener) => {
4667
+ listeners.add(listener);
4668
+ return () => {
4669
+ listeners.delete(listener);
4670
+ };
4671
+ }
4672
+ };
4673
+ };
4674
+
4675
+ // src/angular/voice-routing-status.service.ts
4676
+ var _dec = [
4677
+ Injectable25({ providedIn: "root" })
4678
+ ];
4679
+ var _init = __decoratorStart(undefined);
4680
+
4681
+ class VoiceRoutingStatusService {
4682
+ connect(path = "/api/routing/latest", options = {}) {
4683
+ const store = createVoiceRoutingStatusStore(path, options);
4684
+ const decisionSignal = signal25(null);
4685
+ const errorSignal = signal25(null);
4686
+ const isLoadingSignal = signal25(false);
4687
+ const updatedAtSignal = signal25(undefined);
4688
+ const sync = () => {
4689
+ const snapshot = store.getSnapshot();
4690
+ decisionSignal.set(snapshot.decision);
4691
+ errorSignal.set(snapshot.error);
4692
+ isLoadingSignal.set(snapshot.isLoading);
4693
+ updatedAtSignal.set(snapshot.updatedAt);
4694
+ };
4695
+ const unsubscribe = store.subscribe(sync);
4696
+ sync();
4697
+ store.refresh().catch(() => {});
4698
+ return {
4699
+ close: () => {
4700
+ unsubscribe();
4701
+ store.close();
4702
+ },
4703
+ decision: decisionSignal.asReadonly(),
4704
+ error: errorSignal.asReadonly(),
4705
+ isLoading: isLoadingSignal.asReadonly(),
4706
+ refresh: store.refresh,
4707
+ updatedAt: updatedAtSignal.asReadonly()
4708
+ };
4709
+ }
4710
+ }
4711
+ VoiceRoutingStatusService = __decorateElement(_init, 0, "VoiceRoutingStatusService", _dec, VoiceRoutingStatusService);
4712
+ __runInitializers(_init, 1, VoiceRoutingStatusService);
4713
+ __decoratorMetadata(_init, VoiceRoutingStatusService);
4714
+ let _VoiceRoutingStatusService = VoiceRoutingStatusService;
4715
+ // src/angular/voice-trace-timeline.service.ts
4716
+ import { computed as computed25, Injectable as Injectable26, signal as signal26 } from "@angular/core";
4717
+
4718
+ // src/client/traceTimeline.ts
4719
+ var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
4720
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4721
+ const response = await fetchImpl(path);
4722
+ if (!response.ok) {
4723
+ throw new Error(`Voice trace timeline failed: HTTP ${response.status}`);
4724
+ }
4725
+ return await response.json();
4726
+ };
4727
+ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) => {
4728
+ const listeners = new Set;
4729
+ let closed = false;
4730
+ let timer;
4731
+ let snapshot = {
4732
+ error: null,
4733
+ isLoading: false,
4734
+ report: null
4735
+ };
4736
+ const emit = () => {
4737
+ for (const listener of listeners) {
4738
+ listener();
4739
+ }
4740
+ };
4741
+ const refresh = async () => {
4742
+ if (closed) {
4743
+ return snapshot.report;
4744
+ }
4745
+ snapshot = {
4746
+ ...snapshot,
4747
+ error: null,
4748
+ isLoading: true
4749
+ };
4750
+ emit();
4751
+ try {
4752
+ const report = await fetchVoiceTraceTimeline(path, options);
4753
+ snapshot = {
4754
+ error: null,
4755
+ isLoading: false,
4756
+ report,
4757
+ updatedAt: Date.now()
4758
+ };
4759
+ emit();
4760
+ return report;
4761
+ } catch (error) {
4762
+ snapshot = {
4763
+ ...snapshot,
4764
+ error: error instanceof Error ? error.message : String(error),
4765
+ isLoading: false
4766
+ };
4767
+ emit();
4768
+ throw error;
4769
+ }
4770
+ };
4771
+ const close = () => {
4772
+ closed = true;
4773
+ if (timer) {
4774
+ clearInterval(timer);
4775
+ timer = undefined;
4776
+ }
4777
+ listeners.clear();
4778
+ };
4779
+ if (options.intervalMs && options.intervalMs > 0) {
4780
+ timer = setInterval(() => {
4781
+ refresh().catch(() => {});
4782
+ }, options.intervalMs);
4783
+ }
4784
+ return {
4785
+ close,
4786
+ getServerSnapshot: () => snapshot,
4787
+ getSnapshot: () => snapshot,
4788
+ refresh,
4789
+ subscribe: (listener) => {
4790
+ listeners.add(listener);
4791
+ return () => {
4792
+ listeners.delete(listener);
4793
+ };
4794
+ }
4795
+ };
4796
+ };
4797
+
4798
+ // src/angular/voice-trace-timeline.service.ts
4799
+ var _dec = [
4800
+ Injectable26({ providedIn: "root" })
4801
+ ];
4802
+ var _init = __decoratorStart(undefined);
4803
+
4804
+ class VoiceTraceTimelineService {
4805
+ connect(path = "/api/voice-traces", options = {}) {
4806
+ const store = createVoiceTraceTimelineStore(path, options);
4807
+ const errorSignal = signal26(null);
4808
+ const isLoadingSignal = signal26(false);
4809
+ const reportSignal = signal26(null);
4810
+ const updatedAtSignal = signal26(undefined);
4811
+ const sync = () => {
4812
+ const snapshot = store.getSnapshot();
4813
+ errorSignal.set(snapshot.error);
4814
+ isLoadingSignal.set(snapshot.isLoading);
4815
+ reportSignal.set(snapshot.report);
4816
+ updatedAtSignal.set(snapshot.updatedAt);
4817
+ };
4818
+ const unsubscribe = store.subscribe(sync);
4819
+ sync();
4820
+ store.refresh().catch(() => {});
4821
+ return {
4822
+ close: () => {
4823
+ unsubscribe();
4824
+ store.close();
4825
+ },
4826
+ error: computed25(() => errorSignal()),
4827
+ isLoading: computed25(() => isLoadingSignal()),
4828
+ refresh: store.refresh,
4829
+ report: computed25(() => reportSignal()),
4830
+ updatedAt: computed25(() => updatedAtSignal())
4831
+ };
4832
+ }
4833
+ }
4834
+ VoiceTraceTimelineService = __decorateElement(_init, 0, "VoiceTraceTimelineService", _dec, VoiceTraceTimelineService);
4835
+ __runInitializers(_init, 1, VoiceTraceTimelineService);
4836
+ __decoratorMetadata(_init, VoiceTraceTimelineService);
4837
+ let _VoiceTraceTimelineService = VoiceTraceTimelineService;
4838
+ // src/angular/voice-agent-squad-status.service.ts
4839
+ import { computed as computed26, Injectable as Injectable27, signal as signal27 } from "@angular/core";
4840
+
4841
+ // src/client/agentSquadStatus.ts
4842
+ var getString = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
4843
+ var getPayloadString = (event, key) => getString(event.payload?.[key]);
4844
+ var eventStatus = (event) => {
4845
+ const status = getPayloadString(event, "status");
4846
+ if (status === "blocked")
4847
+ return "blocked";
4848
+ if (status === "unknown-target")
4849
+ return "unknown-target";
4850
+ if (status === "allowed")
4851
+ return "handoff";
4852
+ return event.type === "agent.result" ? "active" : "handoff";
4853
+ };
4854
+ var deriveSessionSpecialist = (session) => {
4855
+ const events = [...session.events].sort((left, right) => left.at - right.at);
4856
+ const agentEvents = events.filter((event) => event.type === "agent.handoff" || event.type === "agent.context" || event.type === "agent.result" || event.type === "agent.model");
4857
+ const latest = agentEvents.at(-1);
4858
+ if (!latest) {
4859
+ return {
4860
+ lastEventAt: session.lastEventAt,
4861
+ sessionId: session.sessionId,
4862
+ status: "idle"
4863
+ };
4864
+ }
4865
+ const handoffEvents = events.filter((event) => event.type === "agent.handoff");
4866
+ const lastHandoff = handoffEvents.at(-1);
4867
+ const latestAgentId = getPayloadString(latest, "agentId");
4868
+ const handoffStatus = lastHandoff ? eventStatus(lastHandoff) : undefined;
4869
+ const currentTarget = handoffStatus === "blocked" || handoffStatus === "unknown-target" ? getPayloadString(lastHandoff, "fromAgentId") ?? latestAgentId : getPayloadString(lastHandoff ?? latest, "targetAgentId") ?? latestAgentId;
4870
+ return {
4871
+ fromAgentId: getPayloadString(lastHandoff ?? latest, "fromAgentId"),
4872
+ lastEventAt: latest.at,
4873
+ reason: getPayloadString(lastHandoff ?? latest, "reason") ?? getPayloadString(latest, "handoffTarget"),
4874
+ sessionId: session.sessionId,
4875
+ status: lastHandoff ? eventStatus(lastHandoff) : "active",
4876
+ summary: getPayloadString(lastHandoff ?? latest, "summary"),
4877
+ targetAgentId: currentTarget,
4878
+ turnId: latest.turnId
4879
+ };
4880
+ };
4881
+ var buildVoiceAgentSquadStatusReport = (timeline, options = {}) => {
4882
+ const sessions = (timeline?.sessions ?? []).filter((session) => !options.sessionId || session.sessionId === options.sessionId).map(deriveSessionSpecialist).sort((left, right) => (right.lastEventAt ?? 0) - (left.lastEventAt ?? 0));
4883
+ const active = sessions.filter((session) => session.status !== "idle");
4884
+ return {
4885
+ active,
4886
+ checkedAt: timeline?.checkedAt,
4887
+ current: active[0] ?? sessions[0],
4888
+ sessionCount: sessions.length,
4889
+ sessions
4890
+ };
4891
+ };
4892
+ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}) => {
4893
+ const timelineStore = createVoiceTraceTimelineStore(path, options);
4894
+ const getReport = () => buildVoiceAgentSquadStatusReport(timelineStore.getSnapshot().report, {
4895
+ sessionId: options.sessionId
4896
+ });
4897
+ const getSnapshot = () => {
4898
+ const snapshot = timelineStore.getSnapshot();
4899
+ return {
4900
+ error: snapshot.error,
4901
+ isLoading: snapshot.isLoading,
4902
+ report: getReport(),
4903
+ updatedAt: snapshot.updatedAt
4904
+ };
4905
+ };
4906
+ return {
4907
+ close: timelineStore.close,
4908
+ getServerSnapshot: getSnapshot,
4909
+ getSnapshot,
4910
+ refresh: timelineStore.refresh,
4911
+ subscribe: timelineStore.subscribe
4912
+ };
4913
+ };
4914
+
4915
+ // src/angular/voice-agent-squad-status.service.ts
4916
+ var _dec = [
4917
+ Injectable27({ providedIn: "root" })
4918
+ ];
4919
+ var _init = __decoratorStart(undefined);
4920
+
4921
+ class VoiceAgentSquadStatusService {
4922
+ connect(path = "/api/voice-traces", options = {}) {
4923
+ const store = createVoiceAgentSquadStatusStore(path, options);
4924
+ const errorSignal = signal27(null);
4925
+ const isLoadingSignal = signal27(false);
4926
+ const reportSignal = signal27(undefined);
4927
+ const updatedAtSignal = signal27(undefined);
4928
+ const sync = () => {
4929
+ const snapshot = store.getSnapshot();
4930
+ errorSignal.set(snapshot.error);
4931
+ isLoadingSignal.set(snapshot.isLoading);
4932
+ reportSignal.set(snapshot.report);
4933
+ updatedAtSignal.set(snapshot.updatedAt);
4934
+ };
4935
+ const unsubscribe = store.subscribe(sync);
4936
+ sync();
4937
+ store.refresh().catch(() => {});
4938
+ return {
4939
+ close: () => {
4940
+ unsubscribe();
4941
+ store.close();
4942
+ },
4943
+ current: computed26(() => reportSignal()?.current),
4944
+ error: computed26(() => errorSignal()),
4945
+ isLoading: computed26(() => isLoadingSignal()),
4946
+ refresh: store.refresh,
4947
+ report: computed26(() => reportSignal()),
4948
+ updatedAt: computed26(() => updatedAtSignal())
4949
+ };
4950
+ }
4951
+ }
4952
+ VoiceAgentSquadStatusService = __decorateElement(_init, 0, "VoiceAgentSquadStatusService", _dec, VoiceAgentSquadStatusService);
4953
+ __runInitializers(_init, 1, VoiceAgentSquadStatusService);
4954
+ __decoratorMetadata(_init, VoiceAgentSquadStatusService);
4955
+ let _VoiceAgentSquadStatusService = VoiceAgentSquadStatusService;
4956
+ // src/angular/voice-turn-latency.service.ts
4957
+ import { computed as computed27, Injectable as Injectable28, signal as signal28 } from "@angular/core";
4958
+
4959
+ // src/client/turnLatency.ts
4960
+ var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
4961
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4962
+ const response = await fetchImpl(path);
4963
+ if (!response.ok) {
4964
+ throw new Error(`Voice turn latency failed: HTTP ${response.status}`);
4965
+ }
4966
+ return await response.json();
4967
+ };
4968
+ var runVoiceTurnLatencyProof = async (path, options = {}) => {
4969
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4970
+ const response = await fetchImpl(path, { method: "POST" });
4971
+ if (!response.ok) {
4972
+ throw new Error(`Voice turn latency proof failed: HTTP ${response.status}`);
4973
+ }
4974
+ return response.json();
4975
+ };
4976
+ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) => {
4977
+ const listeners = new Set;
4978
+ let closed = false;
4979
+ let timer;
4980
+ let snapshot = {
4981
+ error: null,
4982
+ isLoading: false
4983
+ };
4984
+ const emit = () => {
4985
+ for (const listener of listeners) {
4986
+ listener();
4987
+ }
4988
+ };
4989
+ const refresh = async () => {
4990
+ if (closed) {
4991
+ return snapshot.report;
4992
+ }
4993
+ snapshot = { ...snapshot, error: null, isLoading: true };
4994
+ emit();
4995
+ try {
4996
+ const report = await fetchVoiceTurnLatency(path, options);
4997
+ snapshot = {
4998
+ error: null,
4999
+ isLoading: false,
5000
+ report,
5001
+ updatedAt: Date.now()
5002
+ };
5003
+ emit();
5004
+ return report;
5005
+ } catch (error) {
5006
+ snapshot = {
5007
+ ...snapshot,
5008
+ error: error instanceof Error ? error.message : String(error),
5009
+ isLoading: false
5010
+ };
5011
+ emit();
5012
+ throw error;
5013
+ }
5014
+ };
5015
+ const runProof = async () => {
5016
+ if (!options.proofPath) {
5017
+ throw new Error("Voice turn latency proof path is not configured.");
5018
+ }
5019
+ snapshot = { ...snapshot, error: null, isLoading: true };
5020
+ emit();
5021
+ try {
5022
+ await runVoiceTurnLatencyProof(options.proofPath, options);
5023
+ return await refresh();
5024
+ } catch (error) {
1508
5025
  snapshot = {
1509
5026
  ...snapshot,
1510
5027
  error: error instanceof Error ? error.message : String(error),
@@ -1532,6 +5049,7 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1532
5049
  getServerSnapshot: () => snapshot,
1533
5050
  getSnapshot: () => snapshot,
1534
5051
  refresh,
5052
+ runProof,
1535
5053
  subscribe: (listener) => {
1536
5054
  listeners.add(listener);
1537
5055
  return () => {
@@ -1541,24 +5059,24 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1541
5059
  };
1542
5060
  };
1543
5061
 
1544
- // src/angular/voice-provider-status.service.ts
5062
+ // src/angular/voice-turn-latency.service.ts
1545
5063
  var _dec = [
1546
- Injectable4({ providedIn: "root" })
5064
+ Injectable28({ providedIn: "root" })
1547
5065
  ];
1548
5066
  var _init = __decoratorStart(undefined);
1549
5067
 
1550
- class VoiceProviderStatusService {
1551
- connect(path = "/api/provider-status", options = {}) {
1552
- const store = createVoiceProviderStatusStore(path, options);
1553
- const errorSignal = signal4(null);
1554
- const isLoadingSignal = signal4(false);
1555
- const providersSignal = signal4([]);
1556
- const updatedAtSignal = signal4(undefined);
5068
+ class VoiceTurnLatencyService {
5069
+ connect(path = "/api/turn-latency", options = {}) {
5070
+ const store = createVoiceTurnLatencyStore(path, options);
5071
+ const errorSignal = signal28(null);
5072
+ const isLoadingSignal = signal28(false);
5073
+ const reportSignal = signal28(undefined);
5074
+ const updatedAtSignal = signal28(undefined);
1557
5075
  const sync = () => {
1558
5076
  const snapshot = store.getSnapshot();
1559
5077
  errorSignal.set(snapshot.error);
1560
5078
  isLoadingSignal.set(snapshot.isLoading);
1561
- providersSignal.set([...snapshot.providers]);
5079
+ reportSignal.set(snapshot.report);
1562
5080
  updatedAtSignal.set(snapshot.updatedAt);
1563
5081
  };
1564
5082
  const unsubscribe = store.subscribe(sync);
@@ -1569,20 +5087,143 @@ class VoiceProviderStatusService {
1569
5087
  unsubscribe();
1570
5088
  store.close();
1571
5089
  },
1572
- error: computed4(() => errorSignal()),
1573
- isLoading: computed4(() => isLoadingSignal()),
1574
- providers: computed4(() => providersSignal()),
5090
+ error: computed27(() => errorSignal()),
5091
+ isLoading: computed27(() => isLoadingSignal()),
1575
5092
  refresh: store.refresh,
1576
- updatedAt: computed4(() => updatedAtSignal())
5093
+ report: computed27(() => reportSignal()),
5094
+ runProof: store.runProof,
5095
+ updatedAt: computed27(() => updatedAtSignal())
1577
5096
  };
1578
5097
  }
1579
5098
  }
1580
- VoiceProviderStatusService = __decorateElement(_init, 0, "VoiceProviderStatusService", _dec, VoiceProviderStatusService);
1581
- __runInitializers(_init, 1, VoiceProviderStatusService);
1582
- __decoratorMetadata(_init, VoiceProviderStatusService);
1583
- let _VoiceProviderStatusService = VoiceProviderStatusService;
5099
+ VoiceTurnLatencyService = __decorateElement(_init, 0, "VoiceTurnLatencyService", _dec, VoiceTurnLatencyService);
5100
+ __runInitializers(_init, 1, VoiceTurnLatencyService);
5101
+ __decoratorMetadata(_init, VoiceTurnLatencyService);
5102
+ let _VoiceTurnLatencyService = VoiceTurnLatencyService;
5103
+ // src/angular/voice-turn-quality.service.ts
5104
+ import { computed as computed28, Injectable as Injectable29, signal as signal29 } from "@angular/core";
5105
+
5106
+ // src/client/turnQuality.ts
5107
+ var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
5108
+ const fetchImpl = options.fetch ?? globalThis.fetch;
5109
+ const response = await fetchImpl(path);
5110
+ if (!response.ok) {
5111
+ throw new Error(`Voice turn quality failed: HTTP ${response.status}`);
5112
+ }
5113
+ return await response.json();
5114
+ };
5115
+ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) => {
5116
+ const listeners = new Set;
5117
+ let closed = false;
5118
+ let timer;
5119
+ let snapshot = {
5120
+ error: null,
5121
+ isLoading: false
5122
+ };
5123
+ const emit = () => {
5124
+ for (const listener of listeners) {
5125
+ listener();
5126
+ }
5127
+ };
5128
+ const refresh = async () => {
5129
+ if (closed) {
5130
+ return snapshot.report;
5131
+ }
5132
+ snapshot = {
5133
+ ...snapshot,
5134
+ error: null,
5135
+ isLoading: true
5136
+ };
5137
+ emit();
5138
+ try {
5139
+ const report = await fetchVoiceTurnQuality(path, options);
5140
+ snapshot = {
5141
+ error: null,
5142
+ isLoading: false,
5143
+ report,
5144
+ updatedAt: Date.now()
5145
+ };
5146
+ emit();
5147
+ return report;
5148
+ } catch (error) {
5149
+ snapshot = {
5150
+ ...snapshot,
5151
+ error: error instanceof Error ? error.message : String(error),
5152
+ isLoading: false
5153
+ };
5154
+ emit();
5155
+ throw error;
5156
+ }
5157
+ };
5158
+ const close = () => {
5159
+ closed = true;
5160
+ if (timer) {
5161
+ clearInterval(timer);
5162
+ timer = undefined;
5163
+ }
5164
+ listeners.clear();
5165
+ };
5166
+ if (options.intervalMs && options.intervalMs > 0) {
5167
+ timer = setInterval(() => {
5168
+ refresh().catch(() => {});
5169
+ }, options.intervalMs);
5170
+ }
5171
+ return {
5172
+ close,
5173
+ getServerSnapshot: () => snapshot,
5174
+ getSnapshot: () => snapshot,
5175
+ refresh,
5176
+ subscribe: (listener) => {
5177
+ listeners.add(listener);
5178
+ return () => {
5179
+ listeners.delete(listener);
5180
+ };
5181
+ }
5182
+ };
5183
+ };
5184
+
5185
+ // src/angular/voice-turn-quality.service.ts
5186
+ var _dec = [
5187
+ Injectable29({ providedIn: "root" })
5188
+ ];
5189
+ var _init = __decoratorStart(undefined);
5190
+
5191
+ class VoiceTurnQualityService {
5192
+ connect(path = "/api/turn-quality", options = {}) {
5193
+ const store = createVoiceTurnQualityStore(path, options);
5194
+ const errorSignal = signal29(null);
5195
+ const isLoadingSignal = signal29(false);
5196
+ const reportSignal = signal29(undefined);
5197
+ const updatedAtSignal = signal29(undefined);
5198
+ const sync = () => {
5199
+ const snapshot = store.getSnapshot();
5200
+ errorSignal.set(snapshot.error);
5201
+ isLoadingSignal.set(snapshot.isLoading);
5202
+ reportSignal.set(snapshot.report);
5203
+ updatedAtSignal.set(snapshot.updatedAt);
5204
+ };
5205
+ const unsubscribe = store.subscribe(sync);
5206
+ sync();
5207
+ store.refresh().catch(() => {});
5208
+ return {
5209
+ close: () => {
5210
+ unsubscribe();
5211
+ store.close();
5212
+ },
5213
+ error: computed28(() => errorSignal()),
5214
+ isLoading: computed28(() => isLoadingSignal()),
5215
+ refresh: store.refresh,
5216
+ report: computed28(() => reportSignal()),
5217
+ updatedAt: computed28(() => updatedAtSignal())
5218
+ };
5219
+ }
5220
+ }
5221
+ VoiceTurnQualityService = __decorateElement(_init, 0, "VoiceTurnQualityService", _dec, VoiceTurnQualityService);
5222
+ __runInitializers(_init, 1, VoiceTurnQualityService);
5223
+ __decoratorMetadata(_init, VoiceTurnQualityService);
5224
+ let _VoiceTurnQualityService = VoiceTurnQualityService;
1584
5225
  // src/angular/voice-workflow-status.service.ts
1585
- import { computed as computed5, Injectable as Injectable5, signal as signal5 } from "@angular/core";
5226
+ import { computed as computed29, Injectable as Injectable30, signal as signal30 } from "@angular/core";
1586
5227
 
1587
5228
  // src/client/workflowStatus.ts
1588
5229
  var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
@@ -1665,17 +5306,17 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
1665
5306
 
1666
5307
  // src/angular/voice-workflow-status.service.ts
1667
5308
  var _dec = [
1668
- Injectable5({ providedIn: "root" })
5309
+ Injectable30({ providedIn: "root" })
1669
5310
  ];
1670
5311
  var _init = __decoratorStart(undefined);
1671
5312
 
1672
5313
  class VoiceWorkflowStatusService {
1673
5314
  connect(path = "/evals/scenarios/json", options = {}) {
1674
5315
  const store = createVoiceWorkflowStatusStore(path, options);
1675
- const errorSignal = signal5(null);
1676
- const isLoadingSignal = signal5(false);
1677
- const reportSignal = signal5(undefined);
1678
- const updatedAtSignal = signal5(undefined);
5316
+ const errorSignal = signal30(null);
5317
+ const isLoadingSignal = signal30(false);
5318
+ const reportSignal = signal30(undefined);
5319
+ const updatedAtSignal = signal30(undefined);
1679
5320
  const sync = () => {
1680
5321
  const snapshot = store.getSnapshot();
1681
5322
  errorSignal.set(snapshot.error);
@@ -1693,11 +5334,11 @@ class VoiceWorkflowStatusService {
1693
5334
  unsubscribe();
1694
5335
  store.close();
1695
5336
  },
1696
- error: computed5(() => errorSignal()),
1697
- isLoading: computed5(() => isLoadingSignal()),
5337
+ error: computed29(() => errorSignal()),
5338
+ isLoading: computed29(() => isLoadingSignal()),
1698
5339
  refresh: store.refresh,
1699
- report: computed5(() => reportSignal()),
1700
- updatedAt: computed5(() => updatedAtSignal())
5340
+ report: computed29(() => reportSignal()),
5341
+ updatedAt: computed29(() => updatedAtSignal())
1701
5342
  };
1702
5343
  }
1703
5344
  }
@@ -1707,8 +5348,33 @@ __decoratorMetadata(_init, VoiceWorkflowStatusService);
1707
5348
  let _VoiceWorkflowStatusService = VoiceWorkflowStatusService;
1708
5349
  export {
1709
5350
  VoiceWorkflowStatusService,
5351
+ VoiceWidgetService,
5352
+ VoiceTurnQualityService,
5353
+ VoiceTurnLatencyService,
5354
+ VoiceTraceTimelineService,
1710
5355
  VoiceStreamService,
5356
+ VoiceSessionSnapshotService,
5357
+ VoiceSessionObservabilityService,
5358
+ VoiceRoutingStatusService,
5359
+ VoiceReplayTimelineService,
5360
+ VoiceReconnectProfileEvidenceService,
5361
+ VoiceReadinessFailuresService,
1711
5362
  VoiceProviderStatusService,
5363
+ VoiceProviderContractsService,
5364
+ VoiceProviderCapabilitiesService,
5365
+ VoiceProofTrendsService,
5366
+ VoiceProfileComparisonService,
5367
+ VoicePlatformCoverageService,
5368
+ VoiceOpsStatusService,
5369
+ VoiceOpsActionCenterService,
5370
+ VoiceLiveOpsService,
5371
+ VoiceLiveCallViewerService,
5372
+ VoiceLiveAgentConsoleService,
5373
+ VoiceDeliveryRuntimeService,
5374
+ VoiceCostDashboardService,
1712
5375
  VoiceControllerService,
1713
- VoiceAppKitStatusService
5376
+ VoiceCampaignDialerProofService,
5377
+ VoiceCallPlayerService,
5378
+ VoiceCallDebuggerService,
5379
+ VoiceAgentSquadStatusService
1714
5380
  };