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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/README.md +4556 -603
  2. package/dist/agent.d.ts +79 -5
  3. package/dist/agentSquadContract.d.ts +98 -0
  4. package/dist/agentState.d.ts +12 -0
  5. package/dist/agentTools.d.ts +133 -0
  6. package/dist/aiVoiceModel.d.ts +15 -0
  7. package/dist/amdDetector.d.ts +25 -0
  8. package/dist/angular/index.d.ts +26 -5
  9. package/dist/angular/index.js +3350 -313
  10. package/dist/angular/voice-agent-squad-status.service.d.ts +12 -0
  11. package/dist/angular/voice-call-debugger.service.d.ts +12 -0
  12. package/dist/angular/voice-campaign-dialer-proof.service.d.ts +14 -0
  13. package/dist/angular/voice-controller.service.d.ts +3 -1
  14. package/dist/angular/voice-delivery-runtime.component.d.ts +17 -0
  15. package/dist/angular/voice-delivery-runtime.service.d.ts +16 -0
  16. package/dist/angular/voice-live-ops.service.d.ts +11 -0
  17. package/dist/angular/voice-ops-action-center.service.d.ts +13 -0
  18. package/dist/angular/voice-ops-status.component.d.ts +15 -0
  19. package/dist/angular/voice-ops-status.service.d.ts +12 -0
  20. package/dist/angular/voice-platform-coverage.service.d.ts +12 -0
  21. package/dist/angular/voice-profile-comparison.service.d.ts +12 -0
  22. package/dist/angular/voice-proof-trends.service.d.ts +12 -0
  23. package/dist/angular/voice-provider-capabilities.service.d.ts +12 -0
  24. package/dist/angular/voice-provider-contracts.service.d.ts +12 -0
  25. package/dist/angular/voice-provider-status.service.d.ts +2 -2
  26. package/dist/angular/voice-readiness-failures.service.d.ts +13 -0
  27. package/dist/angular/voice-reconnect-profile-evidence.service.d.ts +12 -0
  28. package/dist/angular/voice-routing-status.service.d.ts +11 -0
  29. package/dist/angular/voice-session-observability.service.d.ts +12 -0
  30. package/dist/angular/voice-session-snapshot.service.d.ts +13 -0
  31. package/dist/angular/voice-stream.service.d.ts +4 -1
  32. package/dist/angular/voice-trace-timeline.service.d.ts +12 -0
  33. package/dist/angular/voice-turn-latency.service.d.ts +13 -0
  34. package/dist/angular/voice-turn-quality.service.d.ts +12 -0
  35. package/dist/angular/voice-widget.service.d.ts +18 -0
  36. package/dist/angular/voice-workflow-status.service.d.ts +2 -2
  37. package/dist/assistant.d.ts +12 -13
  38. package/dist/assistantHealth.d.ts +6 -6
  39. package/dist/assistantMemory.d.ts +3 -3
  40. package/dist/assistantMode.d.ts +22 -0
  41. package/dist/audioConditioning.d.ts +1 -1
  42. package/dist/audit.d.ts +131 -0
  43. package/dist/auditDeliveryRoutes.d.ts +85 -0
  44. package/dist/auditExport.d.ts +34 -0
  45. package/dist/auditRoutes.d.ts +66 -0
  46. package/dist/auditSinks.d.ts +151 -0
  47. package/dist/backchannel.d.ts +18 -0
  48. package/dist/bargeInRoutes.d.ts +56 -0
  49. package/dist/browserCallProfiles.d.ts +120 -0
  50. package/dist/browserMediaRoutes.d.ts +62 -0
  51. package/dist/callDebugger.d.ts +66 -0
  52. package/dist/callQuota.d.ts +54 -0
  53. package/dist/callerMemory.d.ts +37 -0
  54. package/dist/campaign.d.ts +794 -0
  55. package/dist/campaignControls.d.ts +37 -0
  56. package/dist/campaignDialers.d.ts +111 -0
  57. package/dist/client/actions.d.ts +95 -1
  58. package/dist/client/agentSquadStatus.d.ts +37 -0
  59. package/dist/client/agentSquadStatusWidget.d.ts +24 -0
  60. package/dist/client/audioPlayer.d.ts +2 -2
  61. package/dist/client/bargeInMonitor.d.ts +7 -0
  62. package/dist/client/browserMedia.d.ts +8 -0
  63. package/dist/client/callDebugger.d.ts +19 -0
  64. package/dist/client/callDebuggerWidget.d.ts +30 -0
  65. package/dist/client/campaignDialerProof.d.ts +23 -0
  66. package/dist/client/connection.d.ts +4 -3
  67. package/dist/client/controller.d.ts +1 -1
  68. package/dist/client/costDashboard.d.ts +27 -0
  69. package/dist/client/createVoiceStream.d.ts +1 -1
  70. package/dist/client/deliveryRuntime.d.ts +34 -0
  71. package/dist/client/deliveryRuntimeWidget.d.ts +37 -0
  72. package/dist/client/duplex.d.ts +2 -2
  73. package/dist/client/htmx.d.ts +1 -1
  74. package/dist/client/htmxBootstrap.js +967 -14
  75. package/dist/client/index.d.ts +104 -13
  76. package/dist/client/index.js +10142 -26
  77. package/dist/client/liveCallViewer.d.ts +42 -0
  78. package/dist/client/liveOps.d.ts +22 -0
  79. package/dist/client/liveOpsWidget.d.ts +23 -0
  80. package/dist/client/liveTurnLatency.d.ts +41 -0
  81. package/dist/client/microphone.d.ts +4 -4
  82. package/dist/client/opsActionCenter.d.ts +54 -0
  83. package/dist/client/opsActionCenterWidget.d.ts +29 -0
  84. package/dist/client/opsActionHistory.d.ts +19 -0
  85. package/dist/client/opsActionHistoryWidget.d.ts +11 -0
  86. package/dist/client/opsStatus.d.ts +19 -0
  87. package/dist/client/opsStatusWidget.d.ts +40 -0
  88. package/dist/client/platformCoverage.d.ts +19 -0
  89. package/dist/client/platformCoverageWidget.d.ts +37 -0
  90. package/dist/client/profileComparison.d.ts +19 -0
  91. package/dist/client/profileComparisonWidget.d.ts +41 -0
  92. package/dist/client/profileSwitchRecommendation.d.ts +19 -0
  93. package/dist/client/profileSwitchRecommendationWidget.d.ts +12 -0
  94. package/dist/client/proofTrends.d.ts +19 -0
  95. package/dist/client/proofTrendsWidget.d.ts +37 -0
  96. package/dist/client/providerCapabilities.d.ts +19 -0
  97. package/dist/client/providerCapabilitiesWidget.d.ts +32 -0
  98. package/dist/client/providerContracts.d.ts +19 -0
  99. package/dist/client/providerContractsWidget.d.ts +37 -0
  100. package/dist/client/providerSimulationControls.d.ts +33 -0
  101. package/dist/client/providerSimulationControlsWidget.d.ts +20 -0
  102. package/dist/client/providerStatus.d.ts +1 -1
  103. package/dist/client/providerStatusWidget.d.ts +32 -0
  104. package/dist/client/readinessFailures.d.ts +19 -0
  105. package/dist/client/readinessFailuresWidget.d.ts +42 -0
  106. package/dist/client/reconnectProfileEvidence.d.ts +19 -0
  107. package/dist/client/reconnectProfileEvidenceWidget.d.ts +39 -0
  108. package/dist/client/replayTimeline.d.ts +26 -0
  109. package/dist/client/routingStatus.d.ts +19 -0
  110. package/dist/client/routingStatusWidget.d.ts +32 -0
  111. package/dist/client/sessionObservability.d.ts +19 -0
  112. package/dist/client/sessionObservabilityWidget.d.ts +31 -0
  113. package/dist/client/sessionSnapshot.d.ts +21 -0
  114. package/dist/client/sessionSnapshotWidget.d.ts +33 -0
  115. package/dist/client/store.d.ts +1 -1
  116. package/dist/client/traceTimeline.d.ts +19 -0
  117. package/dist/client/traceTimelineWidget.d.ts +36 -0
  118. package/dist/client/turnLatency.d.ts +22 -0
  119. package/dist/client/turnLatencyWidget.d.ts +33 -0
  120. package/dist/client/turnQuality.d.ts +19 -0
  121. package/dist/client/turnQualityWidget.d.ts +32 -0
  122. package/dist/client/voiceWidgetView.d.ts +50 -0
  123. package/dist/client/workflowStatus.d.ts +1 -1
  124. package/dist/competitiveCoverage.d.ts +141 -0
  125. package/dist/correction.d.ts +2 -2
  126. package/dist/costAccounting.d.ts +76 -0
  127. package/dist/dataControl.d.ts +180 -0
  128. package/dist/defineVoiceAssistant.d.ts +68 -0
  129. package/dist/deliveryRuntime.d.ts +158 -0
  130. package/dist/deliverySinkRoutes.d.ts +117 -0
  131. package/dist/demoReadyRoutes.d.ts +98 -0
  132. package/dist/diagnosticsRoutes.d.ts +2 -2
  133. package/dist/evalRoutes.d.ts +10 -4
  134. package/dist/fileStore.d.ts +21 -7
  135. package/dist/generated/htmxBootstrapBundle.d.ts +1 -0
  136. package/dist/guardrails.d.ts +128 -0
  137. package/dist/handoff.d.ts +6 -6
  138. package/dist/handoffHealth.d.ts +5 -5
  139. package/dist/htmx.d.ts +1 -1
  140. package/dist/incidentBundle.d.ts +119 -0
  141. package/dist/incidentTimeline.d.ts +260 -0
  142. package/dist/index.d.ts +278 -74
  143. package/dist/index.js +40611 -6669
  144. package/dist/ivrPlan.d.ts +40 -0
  145. package/dist/latencySlo.d.ts +56 -0
  146. package/dist/liveLatency.d.ts +78 -0
  147. package/dist/liveOps.d.ts +190 -0
  148. package/dist/llmJudge.d.ts +45 -0
  149. package/dist/logger.d.ts +1 -1
  150. package/dist/mediaPipelineRoutes.d.ts +171 -0
  151. package/dist/mediaPipelineSurfaces.d.ts +48 -0
  152. package/dist/memoryStore.d.ts +1 -1
  153. package/dist/midCallSummary.d.ts +27 -0
  154. package/dist/modelAdapters.d.ts +59 -7
  155. package/dist/monitor.d.ts +148 -0
  156. package/dist/multilingualProof.d.ts +77 -0
  157. package/dist/oauth2TokenSource.d.ts +21 -0
  158. package/dist/observabilityExport.d.ts +501 -0
  159. package/dist/openaiTTS.d.ts +18 -0
  160. package/dist/operationalStatus.d.ts +87 -0
  161. package/dist/operationsRecord.d.ts +370 -0
  162. package/dist/ops.d.ts +12 -12
  163. package/dist/opsActionAuditRoutes.d.ts +99 -0
  164. package/dist/opsConsoleRoutes.d.ts +8 -5
  165. package/dist/opsPresets.d.ts +2 -2
  166. package/dist/opsRecovery.d.ts +137 -0
  167. package/dist/opsRuntime.d.ts +6 -6
  168. package/dist/opsSinks.d.ts +13 -13
  169. package/dist/opsStatus.d.ts +76 -0
  170. package/dist/opsStatusRoutes.d.ts +33 -0
  171. package/dist/opsWebhook.d.ts +6 -6
  172. package/dist/otelExporter.d.ts +83 -0
  173. package/dist/outcomeContract.d.ts +146 -0
  174. package/dist/outcomeRecipes.d.ts +4 -4
  175. package/dist/phoneAgent.d.ts +139 -0
  176. package/dist/phoneAgentProductionSmoke.d.ts +115 -0
  177. package/dist/platformCoverage.d.ts +91 -0
  178. package/dist/plugin.d.ts +2 -2
  179. package/dist/postCallAnalysis.d.ts +98 -0
  180. package/dist/postgresStore.d.ts +17 -6
  181. package/dist/presets.d.ts +3 -3
  182. package/dist/productionReadiness.d.ts +756 -0
  183. package/dist/profileSwitchRecommendation.d.ts +350 -0
  184. package/dist/proofAssertions.d.ts +32 -0
  185. package/dist/proofPack.d.ts +211 -0
  186. package/dist/proofRunner.d.ts +79 -0
  187. package/dist/proofTrends.d.ts +966 -0
  188. package/dist/providerAdapters.d.ts +16 -5
  189. package/dist/providerCapabilities.d.ts +92 -0
  190. package/dist/providerDecisionTraces.d.ts +130 -0
  191. package/dist/providerHealth.d.ts +3 -3
  192. package/dist/providerOrchestration.d.ts +109 -0
  193. package/dist/providerRouterTraces.d.ts +35 -0
  194. package/dist/providerRoutingContract.d.ts +71 -0
  195. package/dist/providerSlo.d.ts +142 -0
  196. package/dist/providerStackRecommendations.d.ts +187 -0
  197. package/dist/qualityRoutes.d.ts +4 -4
  198. package/dist/queue.d.ts +23 -14
  199. package/dist/ragTool.d.ts +57 -0
  200. package/dist/react/VoiceAgentSquadStatus.d.ts +5 -0
  201. package/dist/react/VoiceCallDebuggerLaunch.d.ts +6 -0
  202. package/dist/react/VoiceCostDashboard.d.ts +10 -0
  203. package/dist/react/VoiceDeliveryRuntime.d.ts +7 -0
  204. package/dist/react/VoiceLiveCallViewer.d.ts +9 -0
  205. package/dist/react/VoiceOpsActionCenter.d.ts +5 -0
  206. package/dist/react/VoiceOpsStatus.d.ts +6 -0
  207. package/dist/react/VoicePlatformCoverage.d.ts +6 -0
  208. package/dist/react/VoiceProfileComparison.d.ts +6 -0
  209. package/dist/react/VoiceProfileSwitchRecommendation.d.ts +6 -0
  210. package/dist/react/VoiceProofTrends.d.ts +6 -0
  211. package/dist/react/VoiceProviderCapabilities.d.ts +6 -0
  212. package/dist/react/VoiceProviderContracts.d.ts +6 -0
  213. package/dist/react/VoiceProviderSimulationControls.d.ts +5 -0
  214. package/dist/react/VoiceProviderStatus.d.ts +6 -0
  215. package/dist/react/VoiceReadinessFailures.d.ts +6 -0
  216. package/dist/react/VoiceReconnectProfileEvidence.d.ts +6 -0
  217. package/dist/react/VoiceReplayTimeline.d.ts +6 -0
  218. package/dist/react/VoiceRoutingStatus.d.ts +6 -0
  219. package/dist/react/VoiceSessionObservability.d.ts +6 -0
  220. package/dist/react/VoiceSessionSnapshot.d.ts +6 -0
  221. package/dist/react/VoiceTraceTimeline.d.ts +6 -0
  222. package/dist/react/VoiceTurnLatency.d.ts +6 -0
  223. package/dist/react/VoiceTurnQuality.d.ts +6 -0
  224. package/dist/react/VoiceWidget.d.ts +13 -0
  225. package/dist/react/index.d.ts +55 -5
  226. package/dist/react/index.js +12037 -106
  227. package/dist/react/useVoiceAgentSquadStatus.d.ts +8 -0
  228. package/dist/react/useVoiceCallDebugger.d.ts +8 -0
  229. package/dist/react/useVoiceCampaignDialerProof.d.ts +10 -0
  230. package/dist/react/useVoiceController.d.ts +4 -1
  231. package/dist/react/useVoiceDeliveryRuntime.d.ts +13 -0
  232. package/dist/react/useVoiceLiveOps.d.ts +9 -0
  233. package/dist/react/useVoiceOpsActionCenter.d.ts +11 -0
  234. package/dist/react/useVoiceOpsStatus.d.ts +8 -0
  235. package/dist/react/useVoicePlatformCoverage.d.ts +8 -0
  236. package/dist/react/useVoiceProfileComparison.d.ts +8 -0
  237. package/dist/react/useVoiceProfileSwitchRecommendation.d.ts +8 -0
  238. package/dist/react/useVoiceProofTrends.d.ts +8 -0
  239. package/dist/react/useVoiceProviderCapabilities.d.ts +8 -0
  240. package/dist/react/useVoiceProviderContracts.d.ts +8 -0
  241. package/dist/react/useVoiceProviderSimulationControls.d.ts +10 -0
  242. package/dist/react/useVoiceProviderStatus.d.ts +1 -1
  243. package/dist/react/useVoiceReadinessFailures.d.ts +8 -0
  244. package/dist/react/useVoiceReconnectProfileEvidence.d.ts +8 -0
  245. package/dist/react/useVoiceRoutingStatus.d.ts +8 -0
  246. package/dist/react/useVoiceSessionObservability.d.ts +8 -0
  247. package/dist/react/useVoiceSessionSnapshot.d.ts +9 -0
  248. package/dist/react/useVoiceStream.d.ts +4 -1
  249. package/dist/react/useVoiceTraceTimeline.d.ts +8 -0
  250. package/dist/react/useVoiceTurnLatency.d.ts +9 -0
  251. package/dist/react/useVoiceTurnQuality.d.ts +8 -0
  252. package/dist/react/useVoiceWorkflowStatus.d.ts +1 -1
  253. package/dist/readinessProfiles.d.ts +45 -0
  254. package/dist/realtimeChannel.d.ts +136 -0
  255. package/dist/realtimeProviderContracts.d.ts +133 -0
  256. package/dist/reconnectContract.d.ts +176 -0
  257. package/dist/recordingRedaction.d.ts +18 -0
  258. package/dist/recordingStore.d.ts +60 -0
  259. package/dist/redaction.d.ts +13 -0
  260. package/dist/resilienceRoutes.d.ts +45 -5
  261. package/dist/retention.d.ts +37 -0
  262. package/dist/routeAuth.d.ts +58 -0
  263. package/dist/routing.d.ts +1 -1
  264. package/dist/runtimeOps.d.ts +3 -3
  265. package/dist/s3Store.d.ts +18 -3
  266. package/dist/semanticTurn.d.ts +27 -0
  267. package/dist/session.d.ts +1 -1
  268. package/dist/sessionObservability.d.ts +145 -0
  269. package/dist/sessionReplay.d.ts +19 -7
  270. package/dist/sessionSnapshot.d.ts +109 -0
  271. package/dist/simulationSuite.d.ts +143 -0
  272. package/dist/sloCalibration.d.ts +185 -0
  273. package/dist/sqliteStore.d.ts +17 -6
  274. package/dist/store.d.ts +1 -1
  275. package/dist/svelte/createVoiceAgentSquadStatus.d.ts +9 -0
  276. package/dist/svelte/createVoiceCallDebugger.d.ts +12 -0
  277. package/dist/svelte/createVoiceCampaignDialerProof.d.ts +9 -0
  278. package/dist/svelte/createVoiceDeliveryRuntime.d.ts +11 -0
  279. package/dist/svelte/createVoiceLiveOps.d.ts +13 -0
  280. package/dist/svelte/createVoiceOpsActionCenter.d.ts +10 -0
  281. package/dist/svelte/createVoiceOpsStatus.d.ts +9 -0
  282. package/dist/svelte/createVoicePlatformCoverage.d.ts +7 -0
  283. package/dist/svelte/createVoiceProfileComparison.d.ts +7 -0
  284. package/dist/svelte/createVoiceProofTrends.d.ts +7 -0
  285. package/dist/svelte/createVoiceProviderCapabilities.d.ts +10 -0
  286. package/dist/svelte/createVoiceProviderContracts.d.ts +10 -0
  287. package/dist/svelte/createVoiceProviderSimulationControls.d.ts +11 -0
  288. package/dist/svelte/createVoiceProviderStatus.d.ts +4 -2
  289. package/dist/svelte/createVoiceReadinessFailures.d.ts +7 -0
  290. package/dist/svelte/createVoiceReconnectProfileEvidence.d.ts +7 -0
  291. package/dist/svelte/createVoiceRoutingStatus.d.ts +10 -0
  292. package/dist/svelte/createVoiceSessionObservability.d.ts +10 -0
  293. package/dist/svelte/createVoiceSessionSnapshot.d.ts +13 -0
  294. package/dist/svelte/createVoiceStream.d.ts +1 -1
  295. package/dist/svelte/createVoiceTraceTimeline.d.ts +10 -0
  296. package/dist/svelte/createVoiceTurnLatency.d.ts +11 -0
  297. package/dist/svelte/createVoiceTurnQuality.d.ts +10 -0
  298. package/dist/svelte/createVoiceWidget.d.ts +19 -0
  299. package/dist/svelte/createVoiceWorkflowStatus.d.ts +1 -1
  300. package/dist/svelte/index.d.ts +27 -5
  301. package/dist/svelte/index.js +6117 -546
  302. package/dist/telephony/contract.d.ts +61 -0
  303. package/dist/telephony/matrix.d.ts +97 -0
  304. package/dist/telephony/plivo.d.ts +303 -0
  305. package/dist/telephony/response.d.ts +1 -1
  306. package/dist/telephony/security.d.ts +182 -0
  307. package/dist/telephony/telnyx.d.ts +291 -0
  308. package/dist/telephony/twilio.d.ts +147 -13
  309. package/dist/telephonyMediaRoutes.d.ts +72 -0
  310. package/dist/telephonyOutcome.d.ts +273 -0
  311. package/dist/testing/accuracy.d.ts +1 -1
  312. package/dist/testing/benchmark.d.ts +9 -9
  313. package/dist/testing/corrected.d.ts +5 -5
  314. package/dist/testing/duplex.d.ts +3 -3
  315. package/dist/testing/fixtures.d.ts +3 -3
  316. package/dist/testing/index.d.ts +13 -13
  317. package/dist/testing/index.js +5223 -159
  318. package/dist/testing/ioProviderSimulator.d.ts +5 -5
  319. package/dist/testing/providerSimulator.d.ts +5 -5
  320. package/dist/testing/review.d.ts +4 -4
  321. package/dist/testing/sessionBenchmark.d.ts +3 -3
  322. package/dist/testing/stt.d.ts +3 -3
  323. package/dist/testing/telephony.d.ts +25 -0
  324. package/dist/testing/tts.d.ts +1 -1
  325. package/dist/toolContract.d.ts +161 -0
  326. package/dist/toolRuntime.d.ts +50 -0
  327. package/dist/trace.d.ts +46 -7
  328. package/dist/traceDeliveryRoutes.d.ts +86 -0
  329. package/dist/traceTimeline.d.ts +97 -0
  330. package/dist/turnDetection.d.ts +1 -1
  331. package/dist/turnLatency.d.ts +95 -0
  332. package/dist/turnProfiles.d.ts +2 -2
  333. package/dist/turnQuality.d.ts +94 -0
  334. package/dist/types.d.ts +293 -80
  335. package/dist/vapiAdapter.d.ts +160 -0
  336. package/dist/voiceMonitoring.d.ts +444 -0
  337. package/dist/vue/VoiceCallDebuggerLaunch.d.ts +68 -0
  338. package/dist/vue/VoiceDeliveryRuntime.d.ts +30 -0
  339. package/dist/vue/VoiceOpsActionCenter.d.ts +13 -0
  340. package/dist/vue/VoiceOpsStatus.d.ts +30 -0
  341. package/dist/vue/VoicePlatformCoverage.d.ts +23 -0
  342. package/dist/vue/VoiceProofTrends.d.ts +21 -0
  343. package/dist/vue/VoiceProviderCapabilities.d.ts +51 -0
  344. package/dist/vue/VoiceProviderContracts.d.ts +21 -0
  345. package/dist/vue/VoiceProviderSimulationControls.d.ts +88 -0
  346. package/dist/vue/VoiceProviderStatus.d.ts +51 -0
  347. package/dist/vue/VoiceReadinessFailures.d.ts +21 -0
  348. package/dist/vue/VoiceReconnectProfileEvidence.d.ts +21 -0
  349. package/dist/vue/VoiceRoutingStatus.d.ts +51 -0
  350. package/dist/vue/VoiceSessionObservability.d.ts +23 -0
  351. package/dist/vue/VoiceSessionSnapshot.d.ts +68 -0
  352. package/dist/vue/VoiceTurnLatency.d.ts +69 -0
  353. package/dist/vue/VoiceTurnQuality.d.ts +51 -0
  354. package/dist/vue/VoiceWidget.d.ts +77 -0
  355. package/dist/vue/index.d.ts +44 -5
  356. package/dist/vue/index.js +10752 -143
  357. package/dist/vue/useVoiceAgentSquadStatus.d.ts +9 -0
  358. package/dist/vue/useVoiceCallDebugger.d.ts +10 -0
  359. package/dist/vue/useVoiceCampaignDialerProof.d.ts +11 -0
  360. package/dist/vue/useVoiceController.d.ts +4 -2
  361. package/dist/vue/useVoiceDeliveryRuntime.d.ts +13 -0
  362. package/dist/vue/useVoiceLiveOps.d.ts +9 -0
  363. package/dist/vue/useVoiceOpsActionCenter.d.ts +11 -0
  364. package/dist/vue/useVoiceOpsStatus.d.ts +9 -0
  365. package/dist/vue/useVoicePlatformCoverage.d.ts +9 -0
  366. package/dist/vue/useVoiceProfileComparison.d.ts +9 -0
  367. package/dist/vue/useVoiceProofTrends.d.ts +9 -0
  368. package/dist/vue/useVoiceProviderCapabilities.d.ts +9 -0
  369. package/dist/vue/useVoiceProviderContracts.d.ts +9 -0
  370. package/dist/vue/useVoiceProviderSimulationControls.d.ts +24 -0
  371. package/dist/vue/useVoiceProviderStatus.d.ts +3 -3
  372. package/dist/vue/useVoiceReadinessFailures.d.ts +959 -0
  373. package/dist/vue/useVoiceReconnectProfileEvidence.d.ts +9 -0
  374. package/dist/vue/useVoiceRoutingStatus.d.ts +8 -0
  375. package/dist/vue/useVoiceSessionObservability.d.ts +9 -0
  376. package/dist/vue/useVoiceSessionSnapshot.d.ts +10 -0
  377. package/dist/vue/useVoiceStream.d.ts +5 -2
  378. package/dist/vue/useVoiceTraceTimeline.d.ts +9 -0
  379. package/dist/vue/useVoiceTurnLatency.d.ts +10 -0
  380. package/dist/vue/useVoiceTurnQuality.d.ts +9 -0
  381. package/dist/vue/useVoiceWorkflowStatus.d.ts +3 -3
  382. package/dist/webhookVerification.d.ts +27 -0
  383. package/dist/workflowContract.d.ts +8 -8
  384. package/fixtures/manifest.json +356 -197
  385. package/package.json +265 -256
  386. package/dist/angular/voice-app-kit-status.service.d.ts +0 -12
  387. package/dist/appKit.d.ts +0 -83
  388. package/dist/client/appKitStatus.d.ts +0 -19
  389. package/dist/react/useVoiceAppKitStatus.d.ts +0 -8
  390. package/dist/svelte/createVoiceAppKitStatus.d.ts +0 -8
  391. 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,87 +1587,204 @@ 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-platform-coverage.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 = {}) => {
1772
+ // src/client/platformCoverage.ts
1773
+ var fetchVoicePlatformCoverage = async (path = "/api/voice/platform-coverage", options = {}) => {
1466
1774
  const fetchImpl = options.fetch ?? globalThis.fetch;
1467
1775
  const response = await fetchImpl(path);
1468
1776
  if (!response.ok) {
1469
- throw new Error(`Voice provider status failed: HTTP ${response.status}`);
1777
+ throw new Error(`Voice platform coverage failed: HTTP ${response.status}`);
1470
1778
  }
1471
1779
  return await response.json();
1472
1780
  };
1473
- var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {}) => {
1781
+ var createVoicePlatformCoverageStore = (path = "/api/voice/platform-coverage", options = {}) => {
1474
1782
  const listeners = new Set;
1475
1783
  let closed = false;
1476
1784
  let timer;
1477
1785
  let snapshot = {
1478
1786
  error: null,
1479
- isLoading: false,
1480
- providers: []
1787
+ isLoading: false
1481
1788
  };
1482
1789
  const emit = () => {
1483
1790
  for (const listener of listeners) {
@@ -1486,7 +1793,7 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1486
1793
  };
1487
1794
  const refresh = async () => {
1488
1795
  if (closed) {
1489
- return snapshot.providers;
1796
+ return snapshot.report;
1490
1797
  }
1491
1798
  snapshot = {
1492
1799
  ...snapshot,
@@ -1495,15 +1802,15 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1495
1802
  };
1496
1803
  emit();
1497
1804
  try {
1498
- const providers = await fetchVoiceProviderStatus(path, options);
1805
+ const report = await fetchVoicePlatformCoverage(path, options);
1499
1806
  snapshot = {
1500
1807
  error: null,
1501
1808
  isLoading: false,
1502
- providers,
1809
+ report,
1503
1810
  updatedAt: Date.now()
1504
1811
  };
1505
1812
  emit();
1506
- return providers;
1813
+ return report;
1507
1814
  } catch (error) {
1508
1815
  snapshot = {
1509
1816
  ...snapshot,
@@ -1522,7 +1829,7 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1522
1829
  }
1523
1830
  listeners.clear();
1524
1831
  };
1525
- if (options.intervalMs && options.intervalMs > 0) {
1832
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
1526
1833
  timer = setInterval(() => {
1527
1834
  refresh().catch(() => {});
1528
1835
  }, options.intervalMs);
@@ -1541,59 +1848,61 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1541
1848
  };
1542
1849
  };
1543
1850
 
1544
- // src/angular/voice-provider-status.service.ts
1851
+ // src/angular/voice-platform-coverage.service.ts
1545
1852
  var _dec = [
1546
- Injectable4({ providedIn: "root" })
1853
+ Injectable3({ providedIn: "root" })
1547
1854
  ];
1548
1855
  var _init = __decoratorStart(undefined);
1549
1856
 
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);
1857
+ class VoicePlatformCoverageService {
1858
+ connect(path = "/api/voice/platform-coverage", options = {}) {
1859
+ const store = createVoicePlatformCoverageStore(path, options);
1860
+ const errorSignal = signal3(null);
1861
+ const isLoadingSignal = signal3(false);
1862
+ const reportSignal = signal3(undefined);
1863
+ const updatedAtSignal = signal3(undefined);
1557
1864
  const sync = () => {
1558
1865
  const snapshot = store.getSnapshot();
1559
1866
  errorSignal.set(snapshot.error);
1560
1867
  isLoadingSignal.set(snapshot.isLoading);
1561
- providersSignal.set([...snapshot.providers]);
1868
+ reportSignal.set(snapshot.report);
1562
1869
  updatedAtSignal.set(snapshot.updatedAt);
1563
1870
  };
1564
1871
  const unsubscribe = store.subscribe(sync);
1565
1872
  sync();
1566
- store.refresh().catch(() => {});
1873
+ if (typeof window !== "undefined") {
1874
+ store.refresh().catch(() => {});
1875
+ }
1567
1876
  return {
1568
1877
  close: () => {
1569
1878
  unsubscribe();
1570
1879
  store.close();
1571
1880
  },
1572
- error: computed4(() => errorSignal()),
1573
- isLoading: computed4(() => isLoadingSignal()),
1574
- providers: computed4(() => providersSignal()),
1881
+ error: computed3(() => errorSignal()),
1882
+ isLoading: computed3(() => isLoadingSignal()),
1575
1883
  refresh: store.refresh,
1576
- updatedAt: computed4(() => updatedAtSignal())
1884
+ report: computed3(() => reportSignal()),
1885
+ updatedAt: computed3(() => updatedAtSignal())
1577
1886
  };
1578
1887
  }
1579
1888
  }
1580
- VoiceProviderStatusService = __decorateElement(_init, 0, "VoiceProviderStatusService", _dec, VoiceProviderStatusService);
1581
- __runInitializers(_init, 1, VoiceProviderStatusService);
1582
- __decoratorMetadata(_init, VoiceProviderStatusService);
1583
- let _VoiceProviderStatusService = VoiceProviderStatusService;
1584
- // src/angular/voice-workflow-status.service.ts
1585
- import { computed as computed5, Injectable as Injectable5, signal as signal5 } from "@angular/core";
1889
+ VoicePlatformCoverageService = __decorateElement(_init, 0, "VoicePlatformCoverageService", _dec, VoicePlatformCoverageService);
1890
+ __runInitializers(_init, 1, VoicePlatformCoverageService);
1891
+ __decoratorMetadata(_init, VoicePlatformCoverageService);
1892
+ let _VoicePlatformCoverageService = VoicePlatformCoverageService;
1893
+ // src/angular/voice-proof-trends.service.ts
1894
+ import { computed as computed4, Injectable as Injectable4, signal as signal4 } from "@angular/core";
1586
1895
 
1587
- // src/client/workflowStatus.ts
1588
- var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
1896
+ // src/client/proofTrends.ts
1897
+ var fetchVoiceProofTrends = async (path = "/api/voice/proof-trends", options = {}) => {
1589
1898
  const fetchImpl = options.fetch ?? globalThis.fetch;
1590
1899
  const response = await fetchImpl(path);
1591
1900
  if (!response.ok) {
1592
- throw new Error(`Voice workflow status failed: HTTP ${response.status}`);
1901
+ throw new Error(`Voice proof trends failed: HTTP ${response.status}`);
1593
1902
  }
1594
1903
  return await response.json();
1595
1904
  };
1596
- var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options = {}) => {
1905
+ var createVoiceProofTrendsStore = (path = "/api/voice/proof-trends", options = {}) => {
1597
1906
  const listeners = new Set;
1598
1907
  let closed = false;
1599
1908
  let timer;
@@ -1617,7 +1926,7 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
1617
1926
  };
1618
1927
  emit();
1619
1928
  try {
1620
- const report = await fetchVoiceWorkflowStatus(path, options);
1929
+ const report = await fetchVoiceProofTrends(path, options);
1621
1930
  snapshot = {
1622
1931
  error: null,
1623
1932
  isLoading: false,
@@ -1663,15 +1972,135 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
1663
1972
  };
1664
1973
  };
1665
1974
 
1666
- // src/angular/voice-workflow-status.service.ts
1975
+ // src/angular/voice-proof-trends.service.ts
1976
+ var _dec = [
1977
+ Injectable4({ providedIn: "root" })
1978
+ ];
1979
+ var _init = __decoratorStart(undefined);
1980
+
1981
+ class VoiceProofTrendsService {
1982
+ connect(path = "/api/voice/proof-trends", options = {}) {
1983
+ const store = createVoiceProofTrendsStore(path, options);
1984
+ const errorSignal = signal4(null);
1985
+ const isLoadingSignal = signal4(false);
1986
+ const reportSignal = signal4(undefined);
1987
+ const updatedAtSignal = signal4(undefined);
1988
+ const sync = () => {
1989
+ const snapshot = store.getSnapshot();
1990
+ errorSignal.set(snapshot.error);
1991
+ isLoadingSignal.set(snapshot.isLoading);
1992
+ reportSignal.set(snapshot.report);
1993
+ updatedAtSignal.set(snapshot.updatedAt);
1994
+ };
1995
+ const unsubscribe = store.subscribe(sync);
1996
+ sync();
1997
+ if (typeof window !== "undefined") {
1998
+ store.refresh().catch(() => {});
1999
+ }
2000
+ return {
2001
+ close: () => {
2002
+ unsubscribe();
2003
+ store.close();
2004
+ },
2005
+ error: computed4(() => errorSignal()),
2006
+ isLoading: computed4(() => isLoadingSignal()),
2007
+ refresh: store.refresh,
2008
+ report: computed4(() => reportSignal()),
2009
+ updatedAt: computed4(() => updatedAtSignal())
2010
+ };
2011
+ }
2012
+ }
2013
+ VoiceProofTrendsService = __decorateElement(_init, 0, "VoiceProofTrendsService", _dec, VoiceProofTrendsService);
2014
+ __runInitializers(_init, 1, VoiceProofTrendsService);
2015
+ __decoratorMetadata(_init, VoiceProofTrendsService);
2016
+ let _VoiceProofTrendsService = VoiceProofTrendsService;
2017
+ // src/angular/voice-reconnect-profile-evidence.service.ts
2018
+ import { computed as computed5, Injectable as Injectable5, signal as signal5 } from "@angular/core";
2019
+
2020
+ // src/client/reconnectProfileEvidence.ts
2021
+ var fetchVoiceReconnectProfileEvidence = async (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
2022
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2023
+ const response = await fetchImpl(path);
2024
+ if (!response.ok) {
2025
+ throw new Error(`Voice reconnect profile evidence failed: HTTP ${response.status}`);
2026
+ }
2027
+ return await response.json();
2028
+ };
2029
+ var createVoiceReconnectProfileEvidenceStore = (path = "/api/voice/reconnect-profile-evidence", options = {}) => {
2030
+ const listeners = new Set;
2031
+ let closed = false;
2032
+ let timer;
2033
+ let snapshot = {
2034
+ error: null,
2035
+ isLoading: false
2036
+ };
2037
+ const emit = () => {
2038
+ for (const listener of listeners) {
2039
+ listener();
2040
+ }
2041
+ };
2042
+ const refresh = async () => {
2043
+ if (closed) {
2044
+ return snapshot.report;
2045
+ }
2046
+ snapshot = { ...snapshot, error: null, isLoading: true };
2047
+ emit();
2048
+ try {
2049
+ const report = await fetchVoiceReconnectProfileEvidence(path, options);
2050
+ snapshot = {
2051
+ error: null,
2052
+ isLoading: false,
2053
+ report,
2054
+ updatedAt: Date.now()
2055
+ };
2056
+ emit();
2057
+ return report;
2058
+ } catch (error) {
2059
+ snapshot = {
2060
+ ...snapshot,
2061
+ error: error instanceof Error ? error.message : String(error),
2062
+ isLoading: false
2063
+ };
2064
+ emit();
2065
+ throw error;
2066
+ }
2067
+ };
2068
+ const close = () => {
2069
+ closed = true;
2070
+ if (timer) {
2071
+ clearInterval(timer);
2072
+ timer = undefined;
2073
+ }
2074
+ listeners.clear();
2075
+ };
2076
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2077
+ timer = setInterval(() => {
2078
+ refresh().catch(() => {});
2079
+ }, options.intervalMs);
2080
+ }
2081
+ return {
2082
+ close,
2083
+ getServerSnapshot: () => snapshot,
2084
+ getSnapshot: () => snapshot,
2085
+ refresh,
2086
+ subscribe: (listener) => {
2087
+ listeners.add(listener);
2088
+ return () => {
2089
+ listeners.delete(listener);
2090
+ };
2091
+ }
2092
+ };
2093
+ };
2094
+
2095
+ // src/angular/voice-reconnect-profile-evidence.service.ts
1667
2096
  var _dec = [
1668
2097
  Injectable5({ providedIn: "root" })
1669
2098
  ];
1670
2099
  var _init = __decoratorStart(undefined);
1671
2100
 
1672
- class VoiceWorkflowStatusService {
1673
- connect(path = "/evals/scenarios/json", options = {}) {
1674
- const store = createVoiceWorkflowStatusStore(path, options);
2101
+ class VoiceReconnectProfileEvidenceService {
2102
+ connect(path = "/api/voice/reconnect-profile-evidence", options = {}) {
2103
+ const store = createVoiceReconnectProfileEvidenceStore(path, options);
1675
2104
  const errorSignal = signal5(null);
1676
2105
  const isLoadingSignal = signal5(false);
1677
2106
  const reportSignal = signal5(undefined);
@@ -1701,14 +2130,2622 @@ class VoiceWorkflowStatusService {
1701
2130
  };
1702
2131
  }
1703
2132
  }
2133
+ VoiceReconnectProfileEvidenceService = __decorateElement(_init, 0, "VoiceReconnectProfileEvidenceService", _dec, VoiceReconnectProfileEvidenceService);
2134
+ __runInitializers(_init, 1, VoiceReconnectProfileEvidenceService);
2135
+ __decoratorMetadata(_init, VoiceReconnectProfileEvidenceService);
2136
+ let _VoiceReconnectProfileEvidenceService = VoiceReconnectProfileEvidenceService;
2137
+ // src/angular/voice-call-debugger.service.ts
2138
+ import { computed as computed6, Injectable as Injectable6, signal as signal6 } from "@angular/core";
2139
+
2140
+ // src/client/callDebugger.ts
2141
+ var fetchVoiceCallDebugger = async (path, options = {}) => {
2142
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2143
+ const response = await fetchImpl(path);
2144
+ if (!response.ok) {
2145
+ throw new Error(`Voice call debugger failed: HTTP ${response.status}`);
2146
+ }
2147
+ return await response.json();
2148
+ };
2149
+ var createVoiceCallDebuggerStore = (path, options = {}) => {
2150
+ const listeners = new Set;
2151
+ let closed = false;
2152
+ let timer;
2153
+ let snapshot = {
2154
+ error: null,
2155
+ isLoading: false
2156
+ };
2157
+ const emit = () => {
2158
+ for (const listener of listeners) {
2159
+ listener();
2160
+ }
2161
+ };
2162
+ const refresh = async () => {
2163
+ if (closed) {
2164
+ return snapshot.report;
2165
+ }
2166
+ snapshot = { ...snapshot, error: null, isLoading: true };
2167
+ emit();
2168
+ try {
2169
+ const report = await fetchVoiceCallDebugger(path, options);
2170
+ snapshot = {
2171
+ error: null,
2172
+ isLoading: false,
2173
+ report,
2174
+ updatedAt: Date.now()
2175
+ };
2176
+ emit();
2177
+ return report;
2178
+ } catch (error) {
2179
+ snapshot = {
2180
+ ...snapshot,
2181
+ error: error instanceof Error ? error.message : String(error),
2182
+ isLoading: false
2183
+ };
2184
+ emit();
2185
+ throw error;
2186
+ }
2187
+ };
2188
+ const close = () => {
2189
+ closed = true;
2190
+ if (timer) {
2191
+ clearInterval(timer);
2192
+ timer = undefined;
2193
+ }
2194
+ listeners.clear();
2195
+ };
2196
+ if (options.intervalMs && options.intervalMs > 0) {
2197
+ timer = setInterval(() => {
2198
+ refresh().catch(() => {});
2199
+ }, options.intervalMs);
2200
+ }
2201
+ return {
2202
+ close,
2203
+ getServerSnapshot: () => snapshot,
2204
+ getSnapshot: () => snapshot,
2205
+ refresh,
2206
+ subscribe: (listener) => {
2207
+ listeners.add(listener);
2208
+ return () => {
2209
+ listeners.delete(listener);
2210
+ };
2211
+ }
2212
+ };
2213
+ };
2214
+
2215
+ // src/angular/voice-call-debugger.service.ts
2216
+ var _dec = [
2217
+ Injectable6({ providedIn: "root" })
2218
+ ];
2219
+ var _init = __decoratorStart(undefined);
2220
+
2221
+ class VoiceCallDebuggerService {
2222
+ connect(path, options = {}) {
2223
+ const store = createVoiceCallDebuggerStore(path, options);
2224
+ const errorSignal = signal6(null);
2225
+ const isLoadingSignal = signal6(false);
2226
+ const reportSignal = signal6(undefined);
2227
+ const updatedAtSignal = signal6(undefined);
2228
+ const sync = () => {
2229
+ const state = store.getSnapshot();
2230
+ errorSignal.set(state.error);
2231
+ isLoadingSignal.set(state.isLoading);
2232
+ reportSignal.set(state.report);
2233
+ updatedAtSignal.set(state.updatedAt);
2234
+ };
2235
+ const unsubscribe = store.subscribe(sync);
2236
+ sync();
2237
+ store.refresh().catch(() => {});
2238
+ return {
2239
+ close: () => {
2240
+ unsubscribe();
2241
+ store.close();
2242
+ },
2243
+ error: computed6(() => errorSignal()),
2244
+ isLoading: computed6(() => isLoadingSignal()),
2245
+ refresh: store.refresh,
2246
+ report: computed6(() => reportSignal()),
2247
+ updatedAt: computed6(() => updatedAtSignal())
2248
+ };
2249
+ }
2250
+ }
2251
+ VoiceCallDebuggerService = __decorateElement(_init, 0, "VoiceCallDebuggerService", _dec, VoiceCallDebuggerService);
2252
+ __runInitializers(_init, 1, VoiceCallDebuggerService);
2253
+ __decoratorMetadata(_init, VoiceCallDebuggerService);
2254
+ let _VoiceCallDebuggerService = VoiceCallDebuggerService;
2255
+ // src/angular/voice-session-snapshot.service.ts
2256
+ import { computed as computed7, Injectable as Injectable7, signal as signal7 } from "@angular/core";
2257
+
2258
+ // src/client/sessionSnapshot.ts
2259
+ var withTurnId = (path, turnId) => {
2260
+ if (!turnId) {
2261
+ return path;
2262
+ }
2263
+ const url = new URL(path, "http://absolutejs.local");
2264
+ url.searchParams.set("turnId", turnId);
2265
+ return `${url.pathname}${url.search}`;
2266
+ };
2267
+ var fetchVoiceSessionSnapshot = async (path, options = {}) => {
2268
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2269
+ const response = await fetchImpl(withTurnId(path, options.turnId));
2270
+ if (!response.ok) {
2271
+ throw new Error(`Voice session snapshot failed: HTTP ${response.status}`);
2272
+ }
2273
+ return await response.json();
2274
+ };
2275
+ var createVoiceSessionSnapshotStore = (path, options = {}) => {
2276
+ const listeners = new Set;
2277
+ let closed = false;
2278
+ let timer;
2279
+ let snapshot = {
2280
+ error: null,
2281
+ isLoading: false
2282
+ };
2283
+ const emit = () => {
2284
+ for (const listener of listeners) {
2285
+ listener();
2286
+ }
2287
+ };
2288
+ const refresh = async () => {
2289
+ if (closed) {
2290
+ return snapshot.snapshot;
2291
+ }
2292
+ snapshot = { ...snapshot, error: null, isLoading: true };
2293
+ emit();
2294
+ try {
2295
+ const next = await fetchVoiceSessionSnapshot(path, options);
2296
+ snapshot = {
2297
+ error: null,
2298
+ isLoading: false,
2299
+ snapshot: next,
2300
+ updatedAt: Date.now()
2301
+ };
2302
+ emit();
2303
+ return next;
2304
+ } catch (error) {
2305
+ snapshot = {
2306
+ ...snapshot,
2307
+ error: error instanceof Error ? error.message : String(error),
2308
+ isLoading: false
2309
+ };
2310
+ emit();
2311
+ throw error;
2312
+ }
2313
+ };
2314
+ const download = () => {
2315
+ const current = snapshot.snapshot;
2316
+ if (current === undefined) {
2317
+ throw new Error("Voice session snapshot has not been loaded.");
2318
+ }
2319
+ return new Blob([JSON.stringify(current, null, 2)], {
2320
+ type: "application/json"
2321
+ });
2322
+ };
2323
+ const close = () => {
2324
+ closed = true;
2325
+ if (timer) {
2326
+ clearInterval(timer);
2327
+ timer = undefined;
2328
+ }
2329
+ listeners.clear();
2330
+ };
2331
+ if (options.intervalMs && options.intervalMs > 0) {
2332
+ timer = setInterval(() => {
2333
+ refresh().catch(() => {});
2334
+ }, options.intervalMs);
2335
+ }
2336
+ return {
2337
+ close,
2338
+ download,
2339
+ getServerSnapshot: () => snapshot,
2340
+ getSnapshot: () => snapshot,
2341
+ refresh,
2342
+ subscribe: (listener) => {
2343
+ listeners.add(listener);
2344
+ return () => {
2345
+ listeners.delete(listener);
2346
+ };
2347
+ }
2348
+ };
2349
+ };
2350
+
2351
+ // src/angular/voice-session-snapshot.service.ts
2352
+ var _dec = [
2353
+ Injectable7({ providedIn: "root" })
2354
+ ];
2355
+ var _init = __decoratorStart(undefined);
2356
+
2357
+ class VoiceSessionSnapshotService {
2358
+ connect(path, options = {}) {
2359
+ const store = createVoiceSessionSnapshotStore(path, options);
2360
+ const errorSignal = signal7(null);
2361
+ const isLoadingSignal = signal7(false);
2362
+ const snapshotSignal = signal7(undefined);
2363
+ const updatedAtSignal = signal7(undefined);
2364
+ const sync = () => {
2365
+ const state = store.getSnapshot();
2366
+ errorSignal.set(state.error);
2367
+ isLoadingSignal.set(state.isLoading);
2368
+ snapshotSignal.set(state.snapshot);
2369
+ updatedAtSignal.set(state.updatedAt);
2370
+ };
2371
+ const unsubscribe = store.subscribe(sync);
2372
+ sync();
2373
+ store.refresh().catch(() => {});
2374
+ return {
2375
+ close: () => {
2376
+ unsubscribe();
2377
+ store.close();
2378
+ },
2379
+ download: store.download,
2380
+ error: computed7(() => errorSignal()),
2381
+ isLoading: computed7(() => isLoadingSignal()),
2382
+ refresh: store.refresh,
2383
+ snapshot: computed7(() => snapshotSignal()),
2384
+ updatedAt: computed7(() => updatedAtSignal())
2385
+ };
2386
+ }
2387
+ }
2388
+ VoiceSessionSnapshotService = __decorateElement(_init, 0, "VoiceSessionSnapshotService", _dec, VoiceSessionSnapshotService);
2389
+ __runInitializers(_init, 1, VoiceSessionSnapshotService);
2390
+ __decoratorMetadata(_init, VoiceSessionSnapshotService);
2391
+ let _VoiceSessionSnapshotService = VoiceSessionSnapshotService;
2392
+ // src/angular/voice-session-observability.service.ts
2393
+ import { computed as computed8, Injectable as Injectable8, signal as signal8 } from "@angular/core";
2394
+
2395
+ // src/client/sessionObservability.ts
2396
+ var fetchVoiceSessionObservability = async (path, options = {}) => {
2397
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2398
+ const response = await fetchImpl(path);
2399
+ if (!response.ok) {
2400
+ throw new Error(`Voice session observability failed: HTTP ${response.status}`);
2401
+ }
2402
+ return await response.json();
2403
+ };
2404
+ var createVoiceSessionObservabilityStore = (path, options = {}) => {
2405
+ const listeners = new Set;
2406
+ let closed = false;
2407
+ let timer;
2408
+ let snapshot = {
2409
+ error: null,
2410
+ isLoading: false,
2411
+ report: null
2412
+ };
2413
+ const emit = () => {
2414
+ for (const listener of listeners) {
2415
+ listener();
2416
+ }
2417
+ };
2418
+ const refresh = async () => {
2419
+ if (closed) {
2420
+ return snapshot.report;
2421
+ }
2422
+ snapshot = {
2423
+ ...snapshot,
2424
+ error: null,
2425
+ isLoading: true
2426
+ };
2427
+ emit();
2428
+ try {
2429
+ const report = await fetchVoiceSessionObservability(path, options);
2430
+ snapshot = {
2431
+ error: null,
2432
+ isLoading: false,
2433
+ report,
2434
+ updatedAt: Date.now()
2435
+ };
2436
+ emit();
2437
+ return report;
2438
+ } catch (error) {
2439
+ snapshot = {
2440
+ ...snapshot,
2441
+ error: error instanceof Error ? error.message : String(error),
2442
+ isLoading: false
2443
+ };
2444
+ emit();
2445
+ throw error;
2446
+ }
2447
+ };
2448
+ const close = () => {
2449
+ closed = true;
2450
+ if (timer) {
2451
+ clearInterval(timer);
2452
+ timer = undefined;
2453
+ }
2454
+ listeners.clear();
2455
+ };
2456
+ if (options.intervalMs && options.intervalMs > 0) {
2457
+ timer = setInterval(() => {
2458
+ refresh().catch(() => {});
2459
+ }, options.intervalMs);
2460
+ }
2461
+ return {
2462
+ close,
2463
+ getServerSnapshot: () => snapshot,
2464
+ getSnapshot: () => snapshot,
2465
+ refresh,
2466
+ subscribe: (listener) => {
2467
+ listeners.add(listener);
2468
+ return () => {
2469
+ listeners.delete(listener);
2470
+ };
2471
+ }
2472
+ };
2473
+ };
2474
+
2475
+ // src/angular/voice-session-observability.service.ts
2476
+ var _dec = [
2477
+ Injectable8({ providedIn: "root" })
2478
+ ];
2479
+ var _init = __decoratorStart(undefined);
2480
+
2481
+ class VoiceSessionObservabilityService {
2482
+ connect(path = "/api/voice/session-observability/latest", options = {}) {
2483
+ const store = createVoiceSessionObservabilityStore(path, options);
2484
+ const errorSignal = signal8(null);
2485
+ const isLoadingSignal = signal8(false);
2486
+ const reportSignal = signal8(null);
2487
+ const updatedAtSignal = signal8(undefined);
2488
+ const sync = () => {
2489
+ const snapshot = store.getSnapshot();
2490
+ errorSignal.set(snapshot.error);
2491
+ isLoadingSignal.set(snapshot.isLoading);
2492
+ reportSignal.set(snapshot.report);
2493
+ updatedAtSignal.set(snapshot.updatedAt);
2494
+ };
2495
+ const unsubscribe = store.subscribe(sync);
2496
+ sync();
2497
+ store.refresh().catch(() => {});
2498
+ return {
2499
+ close: () => {
2500
+ unsubscribe();
2501
+ store.close();
2502
+ },
2503
+ error: computed8(() => errorSignal()),
2504
+ isLoading: computed8(() => isLoadingSignal()),
2505
+ refresh: store.refresh,
2506
+ report: computed8(() => reportSignal()),
2507
+ updatedAt: computed8(() => updatedAtSignal())
2508
+ };
2509
+ }
2510
+ }
2511
+ VoiceSessionObservabilityService = __decorateElement(_init, 0, "VoiceSessionObservabilityService", _dec, VoiceSessionObservabilityService);
2512
+ __runInitializers(_init, 1, VoiceSessionObservabilityService);
2513
+ __decoratorMetadata(_init, VoiceSessionObservabilityService);
2514
+ let _VoiceSessionObservabilityService = VoiceSessionObservabilityService;
2515
+ // src/angular/voice-profile-comparison.service.ts
2516
+ import { computed as computed9, Injectable as Injectable9, signal as signal9 } from "@angular/core";
2517
+
2518
+ // src/client/profileComparison.ts
2519
+ var fetchVoiceProfileComparison = async (path = "/api/voice/real-call-profile-history", options = {}) => {
2520
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2521
+ const response = await fetchImpl(path);
2522
+ if (!response.ok) {
2523
+ throw new Error(`Voice profile comparison failed: HTTP ${response.status}`);
2524
+ }
2525
+ return await response.json();
2526
+ };
2527
+ var createVoiceProfileComparisonStore = (path = "/api/voice/real-call-profile-history", options = {}) => {
2528
+ const listeners = new Set;
2529
+ let closed = false;
2530
+ let timer;
2531
+ let snapshot = {
2532
+ error: null,
2533
+ isLoading: false
2534
+ };
2535
+ const emit = () => {
2536
+ for (const listener of listeners) {
2537
+ listener();
2538
+ }
2539
+ };
2540
+ const refresh = async () => {
2541
+ if (closed) {
2542
+ return snapshot.report;
2543
+ }
2544
+ snapshot = { ...snapshot, error: null, isLoading: true };
2545
+ emit();
2546
+ try {
2547
+ const report = await fetchVoiceProfileComparison(path, options);
2548
+ snapshot = {
2549
+ error: null,
2550
+ isLoading: false,
2551
+ report,
2552
+ updatedAt: Date.now()
2553
+ };
2554
+ emit();
2555
+ return report;
2556
+ } catch (error) {
2557
+ snapshot = {
2558
+ ...snapshot,
2559
+ error: error instanceof Error ? error.message : String(error),
2560
+ isLoading: false
2561
+ };
2562
+ emit();
2563
+ throw error;
2564
+ }
2565
+ };
2566
+ const close = () => {
2567
+ closed = true;
2568
+ if (timer) {
2569
+ clearInterval(timer);
2570
+ timer = undefined;
2571
+ }
2572
+ listeners.clear();
2573
+ };
2574
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2575
+ timer = setInterval(() => {
2576
+ refresh().catch(() => {});
2577
+ }, options.intervalMs);
2578
+ }
2579
+ return {
2580
+ close,
2581
+ getServerSnapshot: () => snapshot,
2582
+ getSnapshot: () => snapshot,
2583
+ refresh,
2584
+ subscribe: (listener) => {
2585
+ listeners.add(listener);
2586
+ return () => {
2587
+ listeners.delete(listener);
2588
+ };
2589
+ }
2590
+ };
2591
+ };
2592
+
2593
+ // src/angular/voice-profile-comparison.service.ts
2594
+ var _dec = [
2595
+ Injectable9({ providedIn: "root" })
2596
+ ];
2597
+ var _init = __decoratorStart(undefined);
2598
+
2599
+ class VoiceProfileComparisonService {
2600
+ connect(path = "/api/voice/real-call-profile-history", options = {}) {
2601
+ const store = createVoiceProfileComparisonStore(path, options);
2602
+ const errorSignal = signal9(null);
2603
+ const isLoadingSignal = signal9(false);
2604
+ const reportSignal = signal9(undefined);
2605
+ const updatedAtSignal = signal9(undefined);
2606
+ const sync = () => {
2607
+ const snapshot = store.getSnapshot();
2608
+ errorSignal.set(snapshot.error);
2609
+ isLoadingSignal.set(snapshot.isLoading);
2610
+ reportSignal.set(snapshot.report);
2611
+ updatedAtSignal.set(snapshot.updatedAt);
2612
+ };
2613
+ const unsubscribe = store.subscribe(sync);
2614
+ sync();
2615
+ if (typeof window !== "undefined") {
2616
+ store.refresh().catch(() => {});
2617
+ }
2618
+ return {
2619
+ close: () => {
2620
+ unsubscribe();
2621
+ store.close();
2622
+ },
2623
+ error: computed9(() => errorSignal()),
2624
+ isLoading: computed9(() => isLoadingSignal()),
2625
+ refresh: store.refresh,
2626
+ report: computed9(() => reportSignal()),
2627
+ updatedAt: computed9(() => updatedAtSignal())
2628
+ };
2629
+ }
2630
+ }
2631
+ VoiceProfileComparisonService = __decorateElement(_init, 0, "VoiceProfileComparisonService", _dec, VoiceProfileComparisonService);
2632
+ __runInitializers(_init, 1, VoiceProfileComparisonService);
2633
+ __decoratorMetadata(_init, VoiceProfileComparisonService);
2634
+ let _VoiceProfileComparisonService = VoiceProfileComparisonService;
2635
+ // src/angular/voice-readiness-failures.service.ts
2636
+ import { computed as computed10, Injectable as Injectable10, signal as signal10 } from "@angular/core";
2637
+
2638
+ // src/client/readinessFailures.ts
2639
+ var fetchVoiceReadinessFailures = async (path = "/api/production-readiness", options = {}) => {
2640
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2641
+ const response = await fetchImpl(path);
2642
+ if (!response.ok) {
2643
+ throw new Error(`Voice readiness failed: HTTP ${response.status}`);
2644
+ }
2645
+ return await response.json();
2646
+ };
2647
+ var createVoiceReadinessFailuresStore = (path = "/api/production-readiness", options = {}) => {
2648
+ const listeners = new Set;
2649
+ let closed = false;
2650
+ let timer;
2651
+ let snapshot = {
2652
+ error: null,
2653
+ isLoading: false
2654
+ };
2655
+ const emit = () => {
2656
+ for (const listener of listeners) {
2657
+ listener();
2658
+ }
2659
+ };
2660
+ const refresh = async () => {
2661
+ if (closed) {
2662
+ return snapshot.report;
2663
+ }
2664
+ snapshot = { ...snapshot, error: null, isLoading: true };
2665
+ emit();
2666
+ try {
2667
+ const report = await fetchVoiceReadinessFailures(path, options);
2668
+ snapshot = {
2669
+ error: null,
2670
+ isLoading: false,
2671
+ report,
2672
+ updatedAt: Date.now()
2673
+ };
2674
+ emit();
2675
+ return report;
2676
+ } catch (error) {
2677
+ snapshot = {
2678
+ ...snapshot,
2679
+ error: error instanceof Error ? error.message : String(error),
2680
+ isLoading: false
2681
+ };
2682
+ emit();
2683
+ throw error;
2684
+ }
2685
+ };
2686
+ const close = () => {
2687
+ closed = true;
2688
+ if (timer) {
2689
+ clearInterval(timer);
2690
+ timer = undefined;
2691
+ }
2692
+ listeners.clear();
2693
+ };
2694
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2695
+ timer = setInterval(() => {
2696
+ refresh().catch(() => {});
2697
+ }, options.intervalMs);
2698
+ }
2699
+ return {
2700
+ close,
2701
+ getServerSnapshot: () => snapshot,
2702
+ getSnapshot: () => snapshot,
2703
+ refresh,
2704
+ subscribe: (listener) => {
2705
+ listeners.add(listener);
2706
+ return () => {
2707
+ listeners.delete(listener);
2708
+ };
2709
+ }
2710
+ };
2711
+ };
2712
+
2713
+ // src/angular/voice-readiness-failures.service.ts
2714
+ var _dec = [
2715
+ Injectable10({ providedIn: "root" })
2716
+ ];
2717
+ var _init = __decoratorStart(undefined);
2718
+
2719
+ class VoiceReadinessFailuresService {
2720
+ connect(path = "/api/production-readiness", options = {}) {
2721
+ const store = createVoiceReadinessFailuresStore(path, options);
2722
+ const errorSignal = signal10(null);
2723
+ const isLoadingSignal = signal10(false);
2724
+ const reportSignal = signal10(undefined);
2725
+ const updatedAtSignal = signal10(undefined);
2726
+ const sync = () => {
2727
+ const snapshot = store.getSnapshot();
2728
+ errorSignal.set(snapshot.error);
2729
+ isLoadingSignal.set(snapshot.isLoading);
2730
+ reportSignal.set(snapshot.report);
2731
+ updatedAtSignal.set(snapshot.updatedAt);
2732
+ };
2733
+ const unsubscribe = store.subscribe(sync);
2734
+ sync();
2735
+ if (typeof window !== "undefined") {
2736
+ store.refresh().catch(() => {});
2737
+ }
2738
+ return {
2739
+ close: () => {
2740
+ unsubscribe();
2741
+ store.close();
2742
+ },
2743
+ error: computed10(() => errorSignal()),
2744
+ explanations: computed10(() => reportSignal()?.checks.filter((check) => check.status !== "pass" && !!check.gateExplanation) ?? []),
2745
+ isLoading: computed10(() => isLoadingSignal()),
2746
+ refresh: store.refresh,
2747
+ report: computed10(() => reportSignal()),
2748
+ updatedAt: computed10(() => updatedAtSignal())
2749
+ };
2750
+ }
2751
+ }
2752
+ VoiceReadinessFailuresService = __decorateElement(_init, 0, "VoiceReadinessFailuresService", _dec, VoiceReadinessFailuresService);
2753
+ __runInitializers(_init, 1, VoiceReadinessFailuresService);
2754
+ __decoratorMetadata(_init, VoiceReadinessFailuresService);
2755
+ let _VoiceReadinessFailuresService = VoiceReadinessFailuresService;
2756
+ // src/angular/voice-ops-action-center.service.ts
2757
+ import { computed as computed11, Injectable as Injectable11, signal as signal11 } from "@angular/core";
2758
+
2759
+ // src/client/opsActionCenter.ts
2760
+ var recordVoiceOpsActionResult = async (result, options = {}) => {
2761
+ if (options.auditPath === false) {
2762
+ return;
2763
+ }
2764
+ const path = options.auditPath ?? "/api/voice/ops-actions/audit";
2765
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2766
+ const response = await fetchImpl(path, {
2767
+ body: JSON.stringify(result),
2768
+ headers: {
2769
+ "Content-Type": "application/json"
2770
+ },
2771
+ method: "POST"
2772
+ });
2773
+ if (!response.ok) {
2774
+ throw new Error(`Voice ops action audit failed: HTTP ${response.status}`);
2775
+ }
2776
+ };
2777
+ var createVoiceOpsActionCenterActions = (options = {}) => {
2778
+ const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
2779
+ const actions = [];
2780
+ if (options.includeProductionReadiness !== false) {
2781
+ actions.push({
2782
+ description: "Refresh the production readiness report.",
2783
+ id: "production-readiness",
2784
+ label: "Refresh readiness",
2785
+ method: "GET",
2786
+ path: options.productionReadinessPath ?? "/api/production-readiness"
2787
+ });
2788
+ }
2789
+ if (options.includeDeliveryRuntime !== false) {
2790
+ actions.push({
2791
+ description: "Drain pending and failed audit/trace deliveries.",
2792
+ id: "delivery-runtime.tick",
2793
+ label: "Tick delivery workers",
2794
+ method: "POST",
2795
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
2796
+ }, {
2797
+ description: "Move reviewed dead letters back to live delivery queues.",
2798
+ id: "delivery-runtime.requeue-dead-letters",
2799
+ label: "Requeue dead letters",
2800
+ method: "POST",
2801
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
2802
+ });
2803
+ }
2804
+ if (options.includeTurnLatencyProof !== false) {
2805
+ actions.push({
2806
+ description: "Run the synthetic turn latency proof.",
2807
+ id: "turn-latency.proof",
2808
+ label: "Run latency proof",
2809
+ method: "POST",
2810
+ path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
2811
+ });
2812
+ }
2813
+ if (options.includeProviderSimulation !== false) {
2814
+ const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
2815
+ for (const provider of options.providers ?? []) {
2816
+ actions.push({
2817
+ description: `Simulate ${provider} provider failure.`,
2818
+ id: `provider.${provider}.failure`,
2819
+ label: `Simulate ${provider} failure`,
2820
+ method: "POST",
2821
+ path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
2822
+ }, {
2823
+ description: `Mark ${provider} provider recovered.`,
2824
+ id: `provider.${provider}.recovery`,
2825
+ label: `Recover ${provider}`,
2826
+ method: "POST",
2827
+ path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
2828
+ });
2829
+ }
2830
+ }
2831
+ return actions;
2832
+ };
2833
+ var runVoiceOpsAction = async (action, options = {}) => {
2834
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2835
+ const response = await fetchImpl(action.path, {
2836
+ method: action.method ?? "POST"
2837
+ });
2838
+ const body = await response.json().catch(() => null);
2839
+ if (!response.ok) {
2840
+ const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
2841
+ throw new Error(message);
2842
+ }
2843
+ return {
2844
+ actionId: action.id,
2845
+ body,
2846
+ ok: response.ok,
2847
+ ranAt: Date.now(),
2848
+ status: response.status
2849
+ };
2850
+ };
2851
+ var createVoiceOpsActionCenterStore = (options = {}) => {
2852
+ const listeners = new Set;
2853
+ let closed = false;
2854
+ let timer;
2855
+ let snapshot = {
2856
+ actions: options.actions ?? createVoiceOpsActionCenterActions(),
2857
+ error: null,
2858
+ isRunning: false
2859
+ };
2860
+ const emit = () => {
2861
+ for (const listener of listeners) {
2862
+ listener();
2863
+ }
2864
+ };
2865
+ const setActions = (actions) => {
2866
+ snapshot = { ...snapshot, actions, updatedAt: Date.now() };
2867
+ emit();
2868
+ };
2869
+ const run = async (actionId) => {
2870
+ if (closed) {
2871
+ return snapshot.lastResult;
2872
+ }
2873
+ const action = snapshot.actions.find((item) => item.id === actionId);
2874
+ if (!action) {
2875
+ throw new Error(`Voice ops action "${actionId}" is not configured.`);
2876
+ }
2877
+ if (action.disabled) {
2878
+ throw new Error(`Voice ops action "${actionId}" is disabled.`);
2879
+ }
2880
+ snapshot = {
2881
+ ...snapshot,
2882
+ error: null,
2883
+ isRunning: true,
2884
+ runningActionId: action.id
2885
+ };
2886
+ emit();
2887
+ try {
2888
+ const result = await runVoiceOpsAction(action, options);
2889
+ await options.onActionResult?.(result);
2890
+ await recordVoiceOpsActionResult(result, options);
2891
+ snapshot = {
2892
+ ...snapshot,
2893
+ error: null,
2894
+ isRunning: false,
2895
+ lastResult: result,
2896
+ runningActionId: undefined,
2897
+ updatedAt: Date.now()
2898
+ };
2899
+ emit();
2900
+ return result;
2901
+ } catch (error) {
2902
+ const result = {
2903
+ actionId: action.id,
2904
+ body: null,
2905
+ error: error instanceof Error ? error.message : String(error),
2906
+ ok: false,
2907
+ ranAt: Date.now(),
2908
+ status: 0
2909
+ };
2910
+ await options.onActionResult?.(result);
2911
+ await recordVoiceOpsActionResult(result, options).catch(() => {});
2912
+ snapshot = {
2913
+ ...snapshot,
2914
+ error: error instanceof Error ? error.message : String(error),
2915
+ isRunning: false,
2916
+ runningActionId: undefined
2917
+ };
2918
+ emit();
2919
+ throw error;
2920
+ }
2921
+ };
2922
+ const close = () => {
2923
+ closed = true;
2924
+ if (timer) {
2925
+ clearInterval(timer);
2926
+ timer = undefined;
2927
+ }
2928
+ listeners.clear();
2929
+ };
2930
+ if (options.intervalMs && options.intervalMs > 0) {
2931
+ timer = setInterval(() => {
2932
+ emit();
2933
+ }, options.intervalMs);
2934
+ }
2935
+ return {
2936
+ close,
2937
+ getServerSnapshot: () => snapshot,
2938
+ getSnapshot: () => snapshot,
2939
+ run,
2940
+ setActions,
2941
+ subscribe: (listener) => {
2942
+ listeners.add(listener);
2943
+ return () => {
2944
+ listeners.delete(listener);
2945
+ };
2946
+ }
2947
+ };
2948
+ };
2949
+
2950
+ // src/angular/voice-ops-action-center.service.ts
2951
+ var _dec = [
2952
+ Injectable11({ providedIn: "root" })
2953
+ ];
2954
+ var _init = __decoratorStart(undefined);
2955
+
2956
+ class VoiceOpsActionCenterService {
2957
+ connect(options = {}) {
2958
+ const store = createVoiceOpsActionCenterStore(options);
2959
+ const actionsSignal = signal11([]);
2960
+ const errorSignal = signal11(null);
2961
+ const isRunningSignal = signal11(false);
2962
+ const lastResultSignal = signal11(undefined);
2963
+ const runningActionIdSignal = signal11(undefined);
2964
+ const sync = () => {
2965
+ const snapshot = store.getSnapshot();
2966
+ actionsSignal.set(snapshot.actions);
2967
+ errorSignal.set(snapshot.error);
2968
+ isRunningSignal.set(snapshot.isRunning);
2969
+ lastResultSignal.set(snapshot.lastResult);
2970
+ runningActionIdSignal.set(snapshot.runningActionId);
2971
+ };
2972
+ const unsubscribe = store.subscribe(sync);
2973
+ sync();
2974
+ return {
2975
+ actions: computed11(() => actionsSignal()),
2976
+ close: () => {
2977
+ unsubscribe();
2978
+ store.close();
2979
+ },
2980
+ error: computed11(() => errorSignal()),
2981
+ isRunning: computed11(() => isRunningSignal()),
2982
+ lastResult: computed11(() => lastResultSignal()),
2983
+ run: store.run,
2984
+ runningActionId: computed11(() => runningActionIdSignal()),
2985
+ setActions: store.setActions
2986
+ };
2987
+ }
2988
+ }
2989
+ VoiceOpsActionCenterService = __decorateElement(_init, 0, "VoiceOpsActionCenterService", _dec, VoiceOpsActionCenterService);
2990
+ __runInitializers(_init, 1, VoiceOpsActionCenterService);
2991
+ __decoratorMetadata(_init, VoiceOpsActionCenterService);
2992
+ let _VoiceOpsActionCenterService = VoiceOpsActionCenterService;
2993
+ // src/angular/voice-live-ops.service.ts
2994
+ import { computed as computed12, Injectable as Injectable12, signal as signal12 } from "@angular/core";
2995
+
2996
+ // src/client/liveOps.ts
2997
+ var postVoiceLiveOpsAction = async (input, options = {}) => {
2998
+ if (!input.sessionId) {
2999
+ throw new Error("Start a voice session before running live ops actions.");
3000
+ }
3001
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3002
+ const response = await fetchImpl(options.actionPath ?? "/api/voice/live-ops/action", {
3003
+ body: JSON.stringify(input),
3004
+ headers: {
3005
+ "Content-Type": "application/json"
3006
+ },
3007
+ method: "POST"
3008
+ });
3009
+ const payload = await response.json().catch(() => null);
3010
+ if (!response.ok || !payload?.ok) {
3011
+ const message = payload && typeof payload === "object" && "error" in payload ? String(payload.error) : `Voice live ops action failed: HTTP ${response.status}`;
3012
+ throw new Error(message);
3013
+ }
3014
+ return payload;
3015
+ };
3016
+ var createVoiceLiveOpsStore = (options = {}) => {
3017
+ const listeners = new Set;
3018
+ let closed = false;
3019
+ let snapshot = {
3020
+ error: null,
3021
+ isRunning: false
3022
+ };
3023
+ const emit = () => {
3024
+ for (const listener of listeners) {
3025
+ listener();
3026
+ }
3027
+ };
3028
+ const run = async (input) => {
3029
+ if (closed) {
3030
+ return snapshot.lastResult;
3031
+ }
3032
+ snapshot = {
3033
+ ...snapshot,
3034
+ error: null,
3035
+ isRunning: true,
3036
+ runningAction: input.action
3037
+ };
3038
+ emit();
3039
+ try {
3040
+ const result = await postVoiceLiveOpsAction(input, options);
3041
+ await options.onControl?.(result);
3042
+ snapshot = {
3043
+ ...snapshot,
3044
+ error: null,
3045
+ isRunning: false,
3046
+ lastResult: result,
3047
+ runningAction: undefined,
3048
+ updatedAt: Date.now()
3049
+ };
3050
+ emit();
3051
+ return result;
3052
+ } catch (error) {
3053
+ snapshot = {
3054
+ ...snapshot,
3055
+ error: error instanceof Error ? error.message : String(error),
3056
+ isRunning: false,
3057
+ runningAction: undefined,
3058
+ updatedAt: Date.now()
3059
+ };
3060
+ emit();
3061
+ throw error;
3062
+ }
3063
+ };
3064
+ const close = () => {
3065
+ closed = true;
3066
+ listeners.clear();
3067
+ };
3068
+ return {
3069
+ close,
3070
+ getServerSnapshot: () => snapshot,
3071
+ getSnapshot: () => snapshot,
3072
+ run,
3073
+ subscribe: (listener) => {
3074
+ listeners.add(listener);
3075
+ return () => {
3076
+ listeners.delete(listener);
3077
+ };
3078
+ }
3079
+ };
3080
+ };
3081
+
3082
+ // src/angular/voice-live-ops.service.ts
3083
+ var _dec = [
3084
+ Injectable12({ providedIn: "root" })
3085
+ ];
3086
+ var _init = __decoratorStart(undefined);
3087
+
3088
+ class VoiceLiveOpsService {
3089
+ connect(options = {}) {
3090
+ const store = createVoiceLiveOpsStore(options);
3091
+ const errorSignal = signal12(null);
3092
+ const isRunningSignal = signal12(false);
3093
+ const lastResultSignal = signal12(undefined);
3094
+ const runningActionSignal = signal12(undefined);
3095
+ const sync = () => {
3096
+ const snapshot = store.getSnapshot();
3097
+ errorSignal.set(snapshot.error);
3098
+ isRunningSignal.set(snapshot.isRunning);
3099
+ lastResultSignal.set(snapshot.lastResult);
3100
+ runningActionSignal.set(snapshot.runningAction);
3101
+ };
3102
+ const unsubscribe = store.subscribe(sync);
3103
+ sync();
3104
+ return {
3105
+ close: () => {
3106
+ unsubscribe();
3107
+ store.close();
3108
+ },
3109
+ error: computed12(() => errorSignal()),
3110
+ isRunning: computed12(() => isRunningSignal()),
3111
+ lastResult: computed12(() => lastResultSignal()),
3112
+ run: store.run,
3113
+ runningAction: computed12(() => runningActionSignal())
3114
+ };
3115
+ }
3116
+ }
3117
+ VoiceLiveOpsService = __decorateElement(_init, 0, "VoiceLiveOpsService", _dec, VoiceLiveOpsService);
3118
+ __runInitializers(_init, 1, VoiceLiveOpsService);
3119
+ __decoratorMetadata(_init, VoiceLiveOpsService);
3120
+ let _VoiceLiveOpsService = VoiceLiveOpsService;
3121
+ // src/angular/voice-delivery-runtime.service.ts
3122
+ import { computed as computed13, Injectable as Injectable13, signal as signal13 } from "@angular/core";
3123
+
3124
+ // src/client/deliveryRuntime.ts
3125
+ var getDefaultActionPath = (path, action, options) => {
3126
+ if (action === "tick") {
3127
+ return options.tickPath ?? `${path.replace(/\/$/, "")}/tick`;
3128
+ }
3129
+ return options.requeueDeadLettersPath ?? `${path.replace(/\/$/, "")}/requeue-dead-letters`;
3130
+ };
3131
+ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
3132
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3133
+ const response = await fetchImpl(path);
3134
+ if (!response.ok) {
3135
+ throw new Error(`Voice delivery runtime failed: HTTP ${response.status}`);
3136
+ }
3137
+ return await response.json();
3138
+ };
3139
+ var runVoiceDeliveryRuntimeAction = async (action, path = "/api/voice-delivery-runtime", options = {}) => {
3140
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3141
+ const response = await fetchImpl(getDefaultActionPath(path, action, options), {
3142
+ method: "POST"
3143
+ });
3144
+ if (!response.ok) {
3145
+ throw new Error(`Voice delivery runtime ${action} failed: HTTP ${response.status}`);
3146
+ }
3147
+ const body = await response.json();
3148
+ return {
3149
+ action,
3150
+ result: body.result,
3151
+ summary: body.summary,
3152
+ updatedAt: Date.now()
3153
+ };
3154
+ };
3155
+ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
3156
+ const listeners = new Set;
3157
+ let closed = false;
3158
+ let timer;
3159
+ let snapshot = {
3160
+ actionError: null,
3161
+ actionStatus: "idle",
3162
+ error: null,
3163
+ isLoading: false
3164
+ };
3165
+ const emit = () => {
3166
+ for (const listener of listeners) {
3167
+ listener();
3168
+ }
3169
+ };
3170
+ const refresh = async () => {
3171
+ if (closed) {
3172
+ return snapshot.report;
3173
+ }
3174
+ snapshot = {
3175
+ ...snapshot,
3176
+ error: null,
3177
+ isLoading: true
3178
+ };
3179
+ emit();
3180
+ try {
3181
+ const report = await fetchVoiceDeliveryRuntime(path, options);
3182
+ snapshot = {
3183
+ ...snapshot,
3184
+ error: null,
3185
+ isLoading: false,
3186
+ report,
3187
+ updatedAt: Date.now()
3188
+ };
3189
+ emit();
3190
+ return report;
3191
+ } catch (error) {
3192
+ snapshot = {
3193
+ ...snapshot,
3194
+ error: error instanceof Error ? error.message : String(error),
3195
+ isLoading: false
3196
+ };
3197
+ emit();
3198
+ throw error;
3199
+ }
3200
+ };
3201
+ const runAction = async (action) => {
3202
+ if (closed) {
3203
+ return snapshot.lastAction;
3204
+ }
3205
+ snapshot = {
3206
+ ...snapshot,
3207
+ actionError: null,
3208
+ actionStatus: "running"
3209
+ };
3210
+ emit();
3211
+ try {
3212
+ const result = await runVoiceDeliveryRuntimeAction(action, path, options);
3213
+ snapshot = {
3214
+ ...snapshot,
3215
+ actionError: null,
3216
+ actionStatus: "completed",
3217
+ lastAction: result
3218
+ };
3219
+ emit();
3220
+ await refresh();
3221
+ return result;
3222
+ } catch (error) {
3223
+ snapshot = {
3224
+ ...snapshot,
3225
+ actionError: error instanceof Error ? error.message : String(error),
3226
+ actionStatus: "failed"
3227
+ };
3228
+ emit();
3229
+ throw error;
3230
+ }
3231
+ };
3232
+ const close = () => {
3233
+ closed = true;
3234
+ if (timer) {
3235
+ clearInterval(timer);
3236
+ timer = undefined;
3237
+ }
3238
+ listeners.clear();
3239
+ };
3240
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
3241
+ timer = setInterval(() => {
3242
+ refresh().catch(() => {});
3243
+ }, options.intervalMs);
3244
+ }
3245
+ return {
3246
+ close,
3247
+ getServerSnapshot: () => snapshot,
3248
+ getSnapshot: () => snapshot,
3249
+ requeueDeadLetters: () => runAction("requeue-dead-letters"),
3250
+ refresh,
3251
+ tick: () => runAction("tick"),
3252
+ subscribe: (listener) => {
3253
+ listeners.add(listener);
3254
+ return () => {
3255
+ listeners.delete(listener);
3256
+ };
3257
+ }
3258
+ };
3259
+ };
3260
+
3261
+ // src/angular/voice-delivery-runtime.service.ts
3262
+ var _dec = [
3263
+ Injectable13({ providedIn: "root" })
3264
+ ];
3265
+ var _init = __decoratorStart(undefined);
3266
+
3267
+ class VoiceDeliveryRuntimeService {
3268
+ connect(path = "/api/voice-delivery-runtime", options = {}) {
3269
+ const store = createVoiceDeliveryRuntimeStore(path, options);
3270
+ const actionErrorSignal = signal13(null);
3271
+ const actionStatusSignal = signal13("idle");
3272
+ const errorSignal = signal13(null);
3273
+ const isLoadingSignal = signal13(false);
3274
+ const reportSignal = signal13(undefined);
3275
+ const updatedAtSignal = signal13(undefined);
3276
+ const sync = () => {
3277
+ const snapshot = store.getSnapshot();
3278
+ actionErrorSignal.set(snapshot.actionError);
3279
+ actionStatusSignal.set(snapshot.actionStatus);
3280
+ errorSignal.set(snapshot.error);
3281
+ isLoadingSignal.set(snapshot.isLoading);
3282
+ reportSignal.set(snapshot.report);
3283
+ updatedAtSignal.set(snapshot.updatedAt);
3284
+ };
3285
+ const unsubscribe = store.subscribe(sync);
3286
+ sync();
3287
+ if (typeof window !== "undefined") {
3288
+ store.refresh().catch(() => {});
3289
+ }
3290
+ return {
3291
+ close: () => {
3292
+ unsubscribe();
3293
+ store.close();
3294
+ },
3295
+ error: computed13(() => errorSignal()),
3296
+ actionError: computed13(() => actionErrorSignal()),
3297
+ actionStatus: computed13(() => actionStatusSignal()),
3298
+ isLoading: computed13(() => isLoadingSignal()),
3299
+ requeueDeadLetters: store.requeueDeadLetters,
3300
+ refresh: store.refresh,
3301
+ report: computed13(() => reportSignal()),
3302
+ tick: store.tick,
3303
+ updatedAt: computed13(() => updatedAtSignal())
3304
+ };
3305
+ }
3306
+ }
3307
+ VoiceDeliveryRuntimeService = __decorateElement(_init, 0, "VoiceDeliveryRuntimeService", _dec, VoiceDeliveryRuntimeService);
3308
+ __runInitializers(_init, 1, VoiceDeliveryRuntimeService);
3309
+ __decoratorMetadata(_init, VoiceDeliveryRuntimeService);
3310
+ let _VoiceDeliveryRuntimeService = VoiceDeliveryRuntimeService;
3311
+ // src/angular/voice-campaign-dialer-proof.service.ts
3312
+ import { computed as computed14, Injectable as Injectable14, signal as signal14 } from "@angular/core";
3313
+
3314
+ // src/client/campaignDialerProof.ts
3315
+ var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3316
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3317
+ const response = await fetchImpl(path);
3318
+ if (!response.ok) {
3319
+ throw new Error(`Voice campaign dialer proof status failed: HTTP ${response.status}`);
3320
+ }
3321
+ return await response.json();
3322
+ };
3323
+ var runVoiceCampaignDialerProofAction = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3324
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3325
+ const response = await fetchImpl(path, { method: "POST" });
3326
+ if (!response.ok) {
3327
+ throw new Error(`Voice campaign dialer proof failed: HTTP ${response.status}`);
3328
+ }
3329
+ return await response.json();
3330
+ };
3331
+ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
3332
+ const listeners = new Set;
3333
+ let closed = false;
3334
+ let timer;
3335
+ let snapshot = {
3336
+ error: null,
3337
+ isLoading: false
3338
+ };
3339
+ const emit = () => {
3340
+ for (const listener of listeners) {
3341
+ listener();
3342
+ }
3343
+ };
3344
+ const refresh = async () => {
3345
+ if (closed) {
3346
+ return snapshot.status;
3347
+ }
3348
+ snapshot = { ...snapshot, error: null, isLoading: true };
3349
+ emit();
3350
+ try {
3351
+ const status = await fetchVoiceCampaignDialerProofStatus(path, options);
3352
+ snapshot = {
3353
+ ...snapshot,
3354
+ error: null,
3355
+ isLoading: false,
3356
+ status,
3357
+ updatedAt: Date.now()
3358
+ };
3359
+ emit();
3360
+ return status;
3361
+ } catch (error) {
3362
+ snapshot = {
3363
+ ...snapshot,
3364
+ error: error instanceof Error ? error.message : String(error),
3365
+ isLoading: false
3366
+ };
3367
+ emit();
3368
+ throw error;
3369
+ }
3370
+ };
3371
+ const runProof = async () => {
3372
+ const runPath = options.runPath ?? snapshot.status?.runPath ?? path;
3373
+ snapshot = { ...snapshot, error: null, isLoading: true };
3374
+ emit();
3375
+ try {
3376
+ const report = await runVoiceCampaignDialerProofAction(runPath, options);
3377
+ snapshot = {
3378
+ ...snapshot,
3379
+ error: null,
3380
+ isLoading: false,
3381
+ report,
3382
+ status: {
3383
+ generatedAt: Date.now(),
3384
+ mode: report.mode,
3385
+ ok: report.ok,
3386
+ providers: report.providers.map((provider) => provider.provider),
3387
+ runPath,
3388
+ safe: true
3389
+ },
3390
+ updatedAt: Date.now()
3391
+ };
3392
+ emit();
3393
+ return report;
3394
+ } catch (error) {
3395
+ snapshot = {
3396
+ ...snapshot,
3397
+ error: error instanceof Error ? error.message : String(error),
3398
+ isLoading: false
3399
+ };
3400
+ emit();
3401
+ throw error;
3402
+ }
3403
+ };
3404
+ const close = () => {
3405
+ closed = true;
3406
+ if (timer) {
3407
+ clearInterval(timer);
3408
+ timer = undefined;
3409
+ }
3410
+ listeners.clear();
3411
+ };
3412
+ if (options.intervalMs && options.intervalMs > 0) {
3413
+ timer = setInterval(() => {
3414
+ refresh().catch(() => {});
3415
+ }, options.intervalMs);
3416
+ }
3417
+ return {
3418
+ close,
3419
+ getServerSnapshot: () => snapshot,
3420
+ getSnapshot: () => snapshot,
3421
+ refresh,
3422
+ runProof,
3423
+ subscribe: (listener) => {
3424
+ listeners.add(listener);
3425
+ return () => {
3426
+ listeners.delete(listener);
3427
+ };
3428
+ }
3429
+ };
3430
+ };
3431
+
3432
+ // src/angular/voice-campaign-dialer-proof.service.ts
3433
+ var _dec = [
3434
+ Injectable14({ providedIn: "root" })
3435
+ ];
3436
+ var _init = __decoratorStart(undefined);
3437
+
3438
+ class VoiceCampaignDialerProofService {
3439
+ connect(path = "/api/voice/campaigns/dialer-proof", options = {}) {
3440
+ const store = createVoiceCampaignDialerProofStore(path, options);
3441
+ const errorSignal = signal14(null);
3442
+ const isLoadingSignal = signal14(false);
3443
+ const reportSignal = signal14(undefined);
3444
+ const statusSignal = signal14(undefined);
3445
+ const updatedAtSignal = signal14(undefined);
3446
+ const sync = () => {
3447
+ const snapshot = store.getSnapshot();
3448
+ errorSignal.set(snapshot.error);
3449
+ isLoadingSignal.set(snapshot.isLoading);
3450
+ reportSignal.set(snapshot.report);
3451
+ statusSignal.set(snapshot.status);
3452
+ updatedAtSignal.set(snapshot.updatedAt);
3453
+ };
3454
+ const unsubscribe = store.subscribe(sync);
3455
+ sync();
3456
+ store.refresh().catch(() => {});
3457
+ return {
3458
+ close: () => {
3459
+ unsubscribe();
3460
+ store.close();
3461
+ },
3462
+ error: computed14(() => errorSignal()),
3463
+ isLoading: computed14(() => isLoadingSignal()),
3464
+ refresh: store.refresh,
3465
+ report: computed14(() => reportSignal()),
3466
+ runProof: store.runProof,
3467
+ status: computed14(() => statusSignal()),
3468
+ updatedAt: computed14(() => updatedAtSignal())
3469
+ };
3470
+ }
3471
+ }
3472
+ VoiceCampaignDialerProofService = __decorateElement(_init, 0, "VoiceCampaignDialerProofService", _dec, VoiceCampaignDialerProofService);
3473
+ __runInitializers(_init, 1, VoiceCampaignDialerProofService);
3474
+ __decoratorMetadata(_init, VoiceCampaignDialerProofService);
3475
+ let _VoiceCampaignDialerProofService = VoiceCampaignDialerProofService;
3476
+ // src/angular/voice-stream.service.ts
3477
+ import { computed as computed15, Injectable as Injectable15, signal as signal15 } from "@angular/core";
3478
+ var _dec = [
3479
+ Injectable15({ providedIn: "root" })
3480
+ ];
3481
+ var _init = __decoratorStart(undefined);
3482
+
3483
+ class VoiceStreamService {
3484
+ connect(path, options = {}) {
3485
+ const stream = createVoiceStream(path, options);
3486
+ const assistantAudioSignal = signal15([]);
3487
+ const assistantTextsSignal = signal15([]);
3488
+ const callSignal = signal15(null);
3489
+ const errorSignal = signal15(null);
3490
+ const isConnectedSignal = signal15(false);
3491
+ const partialSignal = signal15("");
3492
+ const reconnectSignal = signal15(stream.reconnect);
3493
+ const sessionIdSignal = signal15(stream.sessionId);
3494
+ const sessionMetadataSignal = signal15(stream.sessionMetadata);
3495
+ const statusSignal = signal15(stream.status);
3496
+ const turnsSignal = signal15([]);
3497
+ const sync = () => {
3498
+ assistantAudioSignal.set([...stream.assistantAudio]);
3499
+ assistantTextsSignal.set([...stream.assistantTexts]);
3500
+ callSignal.set(stream.call);
3501
+ errorSignal.set(stream.error);
3502
+ isConnectedSignal.set(stream.isConnected);
3503
+ partialSignal.set(stream.partial);
3504
+ reconnectSignal.set(stream.reconnect);
3505
+ sessionIdSignal.set(stream.sessionId);
3506
+ sessionMetadataSignal.set(stream.sessionMetadata);
3507
+ statusSignal.set(stream.status);
3508
+ turnsSignal.set([...stream.turns]);
3509
+ };
3510
+ const unsubscribe = stream.subscribe(sync);
3511
+ sync();
3512
+ return {
3513
+ assistantAudio: computed15(() => assistantAudioSignal()),
3514
+ assistantTexts: computed15(() => assistantTextsSignal()),
3515
+ call: computed15(() => callSignal()),
3516
+ callControl: (message) => stream.callControl(message),
3517
+ close: () => {
3518
+ unsubscribe();
3519
+ stream.close();
3520
+ },
3521
+ endTurn: () => stream.endTurn(),
3522
+ error: computed15(() => errorSignal()),
3523
+ isConnected: computed15(() => isConnectedSignal()),
3524
+ partial: computed15(() => partialSignal()),
3525
+ reconnect: computed15(() => reconnectSignal()),
3526
+ sendAudio: (audio) => stream.sendAudio(audio),
3527
+ simulateDisconnect: () => stream.simulateDisconnect(),
3528
+ sessionId: computed15(() => sessionIdSignal()),
3529
+ sessionMetadata: computed15(() => sessionMetadataSignal()),
3530
+ status: computed15(() => statusSignal()),
3531
+ turns: computed15(() => turnsSignal())
3532
+ };
3533
+ }
3534
+ }
3535
+ VoiceStreamService = __decorateElement(_init, 0, "VoiceStreamService", _dec, VoiceStreamService);
3536
+ __runInitializers(_init, 1, VoiceStreamService);
3537
+ __decoratorMetadata(_init, VoiceStreamService);
3538
+ let _VoiceStreamService = VoiceStreamService;
3539
+ // src/angular/voice-controller.service.ts
3540
+ import { computed as computed16, Injectable as Injectable16, signal as signal16 } from "@angular/core";
3541
+ var _dec = [
3542
+ Injectable16({ providedIn: "root" })
3543
+ ];
3544
+ var _init = __decoratorStart(undefined);
3545
+
3546
+ class VoiceControllerService {
3547
+ connect(path, options = {}) {
3548
+ const controller = createVoiceController(path, options);
3549
+ const assistantAudioSignal = signal16([]);
3550
+ const assistantTextsSignal = signal16([]);
3551
+ const errorSignal = signal16(null);
3552
+ const isConnectedSignal = signal16(false);
3553
+ const isRecordingSignal = signal16(false);
3554
+ const partialSignal = signal16("");
3555
+ const reconnectSignal = signal16(controller.reconnect);
3556
+ const recordingErrorSignal = signal16(null);
3557
+ const sessionIdSignal = signal16(controller.sessionId);
3558
+ const statusSignal = signal16(controller.status);
3559
+ const turnsSignal = signal16([]);
3560
+ const sync = () => {
3561
+ assistantAudioSignal.set([...controller.assistantAudio]);
3562
+ assistantTextsSignal.set([...controller.assistantTexts]);
3563
+ errorSignal.set(controller.error);
3564
+ isConnectedSignal.set(controller.isConnected);
3565
+ isRecordingSignal.set(controller.isRecording);
3566
+ partialSignal.set(controller.partial);
3567
+ reconnectSignal.set(controller.reconnect);
3568
+ recordingErrorSignal.set(controller.recordingError);
3569
+ sessionIdSignal.set(controller.sessionId);
3570
+ statusSignal.set(controller.status);
3571
+ turnsSignal.set([...controller.turns]);
3572
+ };
3573
+ const unsubscribe = controller.subscribe(sync);
3574
+ sync();
3575
+ return {
3576
+ assistantAudio: computed16(() => assistantAudioSignal()),
3577
+ assistantTexts: computed16(() => assistantTextsSignal()),
3578
+ bindHTMX: controller.bindHTMX,
3579
+ close: () => {
3580
+ unsubscribe();
3581
+ controller.close();
3582
+ },
3583
+ endTurn: () => controller.endTurn(),
3584
+ error: computed16(() => errorSignal()),
3585
+ isConnected: computed16(() => isConnectedSignal()),
3586
+ isRecording: computed16(() => isRecordingSignal()),
3587
+ partial: computed16(() => partialSignal()),
3588
+ reconnect: computed16(() => reconnectSignal()),
3589
+ recordingError: computed16(() => recordingErrorSignal()),
3590
+ sendAudio: (audio) => controller.sendAudio(audio),
3591
+ simulateDisconnect: () => controller.simulateDisconnect(),
3592
+ sessionId: computed16(() => sessionIdSignal()),
3593
+ startRecording: () => controller.startRecording(),
3594
+ status: computed16(() => statusSignal()),
3595
+ stopRecording: () => controller.stopRecording(),
3596
+ toggleRecording: () => controller.toggleRecording(),
3597
+ turns: computed16(() => turnsSignal())
3598
+ };
3599
+ }
3600
+ }
3601
+ VoiceControllerService = __decorateElement(_init, 0, "VoiceControllerService", _dec, VoiceControllerService);
3602
+ __runInitializers(_init, 1, VoiceControllerService);
3603
+ __decoratorMetadata(_init, VoiceControllerService);
3604
+ let _VoiceControllerService = VoiceControllerService;
3605
+ // src/angular/voice-provider-capabilities.service.ts
3606
+ import { computed as computed17, Injectable as Injectable17, signal as signal17 } from "@angular/core";
3607
+
3608
+ // src/client/providerCapabilities.ts
3609
+ var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
3610
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3611
+ const response = await fetchImpl(path);
3612
+ if (!response.ok) {
3613
+ throw new Error(`Voice provider capabilities failed: HTTP ${response.status}`);
3614
+ }
3615
+ return await response.json();
3616
+ };
3617
+ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities", options = {}) => {
3618
+ const listeners = new Set;
3619
+ let closed = false;
3620
+ let timer;
3621
+ let snapshot = {
3622
+ error: null,
3623
+ isLoading: false
3624
+ };
3625
+ const emit = () => {
3626
+ for (const listener of listeners) {
3627
+ listener();
3628
+ }
3629
+ };
3630
+ const refresh = async () => {
3631
+ if (closed) {
3632
+ return snapshot.report;
3633
+ }
3634
+ snapshot = {
3635
+ ...snapshot,
3636
+ error: null,
3637
+ isLoading: true
3638
+ };
3639
+ emit();
3640
+ try {
3641
+ const report = await fetchVoiceProviderCapabilities(path, options);
3642
+ snapshot = {
3643
+ error: null,
3644
+ isLoading: false,
3645
+ report,
3646
+ updatedAt: Date.now()
3647
+ };
3648
+ emit();
3649
+ return report;
3650
+ } catch (error) {
3651
+ snapshot = {
3652
+ ...snapshot,
3653
+ error: error instanceof Error ? error.message : String(error),
3654
+ isLoading: false
3655
+ };
3656
+ emit();
3657
+ throw error;
3658
+ }
3659
+ };
3660
+ const close = () => {
3661
+ closed = true;
3662
+ if (timer) {
3663
+ clearInterval(timer);
3664
+ timer = undefined;
3665
+ }
3666
+ listeners.clear();
3667
+ };
3668
+ if (options.intervalMs && options.intervalMs > 0) {
3669
+ timer = setInterval(() => {
3670
+ refresh().catch(() => {});
3671
+ }, options.intervalMs);
3672
+ }
3673
+ return {
3674
+ close,
3675
+ getServerSnapshot: () => snapshot,
3676
+ getSnapshot: () => snapshot,
3677
+ refresh,
3678
+ subscribe: (listener) => {
3679
+ listeners.add(listener);
3680
+ return () => {
3681
+ listeners.delete(listener);
3682
+ };
3683
+ }
3684
+ };
3685
+ };
3686
+
3687
+ // src/angular/voice-provider-capabilities.service.ts
3688
+ var _dec = [
3689
+ Injectable17({ providedIn: "root" })
3690
+ ];
3691
+ var _init = __decoratorStart(undefined);
3692
+
3693
+ class VoiceProviderCapabilitiesService {
3694
+ connect(path = "/api/provider-capabilities", options = {}) {
3695
+ const store = createVoiceProviderCapabilitiesStore(path, options);
3696
+ const errorSignal = signal17(null);
3697
+ const isLoadingSignal = signal17(false);
3698
+ const reportSignal = signal17(undefined);
3699
+ const updatedAtSignal = signal17(undefined);
3700
+ const sync = () => {
3701
+ const snapshot = store.getSnapshot();
3702
+ errorSignal.set(snapshot.error);
3703
+ isLoadingSignal.set(snapshot.isLoading);
3704
+ reportSignal.set(snapshot.report);
3705
+ updatedAtSignal.set(snapshot.updatedAt);
3706
+ };
3707
+ const unsubscribe = store.subscribe(sync);
3708
+ sync();
3709
+ store.refresh().catch(() => {});
3710
+ return {
3711
+ close: () => {
3712
+ unsubscribe();
3713
+ store.close();
3714
+ },
3715
+ error: computed17(() => errorSignal()),
3716
+ isLoading: computed17(() => isLoadingSignal()),
3717
+ refresh: store.refresh,
3718
+ report: computed17(() => reportSignal()),
3719
+ updatedAt: computed17(() => updatedAtSignal())
3720
+ };
3721
+ }
3722
+ }
3723
+ VoiceProviderCapabilitiesService = __decorateElement(_init, 0, "VoiceProviderCapabilitiesService", _dec, VoiceProviderCapabilitiesService);
3724
+ __runInitializers(_init, 1, VoiceProviderCapabilitiesService);
3725
+ __decoratorMetadata(_init, VoiceProviderCapabilitiesService);
3726
+ let _VoiceProviderCapabilitiesService = VoiceProviderCapabilitiesService;
3727
+ // src/angular/voice-provider-contracts.service.ts
3728
+ import { computed as computed18, Injectable as Injectable18, signal as signal18 } from "@angular/core";
3729
+
3730
+ // src/client/providerContracts.ts
3731
+ var fetchVoiceProviderContracts = async (path = "/api/provider-contracts", options = {}) => {
3732
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3733
+ const response = await fetchImpl(path);
3734
+ if (!response.ok) {
3735
+ throw new Error(`Voice provider contracts failed: HTTP ${response.status}`);
3736
+ }
3737
+ return await response.json();
3738
+ };
3739
+ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", options = {}) => {
3740
+ const listeners = new Set;
3741
+ let closed = false;
3742
+ let timer;
3743
+ let snapshot = {
3744
+ error: null,
3745
+ isLoading: false
3746
+ };
3747
+ const emit = () => {
3748
+ for (const listener of listeners) {
3749
+ listener();
3750
+ }
3751
+ };
3752
+ const refresh = async () => {
3753
+ if (closed) {
3754
+ return snapshot.report;
3755
+ }
3756
+ snapshot = { ...snapshot, error: null, isLoading: true };
3757
+ emit();
3758
+ try {
3759
+ const report = await fetchVoiceProviderContracts(path, options);
3760
+ snapshot = {
3761
+ error: null,
3762
+ isLoading: false,
3763
+ report,
3764
+ updatedAt: Date.now()
3765
+ };
3766
+ emit();
3767
+ return report;
3768
+ } catch (error) {
3769
+ snapshot = {
3770
+ ...snapshot,
3771
+ error: error instanceof Error ? error.message : String(error),
3772
+ isLoading: false
3773
+ };
3774
+ emit();
3775
+ throw error;
3776
+ }
3777
+ };
3778
+ const close = () => {
3779
+ closed = true;
3780
+ if (timer) {
3781
+ clearInterval(timer);
3782
+ timer = undefined;
3783
+ }
3784
+ listeners.clear();
3785
+ };
3786
+ if (options.intervalMs && options.intervalMs > 0) {
3787
+ timer = setInterval(() => {
3788
+ refresh().catch(() => {});
3789
+ }, options.intervalMs);
3790
+ }
3791
+ return {
3792
+ close,
3793
+ getServerSnapshot: () => snapshot,
3794
+ getSnapshot: () => snapshot,
3795
+ refresh,
3796
+ subscribe: (listener) => {
3797
+ listeners.add(listener);
3798
+ return () => {
3799
+ listeners.delete(listener);
3800
+ };
3801
+ }
3802
+ };
3803
+ };
3804
+
3805
+ // src/angular/voice-provider-contracts.service.ts
3806
+ var _dec = [
3807
+ Injectable18({ providedIn: "root" })
3808
+ ];
3809
+ var _init = __decoratorStart(undefined);
3810
+
3811
+ class VoiceProviderContractsService {
3812
+ connect(path = "/api/provider-contracts", options = {}) {
3813
+ const store = createVoiceProviderContractsStore(path, options);
3814
+ const errorSignal = signal18(null);
3815
+ const isLoadingSignal = signal18(false);
3816
+ const reportSignal = signal18(undefined);
3817
+ const updatedAtSignal = signal18(undefined);
3818
+ const sync = () => {
3819
+ const snapshot = store.getSnapshot();
3820
+ errorSignal.set(snapshot.error);
3821
+ isLoadingSignal.set(snapshot.isLoading);
3822
+ reportSignal.set(snapshot.report);
3823
+ updatedAtSignal.set(snapshot.updatedAt);
3824
+ };
3825
+ const unsubscribe = store.subscribe(sync);
3826
+ sync();
3827
+ store.refresh().catch(() => {});
3828
+ return {
3829
+ close: () => {
3830
+ unsubscribe();
3831
+ store.close();
3832
+ },
3833
+ error: computed18(() => errorSignal()),
3834
+ isLoading: computed18(() => isLoadingSignal()),
3835
+ refresh: store.refresh,
3836
+ report: computed18(() => reportSignal()),
3837
+ updatedAt: computed18(() => updatedAtSignal())
3838
+ };
3839
+ }
3840
+ }
3841
+ VoiceProviderContractsService = __decorateElement(_init, 0, "VoiceProviderContractsService", _dec, VoiceProviderContractsService);
3842
+ __runInitializers(_init, 1, VoiceProviderContractsService);
3843
+ __decoratorMetadata(_init, VoiceProviderContractsService);
3844
+ let _VoiceProviderContractsService = VoiceProviderContractsService;
3845
+ // src/angular/voice-provider-status.service.ts
3846
+ import { computed as computed19, Injectable as Injectable19, signal as signal19 } from "@angular/core";
3847
+
3848
+ // src/client/providerStatus.ts
3849
+ var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
3850
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3851
+ const response = await fetchImpl(path);
3852
+ if (!response.ok) {
3853
+ throw new Error(`Voice provider status failed: HTTP ${response.status}`);
3854
+ }
3855
+ return await response.json();
3856
+ };
3857
+ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {}) => {
3858
+ const listeners = new Set;
3859
+ let closed = false;
3860
+ let timer;
3861
+ let snapshot = {
3862
+ error: null,
3863
+ isLoading: false,
3864
+ providers: []
3865
+ };
3866
+ const emit = () => {
3867
+ for (const listener of listeners) {
3868
+ listener();
3869
+ }
3870
+ };
3871
+ const refresh = async () => {
3872
+ if (closed) {
3873
+ return snapshot.providers;
3874
+ }
3875
+ snapshot = {
3876
+ ...snapshot,
3877
+ error: null,
3878
+ isLoading: true
3879
+ };
3880
+ emit();
3881
+ try {
3882
+ const providers = await fetchVoiceProviderStatus(path, options);
3883
+ snapshot = {
3884
+ error: null,
3885
+ isLoading: false,
3886
+ providers,
3887
+ updatedAt: Date.now()
3888
+ };
3889
+ emit();
3890
+ return providers;
3891
+ } catch (error) {
3892
+ snapshot = {
3893
+ ...snapshot,
3894
+ error: error instanceof Error ? error.message : String(error),
3895
+ isLoading: false
3896
+ };
3897
+ emit();
3898
+ throw error;
3899
+ }
3900
+ };
3901
+ const close = () => {
3902
+ closed = true;
3903
+ if (timer) {
3904
+ clearInterval(timer);
3905
+ timer = undefined;
3906
+ }
3907
+ listeners.clear();
3908
+ };
3909
+ if (options.intervalMs && options.intervalMs > 0) {
3910
+ timer = setInterval(() => {
3911
+ refresh().catch(() => {});
3912
+ }, options.intervalMs);
3913
+ }
3914
+ return {
3915
+ close,
3916
+ getServerSnapshot: () => snapshot,
3917
+ getSnapshot: () => snapshot,
3918
+ refresh,
3919
+ subscribe: (listener) => {
3920
+ listeners.add(listener);
3921
+ return () => {
3922
+ listeners.delete(listener);
3923
+ };
3924
+ }
3925
+ };
3926
+ };
3927
+
3928
+ // src/angular/voice-provider-status.service.ts
3929
+ var _dec = [
3930
+ Injectable19({ providedIn: "root" })
3931
+ ];
3932
+ var _init = __decoratorStart(undefined);
3933
+
3934
+ class VoiceProviderStatusService {
3935
+ connect(path = "/api/provider-status", options = {}) {
3936
+ const store = createVoiceProviderStatusStore(path, options);
3937
+ const errorSignal = signal19(null);
3938
+ const isLoadingSignal = signal19(false);
3939
+ const providersSignal = signal19([]);
3940
+ const updatedAtSignal = signal19(undefined);
3941
+ const sync = () => {
3942
+ const snapshot = store.getSnapshot();
3943
+ errorSignal.set(snapshot.error);
3944
+ isLoadingSignal.set(snapshot.isLoading);
3945
+ providersSignal.set([...snapshot.providers]);
3946
+ updatedAtSignal.set(snapshot.updatedAt);
3947
+ };
3948
+ const unsubscribe = store.subscribe(sync);
3949
+ sync();
3950
+ store.refresh().catch(() => {});
3951
+ return {
3952
+ close: () => {
3953
+ unsubscribe();
3954
+ store.close();
3955
+ },
3956
+ error: computed19(() => errorSignal()),
3957
+ isLoading: computed19(() => isLoadingSignal()),
3958
+ providers: computed19(() => providersSignal()),
3959
+ refresh: store.refresh,
3960
+ updatedAt: computed19(() => updatedAtSignal())
3961
+ };
3962
+ }
3963
+ }
3964
+ VoiceProviderStatusService = __decorateElement(_init, 0, "VoiceProviderStatusService", _dec, VoiceProviderStatusService);
3965
+ __runInitializers(_init, 1, VoiceProviderStatusService);
3966
+ __decoratorMetadata(_init, VoiceProviderStatusService);
3967
+ let _VoiceProviderStatusService = VoiceProviderStatusService;
3968
+ // src/angular/voice-routing-status.service.ts
3969
+ import { Injectable as Injectable20, signal as signal20 } from "@angular/core";
3970
+
3971
+ // src/client/routingStatus.ts
3972
+ var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
3973
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3974
+ const response = await fetchImpl(path);
3975
+ if (!response.ok) {
3976
+ throw new Error(`Voice routing status failed: HTTP ${response.status}`);
3977
+ }
3978
+ return await response.json();
3979
+ };
3980
+ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {}) => {
3981
+ const listeners = new Set;
3982
+ let closed = false;
3983
+ let timer;
3984
+ let snapshot = {
3985
+ decision: null,
3986
+ error: null,
3987
+ isLoading: false
3988
+ };
3989
+ const emit = () => {
3990
+ for (const listener of listeners) {
3991
+ listener();
3992
+ }
3993
+ };
3994
+ const refresh = async () => {
3995
+ if (closed) {
3996
+ return snapshot.decision;
3997
+ }
3998
+ snapshot = {
3999
+ ...snapshot,
4000
+ error: null,
4001
+ isLoading: true
4002
+ };
4003
+ emit();
4004
+ try {
4005
+ const decision = await fetchVoiceRoutingStatus(path, options);
4006
+ snapshot = {
4007
+ decision,
4008
+ error: null,
4009
+ isLoading: false,
4010
+ updatedAt: Date.now()
4011
+ };
4012
+ emit();
4013
+ return decision;
4014
+ } catch (error) {
4015
+ snapshot = {
4016
+ ...snapshot,
4017
+ error: error instanceof Error ? error.message : String(error),
4018
+ isLoading: false
4019
+ };
4020
+ emit();
4021
+ throw error;
4022
+ }
4023
+ };
4024
+ const close = () => {
4025
+ closed = true;
4026
+ if (timer) {
4027
+ clearInterval(timer);
4028
+ timer = undefined;
4029
+ }
4030
+ listeners.clear();
4031
+ };
4032
+ if (options.intervalMs && options.intervalMs > 0) {
4033
+ timer = setInterval(() => {
4034
+ refresh().catch(() => {});
4035
+ }, options.intervalMs);
4036
+ }
4037
+ return {
4038
+ close,
4039
+ getServerSnapshot: () => snapshot,
4040
+ getSnapshot: () => snapshot,
4041
+ refresh,
4042
+ subscribe: (listener) => {
4043
+ listeners.add(listener);
4044
+ return () => {
4045
+ listeners.delete(listener);
4046
+ };
4047
+ }
4048
+ };
4049
+ };
4050
+
4051
+ // src/angular/voice-routing-status.service.ts
4052
+ var _dec = [
4053
+ Injectable20({ providedIn: "root" })
4054
+ ];
4055
+ var _init = __decoratorStart(undefined);
4056
+
4057
+ class VoiceRoutingStatusService {
4058
+ connect(path = "/api/routing/latest", options = {}) {
4059
+ const store = createVoiceRoutingStatusStore(path, options);
4060
+ const decisionSignal = signal20(null);
4061
+ const errorSignal = signal20(null);
4062
+ const isLoadingSignal = signal20(false);
4063
+ const updatedAtSignal = signal20(undefined);
4064
+ const sync = () => {
4065
+ const snapshot = store.getSnapshot();
4066
+ decisionSignal.set(snapshot.decision);
4067
+ errorSignal.set(snapshot.error);
4068
+ isLoadingSignal.set(snapshot.isLoading);
4069
+ updatedAtSignal.set(snapshot.updatedAt);
4070
+ };
4071
+ const unsubscribe = store.subscribe(sync);
4072
+ sync();
4073
+ store.refresh().catch(() => {});
4074
+ return {
4075
+ close: () => {
4076
+ unsubscribe();
4077
+ store.close();
4078
+ },
4079
+ decision: decisionSignal.asReadonly(),
4080
+ error: errorSignal.asReadonly(),
4081
+ isLoading: isLoadingSignal.asReadonly(),
4082
+ refresh: store.refresh,
4083
+ updatedAt: updatedAtSignal.asReadonly()
4084
+ };
4085
+ }
4086
+ }
4087
+ VoiceRoutingStatusService = __decorateElement(_init, 0, "VoiceRoutingStatusService", _dec, VoiceRoutingStatusService);
4088
+ __runInitializers(_init, 1, VoiceRoutingStatusService);
4089
+ __decoratorMetadata(_init, VoiceRoutingStatusService);
4090
+ let _VoiceRoutingStatusService = VoiceRoutingStatusService;
4091
+ // src/angular/voice-trace-timeline.service.ts
4092
+ import { computed as computed20, Injectable as Injectable21, signal as signal21 } from "@angular/core";
4093
+
4094
+ // src/client/traceTimeline.ts
4095
+ var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
4096
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4097
+ const response = await fetchImpl(path);
4098
+ if (!response.ok) {
4099
+ throw new Error(`Voice trace timeline failed: HTTP ${response.status}`);
4100
+ }
4101
+ return await response.json();
4102
+ };
4103
+ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) => {
4104
+ const listeners = new Set;
4105
+ let closed = false;
4106
+ let timer;
4107
+ let snapshot = {
4108
+ error: null,
4109
+ isLoading: false,
4110
+ report: null
4111
+ };
4112
+ const emit = () => {
4113
+ for (const listener of listeners) {
4114
+ listener();
4115
+ }
4116
+ };
4117
+ const refresh = async () => {
4118
+ if (closed) {
4119
+ return snapshot.report;
4120
+ }
4121
+ snapshot = {
4122
+ ...snapshot,
4123
+ error: null,
4124
+ isLoading: true
4125
+ };
4126
+ emit();
4127
+ try {
4128
+ const report = await fetchVoiceTraceTimeline(path, options);
4129
+ snapshot = {
4130
+ error: null,
4131
+ isLoading: false,
4132
+ report,
4133
+ updatedAt: Date.now()
4134
+ };
4135
+ emit();
4136
+ return report;
4137
+ } catch (error) {
4138
+ snapshot = {
4139
+ ...snapshot,
4140
+ error: error instanceof Error ? error.message : String(error),
4141
+ isLoading: false
4142
+ };
4143
+ emit();
4144
+ throw error;
4145
+ }
4146
+ };
4147
+ const close = () => {
4148
+ closed = true;
4149
+ if (timer) {
4150
+ clearInterval(timer);
4151
+ timer = undefined;
4152
+ }
4153
+ listeners.clear();
4154
+ };
4155
+ if (options.intervalMs && options.intervalMs > 0) {
4156
+ timer = setInterval(() => {
4157
+ refresh().catch(() => {});
4158
+ }, options.intervalMs);
4159
+ }
4160
+ return {
4161
+ close,
4162
+ getServerSnapshot: () => snapshot,
4163
+ getSnapshot: () => snapshot,
4164
+ refresh,
4165
+ subscribe: (listener) => {
4166
+ listeners.add(listener);
4167
+ return () => {
4168
+ listeners.delete(listener);
4169
+ };
4170
+ }
4171
+ };
4172
+ };
4173
+
4174
+ // src/angular/voice-trace-timeline.service.ts
4175
+ var _dec = [
4176
+ Injectable21({ providedIn: "root" })
4177
+ ];
4178
+ var _init = __decoratorStart(undefined);
4179
+
4180
+ class VoiceTraceTimelineService {
4181
+ connect(path = "/api/voice-traces", options = {}) {
4182
+ const store = createVoiceTraceTimelineStore(path, options);
4183
+ const errorSignal = signal21(null);
4184
+ const isLoadingSignal = signal21(false);
4185
+ const reportSignal = signal21(null);
4186
+ const updatedAtSignal = signal21(undefined);
4187
+ const sync = () => {
4188
+ const snapshot = store.getSnapshot();
4189
+ errorSignal.set(snapshot.error);
4190
+ isLoadingSignal.set(snapshot.isLoading);
4191
+ reportSignal.set(snapshot.report);
4192
+ updatedAtSignal.set(snapshot.updatedAt);
4193
+ };
4194
+ const unsubscribe = store.subscribe(sync);
4195
+ sync();
4196
+ store.refresh().catch(() => {});
4197
+ return {
4198
+ close: () => {
4199
+ unsubscribe();
4200
+ store.close();
4201
+ },
4202
+ error: computed20(() => errorSignal()),
4203
+ isLoading: computed20(() => isLoadingSignal()),
4204
+ refresh: store.refresh,
4205
+ report: computed20(() => reportSignal()),
4206
+ updatedAt: computed20(() => updatedAtSignal())
4207
+ };
4208
+ }
4209
+ }
4210
+ VoiceTraceTimelineService = __decorateElement(_init, 0, "VoiceTraceTimelineService", _dec, VoiceTraceTimelineService);
4211
+ __runInitializers(_init, 1, VoiceTraceTimelineService);
4212
+ __decoratorMetadata(_init, VoiceTraceTimelineService);
4213
+ let _VoiceTraceTimelineService = VoiceTraceTimelineService;
4214
+ // src/angular/voice-agent-squad-status.service.ts
4215
+ import { computed as computed21, Injectable as Injectable22, signal as signal22 } from "@angular/core";
4216
+
4217
+ // src/client/agentSquadStatus.ts
4218
+ var getString = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
4219
+ var getPayloadString = (event, key) => getString(event.payload?.[key]);
4220
+ var eventStatus = (event) => {
4221
+ const status = getPayloadString(event, "status");
4222
+ if (status === "blocked")
4223
+ return "blocked";
4224
+ if (status === "unknown-target")
4225
+ return "unknown-target";
4226
+ if (status === "allowed")
4227
+ return "handoff";
4228
+ return event.type === "agent.result" ? "active" : "handoff";
4229
+ };
4230
+ var deriveSessionSpecialist = (session) => {
4231
+ const events = [...session.events].sort((left, right) => left.at - right.at);
4232
+ const agentEvents = events.filter((event) => event.type === "agent.handoff" || event.type === "agent.context" || event.type === "agent.result" || event.type === "agent.model");
4233
+ const latest = agentEvents.at(-1);
4234
+ if (!latest) {
4235
+ return {
4236
+ lastEventAt: session.lastEventAt,
4237
+ sessionId: session.sessionId,
4238
+ status: "idle"
4239
+ };
4240
+ }
4241
+ const handoffEvents = events.filter((event) => event.type === "agent.handoff");
4242
+ const lastHandoff = handoffEvents.at(-1);
4243
+ const latestAgentId = getPayloadString(latest, "agentId");
4244
+ const handoffStatus = lastHandoff ? eventStatus(lastHandoff) : undefined;
4245
+ const currentTarget = handoffStatus === "blocked" || handoffStatus === "unknown-target" ? getPayloadString(lastHandoff, "fromAgentId") ?? latestAgentId : getPayloadString(lastHandoff ?? latest, "targetAgentId") ?? latestAgentId;
4246
+ return {
4247
+ fromAgentId: getPayloadString(lastHandoff ?? latest, "fromAgentId"),
4248
+ lastEventAt: latest.at,
4249
+ reason: getPayloadString(lastHandoff ?? latest, "reason") ?? getPayloadString(latest, "handoffTarget"),
4250
+ sessionId: session.sessionId,
4251
+ status: lastHandoff ? eventStatus(lastHandoff) : "active",
4252
+ summary: getPayloadString(lastHandoff ?? latest, "summary"),
4253
+ targetAgentId: currentTarget,
4254
+ turnId: latest.turnId
4255
+ };
4256
+ };
4257
+ var buildVoiceAgentSquadStatusReport = (timeline, options = {}) => {
4258
+ const sessions = (timeline?.sessions ?? []).filter((session) => !options.sessionId || session.sessionId === options.sessionId).map(deriveSessionSpecialist).sort((left, right) => (right.lastEventAt ?? 0) - (left.lastEventAt ?? 0));
4259
+ const active = sessions.filter((session) => session.status !== "idle");
4260
+ return {
4261
+ active,
4262
+ checkedAt: timeline?.checkedAt,
4263
+ current: active[0] ?? sessions[0],
4264
+ sessionCount: sessions.length,
4265
+ sessions
4266
+ };
4267
+ };
4268
+ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}) => {
4269
+ const timelineStore = createVoiceTraceTimelineStore(path, options);
4270
+ const getReport = () => buildVoiceAgentSquadStatusReport(timelineStore.getSnapshot().report, {
4271
+ sessionId: options.sessionId
4272
+ });
4273
+ const getSnapshot = () => {
4274
+ const snapshot = timelineStore.getSnapshot();
4275
+ return {
4276
+ error: snapshot.error,
4277
+ isLoading: snapshot.isLoading,
4278
+ report: getReport(),
4279
+ updatedAt: snapshot.updatedAt
4280
+ };
4281
+ };
4282
+ return {
4283
+ close: timelineStore.close,
4284
+ getServerSnapshot: getSnapshot,
4285
+ getSnapshot,
4286
+ refresh: timelineStore.refresh,
4287
+ subscribe: timelineStore.subscribe
4288
+ };
4289
+ };
4290
+
4291
+ // src/angular/voice-agent-squad-status.service.ts
4292
+ var _dec = [
4293
+ Injectable22({ providedIn: "root" })
4294
+ ];
4295
+ var _init = __decoratorStart(undefined);
4296
+
4297
+ class VoiceAgentSquadStatusService {
4298
+ connect(path = "/api/voice-traces", options = {}) {
4299
+ const store = createVoiceAgentSquadStatusStore(path, options);
4300
+ const errorSignal = signal22(null);
4301
+ const isLoadingSignal = signal22(false);
4302
+ const reportSignal = signal22(undefined);
4303
+ const updatedAtSignal = signal22(undefined);
4304
+ const sync = () => {
4305
+ const snapshot = store.getSnapshot();
4306
+ errorSignal.set(snapshot.error);
4307
+ isLoadingSignal.set(snapshot.isLoading);
4308
+ reportSignal.set(snapshot.report);
4309
+ updatedAtSignal.set(snapshot.updatedAt);
4310
+ };
4311
+ const unsubscribe = store.subscribe(sync);
4312
+ sync();
4313
+ store.refresh().catch(() => {});
4314
+ return {
4315
+ close: () => {
4316
+ unsubscribe();
4317
+ store.close();
4318
+ },
4319
+ current: computed21(() => reportSignal()?.current),
4320
+ error: computed21(() => errorSignal()),
4321
+ isLoading: computed21(() => isLoadingSignal()),
4322
+ refresh: store.refresh,
4323
+ report: computed21(() => reportSignal()),
4324
+ updatedAt: computed21(() => updatedAtSignal())
4325
+ };
4326
+ }
4327
+ }
4328
+ VoiceAgentSquadStatusService = __decorateElement(_init, 0, "VoiceAgentSquadStatusService", _dec, VoiceAgentSquadStatusService);
4329
+ __runInitializers(_init, 1, VoiceAgentSquadStatusService);
4330
+ __decoratorMetadata(_init, VoiceAgentSquadStatusService);
4331
+ let _VoiceAgentSquadStatusService = VoiceAgentSquadStatusService;
4332
+ // src/angular/voice-turn-latency.service.ts
4333
+ import { computed as computed22, Injectable as Injectable23, signal as signal23 } from "@angular/core";
4334
+
4335
+ // src/client/turnLatency.ts
4336
+ var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
4337
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4338
+ const response = await fetchImpl(path);
4339
+ if (!response.ok) {
4340
+ throw new Error(`Voice turn latency failed: HTTP ${response.status}`);
4341
+ }
4342
+ return await response.json();
4343
+ };
4344
+ var runVoiceTurnLatencyProof = async (path, options = {}) => {
4345
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4346
+ const response = await fetchImpl(path, { method: "POST" });
4347
+ if (!response.ok) {
4348
+ throw new Error(`Voice turn latency proof failed: HTTP ${response.status}`);
4349
+ }
4350
+ return response.json();
4351
+ };
4352
+ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) => {
4353
+ const listeners = new Set;
4354
+ let closed = false;
4355
+ let timer;
4356
+ let snapshot = {
4357
+ error: null,
4358
+ isLoading: false
4359
+ };
4360
+ const emit = () => {
4361
+ for (const listener of listeners) {
4362
+ listener();
4363
+ }
4364
+ };
4365
+ const refresh = async () => {
4366
+ if (closed) {
4367
+ return snapshot.report;
4368
+ }
4369
+ snapshot = { ...snapshot, error: null, isLoading: true };
4370
+ emit();
4371
+ try {
4372
+ const report = await fetchVoiceTurnLatency(path, options);
4373
+ snapshot = {
4374
+ error: null,
4375
+ isLoading: false,
4376
+ report,
4377
+ updatedAt: Date.now()
4378
+ };
4379
+ emit();
4380
+ return report;
4381
+ } catch (error) {
4382
+ snapshot = {
4383
+ ...snapshot,
4384
+ error: error instanceof Error ? error.message : String(error),
4385
+ isLoading: false
4386
+ };
4387
+ emit();
4388
+ throw error;
4389
+ }
4390
+ };
4391
+ const runProof = async () => {
4392
+ if (!options.proofPath) {
4393
+ throw new Error("Voice turn latency proof path is not configured.");
4394
+ }
4395
+ snapshot = { ...snapshot, error: null, isLoading: true };
4396
+ emit();
4397
+ try {
4398
+ await runVoiceTurnLatencyProof(options.proofPath, options);
4399
+ return await refresh();
4400
+ } catch (error) {
4401
+ snapshot = {
4402
+ ...snapshot,
4403
+ error: error instanceof Error ? error.message : String(error),
4404
+ isLoading: false
4405
+ };
4406
+ emit();
4407
+ throw error;
4408
+ }
4409
+ };
4410
+ const close = () => {
4411
+ closed = true;
4412
+ if (timer) {
4413
+ clearInterval(timer);
4414
+ timer = undefined;
4415
+ }
4416
+ listeners.clear();
4417
+ };
4418
+ if (options.intervalMs && options.intervalMs > 0) {
4419
+ timer = setInterval(() => {
4420
+ refresh().catch(() => {});
4421
+ }, options.intervalMs);
4422
+ }
4423
+ return {
4424
+ close,
4425
+ getServerSnapshot: () => snapshot,
4426
+ getSnapshot: () => snapshot,
4427
+ refresh,
4428
+ runProof,
4429
+ subscribe: (listener) => {
4430
+ listeners.add(listener);
4431
+ return () => {
4432
+ listeners.delete(listener);
4433
+ };
4434
+ }
4435
+ };
4436
+ };
4437
+
4438
+ // src/angular/voice-turn-latency.service.ts
4439
+ var _dec = [
4440
+ Injectable23({ providedIn: "root" })
4441
+ ];
4442
+ var _init = __decoratorStart(undefined);
4443
+
4444
+ class VoiceTurnLatencyService {
4445
+ connect(path = "/api/turn-latency", options = {}) {
4446
+ const store = createVoiceTurnLatencyStore(path, options);
4447
+ const errorSignal = signal23(null);
4448
+ const isLoadingSignal = signal23(false);
4449
+ const reportSignal = signal23(undefined);
4450
+ const updatedAtSignal = signal23(undefined);
4451
+ const sync = () => {
4452
+ const snapshot = store.getSnapshot();
4453
+ errorSignal.set(snapshot.error);
4454
+ isLoadingSignal.set(snapshot.isLoading);
4455
+ reportSignal.set(snapshot.report);
4456
+ updatedAtSignal.set(snapshot.updatedAt);
4457
+ };
4458
+ const unsubscribe = store.subscribe(sync);
4459
+ sync();
4460
+ store.refresh().catch(() => {});
4461
+ return {
4462
+ close: () => {
4463
+ unsubscribe();
4464
+ store.close();
4465
+ },
4466
+ error: computed22(() => errorSignal()),
4467
+ isLoading: computed22(() => isLoadingSignal()),
4468
+ refresh: store.refresh,
4469
+ report: computed22(() => reportSignal()),
4470
+ runProof: store.runProof,
4471
+ updatedAt: computed22(() => updatedAtSignal())
4472
+ };
4473
+ }
4474
+ }
4475
+ VoiceTurnLatencyService = __decorateElement(_init, 0, "VoiceTurnLatencyService", _dec, VoiceTurnLatencyService);
4476
+ __runInitializers(_init, 1, VoiceTurnLatencyService);
4477
+ __decoratorMetadata(_init, VoiceTurnLatencyService);
4478
+ let _VoiceTurnLatencyService = VoiceTurnLatencyService;
4479
+ // src/angular/voice-turn-quality.service.ts
4480
+ import { computed as computed23, Injectable as Injectable24, signal as signal24 } from "@angular/core";
4481
+
4482
+ // src/client/turnQuality.ts
4483
+ var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
4484
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4485
+ const response = await fetchImpl(path);
4486
+ if (!response.ok) {
4487
+ throw new Error(`Voice turn quality failed: HTTP ${response.status}`);
4488
+ }
4489
+ return await response.json();
4490
+ };
4491
+ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) => {
4492
+ const listeners = new Set;
4493
+ let closed = false;
4494
+ let timer;
4495
+ let snapshot = {
4496
+ error: null,
4497
+ isLoading: false
4498
+ };
4499
+ const emit = () => {
4500
+ for (const listener of listeners) {
4501
+ listener();
4502
+ }
4503
+ };
4504
+ const refresh = async () => {
4505
+ if (closed) {
4506
+ return snapshot.report;
4507
+ }
4508
+ snapshot = {
4509
+ ...snapshot,
4510
+ error: null,
4511
+ isLoading: true
4512
+ };
4513
+ emit();
4514
+ try {
4515
+ const report = await fetchVoiceTurnQuality(path, options);
4516
+ snapshot = {
4517
+ error: null,
4518
+ isLoading: false,
4519
+ report,
4520
+ updatedAt: Date.now()
4521
+ };
4522
+ emit();
4523
+ return report;
4524
+ } catch (error) {
4525
+ snapshot = {
4526
+ ...snapshot,
4527
+ error: error instanceof Error ? error.message : String(error),
4528
+ isLoading: false
4529
+ };
4530
+ emit();
4531
+ throw error;
4532
+ }
4533
+ };
4534
+ const close = () => {
4535
+ closed = true;
4536
+ if (timer) {
4537
+ clearInterval(timer);
4538
+ timer = undefined;
4539
+ }
4540
+ listeners.clear();
4541
+ };
4542
+ if (options.intervalMs && options.intervalMs > 0) {
4543
+ timer = setInterval(() => {
4544
+ refresh().catch(() => {});
4545
+ }, options.intervalMs);
4546
+ }
4547
+ return {
4548
+ close,
4549
+ getServerSnapshot: () => snapshot,
4550
+ getSnapshot: () => snapshot,
4551
+ refresh,
4552
+ subscribe: (listener) => {
4553
+ listeners.add(listener);
4554
+ return () => {
4555
+ listeners.delete(listener);
4556
+ };
4557
+ }
4558
+ };
4559
+ };
4560
+
4561
+ // src/angular/voice-turn-quality.service.ts
4562
+ var _dec = [
4563
+ Injectable24({ providedIn: "root" })
4564
+ ];
4565
+ var _init = __decoratorStart(undefined);
4566
+
4567
+ class VoiceTurnQualityService {
4568
+ connect(path = "/api/turn-quality", options = {}) {
4569
+ const store = createVoiceTurnQualityStore(path, options);
4570
+ const errorSignal = signal24(null);
4571
+ const isLoadingSignal = signal24(false);
4572
+ const reportSignal = signal24(undefined);
4573
+ const updatedAtSignal = signal24(undefined);
4574
+ const sync = () => {
4575
+ const snapshot = store.getSnapshot();
4576
+ errorSignal.set(snapshot.error);
4577
+ isLoadingSignal.set(snapshot.isLoading);
4578
+ reportSignal.set(snapshot.report);
4579
+ updatedAtSignal.set(snapshot.updatedAt);
4580
+ };
4581
+ const unsubscribe = store.subscribe(sync);
4582
+ sync();
4583
+ store.refresh().catch(() => {});
4584
+ return {
4585
+ close: () => {
4586
+ unsubscribe();
4587
+ store.close();
4588
+ },
4589
+ error: computed23(() => errorSignal()),
4590
+ isLoading: computed23(() => isLoadingSignal()),
4591
+ refresh: store.refresh,
4592
+ report: computed23(() => reportSignal()),
4593
+ updatedAt: computed23(() => updatedAtSignal())
4594
+ };
4595
+ }
4596
+ }
4597
+ VoiceTurnQualityService = __decorateElement(_init, 0, "VoiceTurnQualityService", _dec, VoiceTurnQualityService);
4598
+ __runInitializers(_init, 1, VoiceTurnQualityService);
4599
+ __decoratorMetadata(_init, VoiceTurnQualityService);
4600
+ let _VoiceTurnQualityService = VoiceTurnQualityService;
4601
+ // src/angular/voice-workflow-status.service.ts
4602
+ import { computed as computed24, Injectable as Injectable25, signal as signal25 } from "@angular/core";
4603
+
4604
+ // src/client/workflowStatus.ts
4605
+ var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
4606
+ const fetchImpl = options.fetch ?? globalThis.fetch;
4607
+ const response = await fetchImpl(path);
4608
+ if (!response.ok) {
4609
+ throw new Error(`Voice workflow status failed: HTTP ${response.status}`);
4610
+ }
4611
+ return await response.json();
4612
+ };
4613
+ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options = {}) => {
4614
+ const listeners = new Set;
4615
+ let closed = false;
4616
+ let timer;
4617
+ let snapshot = {
4618
+ error: null,
4619
+ isLoading: false
4620
+ };
4621
+ const emit = () => {
4622
+ for (const listener of listeners) {
4623
+ listener();
4624
+ }
4625
+ };
4626
+ const refresh = async () => {
4627
+ if (closed) {
4628
+ return snapshot.report;
4629
+ }
4630
+ snapshot = {
4631
+ ...snapshot,
4632
+ error: null,
4633
+ isLoading: true
4634
+ };
4635
+ emit();
4636
+ try {
4637
+ const report = await fetchVoiceWorkflowStatus(path, options);
4638
+ snapshot = {
4639
+ error: null,
4640
+ isLoading: false,
4641
+ report,
4642
+ updatedAt: Date.now()
4643
+ };
4644
+ emit();
4645
+ return report;
4646
+ } catch (error) {
4647
+ snapshot = {
4648
+ ...snapshot,
4649
+ error: error instanceof Error ? error.message : String(error),
4650
+ isLoading: false
4651
+ };
4652
+ emit();
4653
+ throw error;
4654
+ }
4655
+ };
4656
+ const close = () => {
4657
+ closed = true;
4658
+ if (timer) {
4659
+ clearInterval(timer);
4660
+ timer = undefined;
4661
+ }
4662
+ listeners.clear();
4663
+ };
4664
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
4665
+ timer = setInterval(() => {
4666
+ refresh().catch(() => {});
4667
+ }, options.intervalMs);
4668
+ }
4669
+ return {
4670
+ close,
4671
+ getServerSnapshot: () => snapshot,
4672
+ getSnapshot: () => snapshot,
4673
+ refresh,
4674
+ subscribe: (listener) => {
4675
+ listeners.add(listener);
4676
+ return () => {
4677
+ listeners.delete(listener);
4678
+ };
4679
+ }
4680
+ };
4681
+ };
4682
+
4683
+ // src/angular/voice-workflow-status.service.ts
4684
+ var _dec = [
4685
+ Injectable25({ providedIn: "root" })
4686
+ ];
4687
+ var _init = __decoratorStart(undefined);
4688
+
4689
+ class VoiceWorkflowStatusService {
4690
+ connect(path = "/evals/scenarios/json", options = {}) {
4691
+ const store = createVoiceWorkflowStatusStore(path, options);
4692
+ const errorSignal = signal25(null);
4693
+ const isLoadingSignal = signal25(false);
4694
+ const reportSignal = signal25(undefined);
4695
+ const updatedAtSignal = signal25(undefined);
4696
+ const sync = () => {
4697
+ const snapshot = store.getSnapshot();
4698
+ errorSignal.set(snapshot.error);
4699
+ isLoadingSignal.set(snapshot.isLoading);
4700
+ reportSignal.set(snapshot.report);
4701
+ updatedAtSignal.set(snapshot.updatedAt);
4702
+ };
4703
+ const unsubscribe = store.subscribe(sync);
4704
+ sync();
4705
+ if (typeof window !== "undefined") {
4706
+ store.refresh().catch(() => {});
4707
+ }
4708
+ return {
4709
+ close: () => {
4710
+ unsubscribe();
4711
+ store.close();
4712
+ },
4713
+ error: computed24(() => errorSignal()),
4714
+ isLoading: computed24(() => isLoadingSignal()),
4715
+ refresh: store.refresh,
4716
+ report: computed24(() => reportSignal()),
4717
+ updatedAt: computed24(() => updatedAtSignal())
4718
+ };
4719
+ }
4720
+ }
1704
4721
  VoiceWorkflowStatusService = __decorateElement(_init, 0, "VoiceWorkflowStatusService", _dec, VoiceWorkflowStatusService);
1705
4722
  __runInitializers(_init, 1, VoiceWorkflowStatusService);
1706
4723
  __decoratorMetadata(_init, VoiceWorkflowStatusService);
1707
4724
  let _VoiceWorkflowStatusService = VoiceWorkflowStatusService;
1708
4725
  export {
1709
4726
  VoiceWorkflowStatusService,
4727
+ VoiceWidgetService,
4728
+ VoiceTurnQualityService,
4729
+ VoiceTurnLatencyService,
4730
+ VoiceTraceTimelineService,
1710
4731
  VoiceStreamService,
4732
+ VoiceSessionSnapshotService,
4733
+ VoiceSessionObservabilityService,
4734
+ VoiceRoutingStatusService,
4735
+ VoiceReconnectProfileEvidenceService,
4736
+ VoiceReadinessFailuresService,
1711
4737
  VoiceProviderStatusService,
4738
+ VoiceProviderContractsService,
4739
+ VoiceProviderCapabilitiesService,
4740
+ VoiceProofTrendsService,
4741
+ VoiceProfileComparisonService,
4742
+ VoicePlatformCoverageService,
4743
+ VoiceOpsStatusService,
4744
+ VoiceOpsActionCenterService,
4745
+ VoiceLiveOpsService,
4746
+ VoiceDeliveryRuntimeService,
1712
4747
  VoiceControllerService,
1713
- VoiceAppKitStatusService
4748
+ VoiceCampaignDialerProofService,
4749
+ VoiceCallDebuggerService,
4750
+ VoiceAgentSquadStatusService
1714
4751
  };