@absolutejs/voice 0.0.22-beta.12 → 0.0.22-beta.120

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 (146) hide show
  1. package/README.md +411 -3
  2. package/dist/agent.d.ts +2 -0
  3. package/dist/angular/index.d.ts +9 -0
  4. package/dist/angular/index.js +1278 -44
  5. package/dist/angular/voice-app-kit-status.service.d.ts +12 -0
  6. package/dist/angular/voice-campaign-dialer-proof.service.d.ts +14 -0
  7. package/dist/angular/voice-ops-status.component.d.ts +15 -0
  8. package/dist/angular/voice-provider-capabilities.service.d.ts +12 -0
  9. package/dist/angular/voice-provider-status.service.d.ts +12 -0
  10. package/dist/angular/voice-routing-status.service.d.ts +11 -0
  11. package/dist/angular/voice-stream.service.d.ts +2 -0
  12. package/dist/angular/voice-trace-timeline.service.d.ts +12 -0
  13. package/dist/angular/voice-turn-latency.service.d.ts +13 -0
  14. package/dist/angular/voice-turn-quality.service.d.ts +12 -0
  15. package/dist/angular/voice-workflow-status.service.d.ts +12 -0
  16. package/dist/appKit.d.ts +100 -0
  17. package/dist/assistantHealth.d.ts +81 -0
  18. package/dist/bargeInRoutes.d.ts +56 -0
  19. package/dist/campaign.d.ts +610 -0
  20. package/dist/campaignDialers.d.ts +90 -0
  21. package/dist/client/actions.d.ts +22 -0
  22. package/dist/client/appKitStatus.d.ts +19 -0
  23. package/dist/client/bargeInMonitor.d.ts +7 -0
  24. package/dist/client/campaignDialerProof.d.ts +23 -0
  25. package/dist/client/connection.d.ts +3 -0
  26. package/dist/client/duplex.d.ts +1 -1
  27. package/dist/client/htmxBootstrap.js +587 -13
  28. package/dist/client/index.d.ts +40 -0
  29. package/dist/client/index.js +2028 -8
  30. package/dist/client/liveTurnLatency.d.ts +41 -0
  31. package/dist/client/opsStatusWidget.d.ts +40 -0
  32. package/dist/client/providerCapabilities.d.ts +19 -0
  33. package/dist/client/providerCapabilitiesWidget.d.ts +32 -0
  34. package/dist/client/providerSimulationControls.d.ts +33 -0
  35. package/dist/client/providerSimulationControlsWidget.d.ts +20 -0
  36. package/dist/client/providerStatus.d.ts +19 -0
  37. package/dist/client/providerStatusWidget.d.ts +32 -0
  38. package/dist/client/routingStatus.d.ts +19 -0
  39. package/dist/client/routingStatusWidget.d.ts +28 -0
  40. package/dist/client/traceTimeline.d.ts +19 -0
  41. package/dist/client/traceTimelineWidget.d.ts +32 -0
  42. package/dist/client/turnLatency.d.ts +22 -0
  43. package/dist/client/turnLatencyWidget.d.ts +33 -0
  44. package/dist/client/turnQuality.d.ts +19 -0
  45. package/dist/client/turnQualityWidget.d.ts +32 -0
  46. package/dist/client/workflowStatus.d.ts +19 -0
  47. package/dist/diagnosticsRoutes.d.ts +44 -0
  48. package/dist/evalRoutes.d.ts +213 -0
  49. package/dist/fileStore.d.ts +3 -0
  50. package/dist/handoff.d.ts +54 -0
  51. package/dist/handoffHealth.d.ts +94 -0
  52. package/dist/index.d.ts +77 -8
  53. package/dist/index.js +12645 -3061
  54. package/dist/liveLatency.d.ts +78 -0
  55. package/dist/modelAdapters.d.ts +41 -2
  56. package/dist/openaiTTS.d.ts +18 -0
  57. package/dist/opsConsoleRoutes.d.ts +77 -0
  58. package/dist/opsWebhook.d.ts +126 -0
  59. package/dist/outcomeContract.d.ts +112 -0
  60. package/dist/phoneAgent.d.ts +58 -0
  61. package/dist/postgresStore.d.ts +5 -0
  62. package/dist/productionReadiness.d.ts +121 -0
  63. package/dist/providerAdapters.d.ts +48 -0
  64. package/dist/providerCapabilities.d.ts +92 -0
  65. package/dist/providerHealth.d.ts +79 -0
  66. package/dist/qualityRoutes.d.ts +76 -0
  67. package/dist/queue.d.ts +61 -0
  68. package/dist/react/VoiceOpsStatus.d.ts +6 -0
  69. package/dist/react/VoiceProviderCapabilities.d.ts +6 -0
  70. package/dist/react/VoiceProviderSimulationControls.d.ts +5 -0
  71. package/dist/react/VoiceProviderStatus.d.ts +6 -0
  72. package/dist/react/VoiceRoutingStatus.d.ts +6 -0
  73. package/dist/react/VoiceTraceTimeline.d.ts +6 -0
  74. package/dist/react/VoiceTurnLatency.d.ts +6 -0
  75. package/dist/react/VoiceTurnQuality.d.ts +6 -0
  76. package/dist/react/index.d.ts +18 -0
  77. package/dist/react/index.js +2606 -12
  78. package/dist/react/useVoiceAppKitStatus.d.ts +8 -0
  79. package/dist/react/useVoiceCampaignDialerProof.d.ts +10 -0
  80. package/dist/react/useVoiceController.d.ts +2 -0
  81. package/dist/react/useVoiceProviderCapabilities.d.ts +8 -0
  82. package/dist/react/useVoiceProviderSimulationControls.d.ts +10 -0
  83. package/dist/react/useVoiceProviderStatus.d.ts +8 -0
  84. package/dist/react/useVoiceRoutingStatus.d.ts +8 -0
  85. package/dist/react/useVoiceStream.d.ts +2 -0
  86. package/dist/react/useVoiceTraceTimeline.d.ts +8 -0
  87. package/dist/react/useVoiceTurnLatency.d.ts +9 -0
  88. package/dist/react/useVoiceTurnQuality.d.ts +8 -0
  89. package/dist/react/useVoiceWorkflowStatus.d.ts +8 -0
  90. package/dist/resilienceRoutes.d.ts +142 -0
  91. package/dist/sessionReplay.d.ts +175 -0
  92. package/dist/simulationSuite.d.ts +120 -0
  93. package/dist/sqliteStore.d.ts +5 -0
  94. package/dist/svelte/createVoiceAppKitStatus.d.ts +8 -0
  95. package/dist/svelte/createVoiceCampaignDialerProof.d.ts +9 -0
  96. package/dist/svelte/createVoiceOpsStatus.d.ts +9 -0
  97. package/dist/svelte/createVoiceProviderCapabilities.d.ts +10 -0
  98. package/dist/svelte/createVoiceProviderSimulationControls.d.ts +11 -0
  99. package/dist/svelte/createVoiceProviderStatus.d.ts +10 -0
  100. package/dist/svelte/createVoiceRoutingStatus.d.ts +10 -0
  101. package/dist/svelte/createVoiceTraceTimeline.d.ts +10 -0
  102. package/dist/svelte/createVoiceTurnLatency.d.ts +11 -0
  103. package/dist/svelte/createVoiceTurnQuality.d.ts +10 -0
  104. package/dist/svelte/createVoiceWorkflowStatus.d.ts +8 -0
  105. package/dist/svelte/index.d.ts +11 -0
  106. package/dist/svelte/index.js +1849 -4
  107. package/dist/telephony/contract.d.ts +61 -0
  108. package/dist/telephony/matrix.d.ts +97 -0
  109. package/dist/telephony/plivo.d.ts +254 -0
  110. package/dist/telephony/telnyx.d.ts +247 -0
  111. package/dist/telephony/twilio.d.ts +132 -0
  112. package/dist/telephonyOutcome.d.ts +201 -0
  113. package/dist/testing/index.d.ts +2 -0
  114. package/dist/testing/index.js +2640 -21
  115. package/dist/testing/ioProviderSimulator.d.ts +41 -0
  116. package/dist/testing/providerSimulator.d.ts +44 -0
  117. package/dist/toolContract.d.ts +130 -0
  118. package/dist/toolRuntime.d.ts +50 -0
  119. package/dist/trace.d.ts +1 -1
  120. package/dist/traceTimeline.d.ts +93 -0
  121. package/dist/turnLatency.d.ts +95 -0
  122. package/dist/turnQuality.d.ts +94 -0
  123. package/dist/types.d.ts +125 -2
  124. package/dist/vue/VoiceOpsStatus.d.ts +30 -0
  125. package/dist/vue/VoiceProviderCapabilities.d.ts +51 -0
  126. package/dist/vue/VoiceProviderSimulationControls.d.ts +88 -0
  127. package/dist/vue/VoiceProviderStatus.d.ts +51 -0
  128. package/dist/vue/VoiceRoutingStatus.d.ts +51 -0
  129. package/dist/vue/VoiceTurnLatency.d.ts +69 -0
  130. package/dist/vue/VoiceTurnQuality.d.ts +51 -0
  131. package/dist/vue/index.d.ts +17 -0
  132. package/dist/vue/index.js +2520 -29
  133. package/dist/vue/useVoiceAppKitStatus.d.ts +9 -0
  134. package/dist/vue/useVoiceCampaignDialerProof.d.ts +11 -0
  135. package/dist/vue/useVoiceController.d.ts +1 -1
  136. package/dist/vue/useVoiceProviderCapabilities.d.ts +9 -0
  137. package/dist/vue/useVoiceProviderSimulationControls.d.ts +24 -0
  138. package/dist/vue/useVoiceProviderStatus.d.ts +9 -0
  139. package/dist/vue/useVoiceRoutingStatus.d.ts +8 -0
  140. package/dist/vue/useVoiceStream.d.ts +3 -1
  141. package/dist/vue/useVoiceTraceTimeline.d.ts +9 -0
  142. package/dist/vue/useVoiceTurnLatency.d.ts +10 -0
  143. package/dist/vue/useVoiceTurnQuality.d.ts +9 -0
  144. package/dist/vue/useVoiceWorkflowStatus.d.ts +9 -0
  145. package/dist/workflowContract.d.ts +91 -0
  146. package/package.json +1 -1
package/README.md CHANGED
@@ -1,11 +1,48 @@
1
1
  # `@absolutejs/voice`
2
2
 
3
- `@absolutejs/voice` is the voice session layer for AbsoluteJS. It owns the duplex WebSocket lifecycle, transcript buffering, turn commits, reconnect behavior, and client primitives, while keeping speech vendors and session storage pluggable.
3
+ `@absolutejs/voice` is the self-hosted voice operations layer for AbsoluteJS.
4
+
5
+ It gives your app the primitives hosted voice platforms usually keep behind their dashboards: browser voice sessions, phone-call routes, provider routing, assistant tools, handoffs, traces, evals, production-readiness checks, latency proof, storage adapters, and framework-native UI helpers.
6
+
7
+ Use it when you want Vapi/Retell/Bland-style voice-agent capability, but you want the orchestration, data, traces, storage, and UI to live inside the AbsoluteJS server you already operate.
8
+
9
+ ## Why AbsoluteJS Voice
10
+
11
+ - Self-hosted by default: your app owns sessions, traces, reviews, tasks, handoffs, retention, and provider keys.
12
+ - Provider-neutral: use Deepgram, AssemblyAI, OpenAI, Anthropic, Gemini, ElevenLabs-style TTS, or your own adapters without rewriting app workflow code.
13
+ - Browser and phone surfaces: mount browser WebSocket voice routes plus Twilio, Telnyx, and Plivo telephony routes from the same package.
14
+ - Production proof: App Kit, production readiness, turn quality, turn latency, live browser p50/p95 latency, trace timelines, evals, fixtures, and contracts are package primitives.
15
+ - Framework parity: React, Vue, Svelte, Angular, HTML, HTMX, and plain client entrypoints share the same core behavior.
16
+ - No hosted platform tax: AbsoluteJS Voice does not add a mandatory per-minute orchestration fee between your app and your providers.
17
+
18
+ ## Start Here
19
+
20
+ Pick the path that matches what you are building:
21
+
22
+ - Browser voice agent: mount `voice(...)`, choose an STT adapter, and use the React/Vue/Svelte/Angular/HTML/HTMX client helpers for mic, transcript, reconnect, and status UI.
23
+ - Phone voice agent: mount Twilio, Telnyx, or Plivo routes, normalize carrier outcomes, inspect carrier readiness, and persist call lifecycle traces.
24
+ - Production readiness: mount `createVoiceAppKitRoutes(...)` to get ops console/status, quality, evals, provider health, sessions, handoffs, diagnostics, and readiness gates.
25
+ - Provider routing and fallback: use LLM/STT/TTS provider routers, provider health, provider simulation controls, and cost/latency-aware routing policies.
26
+ - Evals and simulation: mount `createVoiceSimulationSuiteRoutes(...)` to run scenario fixtures, workflow contracts, tool contracts, outcome contracts, baseline comparisons, and saved benchmark artifacts before live traffic.
27
+
28
+ ## How This Differs From Hosted Voice Platforms
29
+
30
+ Hosted voice-agent platforms are strongest when you want a managed dashboard, phone-number provisioning, hosted orchestration, and campaign tooling out of the box.
31
+
32
+ AbsoluteJS Voice is strongest when voice is part of your own product and you need code-owned primitives:
33
+
34
+ - Your app stores the call data instead of a vendor dashboard being the source of truth.
35
+ - Your app controls provider routing, fallback, retries, handoffs, and retention.
36
+ - Your team can inspect and extend every primitive.
37
+ - Your framework UI can render first-class voice state without iframe/dashboard handoffs.
38
+ - Your production checks and evals can run in CI, smoke tests, or your own admin UI.
39
+
40
+ The goal is not to clone a hosted platform. The goal is to make AbsoluteJS the best place to build and operate self-hosted voice products.
4
41
 
5
42
  ## Install
6
43
 
7
44
  ```bash
8
- bun add @absolutejs/voice
45
+ bun add @absolutejs/voice @absolutejs/voice-deepgram
9
46
  ```
10
47
 
11
48
  Peer dependencies:
@@ -21,7 +58,12 @@ Optional framework entrypoints:
21
58
  - `@absolutejs/voice/angular`
22
59
  - `@absolutejs/voice/client`
23
60
 
24
- ## Route Setup
61
+ Common optional adapters:
62
+
63
+ - `@absolutejs/voice-deepgram`
64
+ - `@absolutejs/voice-assemblyai`
65
+
66
+ ## Browser Voice Agent
25
67
 
26
68
  ```ts
27
69
  import { Elysia } from 'elysia';
@@ -73,6 +115,276 @@ const app = new Elysia()
73
115
 
74
116
  `createVoiceMemoryStore()` is dev-only. Real deployments should provide a shared store backed by Redis, Postgres, or equivalent.
75
117
 
118
+ ## Production Readiness Path
119
+
120
+ Once the basic route works, mount the App Kit. This gives you the self-hosted operational surface that hosted platforms usually make mandatory:
121
+
122
+ ```ts
123
+ import {
124
+ createVoiceAppKitRoutes,
125
+ createVoiceFileRuntimeStorage,
126
+ createVoiceLiveLatencyRoutes,
127
+ createVoiceProductionReadinessRoutes,
128
+ createVoiceTraceTimelineRoutes,
129
+ createVoiceTurnLatencyRoutes,
130
+ createVoiceTurnQualityRoutes
131
+ } from '@absolutejs/voice';
132
+
133
+ const runtime = createVoiceFileRuntimeStorage({
134
+ directory: '.voice-runtime/support'
135
+ });
136
+
137
+ app
138
+ .use(
139
+ createVoiceAppKitRoutes({
140
+ store: runtime.traces,
141
+ llmProviders: ['openai', 'anthropic', 'gemini'],
142
+ sttProviders: ['deepgram', 'assemblyai']
143
+ }).routes
144
+ )
145
+ .use(
146
+ createVoiceTurnLatencyRoutes({
147
+ htmlPath: '/turn-latency',
148
+ path: '/api/turn-latency',
149
+ store: runtime.session,
150
+ traceStore: runtime.traces
151
+ })
152
+ )
153
+ .use(
154
+ createVoiceLiveLatencyRoutes({
155
+ htmlPath: '/live-latency',
156
+ path: '/api/live-latency',
157
+ store: runtime.traces
158
+ })
159
+ )
160
+ .use(
161
+ createVoiceTurnQualityRoutes({
162
+ htmlPath: '/turn-quality',
163
+ path: '/api/turn-quality',
164
+ store: runtime.session
165
+ })
166
+ )
167
+ .use(
168
+ createVoiceTraceTimelineRoutes({
169
+ htmlPath: '/traces',
170
+ path: '/api/voice-traces',
171
+ store: runtime.traces
172
+ })
173
+ )
174
+ .use(
175
+ createVoiceProductionReadinessRoutes({
176
+ htmlPath: '/production-readiness',
177
+ path: '/api/production-readiness',
178
+ store: runtime.traces
179
+ })
180
+ );
181
+ ```
182
+
183
+ Recommended proof routes:
184
+
185
+ - `/app-kit/status`: compact customer-facing app status.
186
+ - `/production-readiness`: production gate summary.
187
+ - `/traces`: per-session trace timelines.
188
+ - `/turn-latency`: server-side turn-stage latency.
189
+ - `/live-latency`: browser-measured speech-to-assistant p50/p95 latency.
190
+ - `/turn-quality`: STT confidence, correction, fallback, and transcript diagnostics.
191
+
192
+ ## Simulation Suite Path
193
+
194
+ Use `createVoiceSimulationSuiteRoutes(...)` when you want one pre-production proof surface for the things that usually live in separate dashboards or scripts:
195
+
196
+ ```ts
197
+ import {
198
+ createVoiceSimulationSuiteRoutes,
199
+ createVoiceFileRuntimeStorage
200
+ } from '@absolutejs/voice';
201
+
202
+ const runtime = createVoiceFileRuntimeStorage({
203
+ directory: '.voice-runtime/support'
204
+ });
205
+
206
+ app.use(
207
+ createVoiceSimulationSuiteRoutes({
208
+ htmlPath: '/voice/simulations',
209
+ path: '/api/voice/simulations',
210
+ store: runtime.traces,
211
+ scenarios: workflowScenarios,
212
+ fixtureStore: scenarioFixtureStore,
213
+ tools: toolContracts,
214
+ outcomes: {
215
+ contracts: outcomeContracts,
216
+ events: runtime.events,
217
+ reviews: runtime.reviews,
218
+ sessions: runtime.session,
219
+ tasks: runtime.tasks
220
+ }
221
+ })
222
+ );
223
+ ```
224
+
225
+ The suite rolls up session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts into one pass/fail report. It is the code-owned equivalent of "test this voice flow before production" without requiring a hosted voice-agent dashboard.
226
+
227
+ ## Phone Voice Agent Path
228
+
229
+ Use the telephony primitives when the agent needs to answer or place calls through your own carrier account:
230
+
231
+ ```ts
232
+ import {
233
+ createVoicePhoneAgent,
234
+ createVoiceTelephonyOutcomePolicy
235
+ } from '@absolutejs/voice';
236
+ import { deepgram } from '@absolutejs/voice-deepgram';
237
+
238
+ const outcomePolicy = createVoiceTelephonyOutcomePolicy({
239
+ transferTarget: '+15551234567'
240
+ });
241
+
242
+ app
243
+ .use(
244
+ createVoicePhoneAgent({
245
+ matrix: {
246
+ path: '/api/carriers',
247
+ title: 'AbsoluteJS Voice Carrier Matrix'
248
+ },
249
+ carriers: [
250
+ {
251
+ provider: 'twilio',
252
+ options: {
253
+ context: {},
254
+ outcomePolicy,
255
+ session: runtime.session,
256
+ stt: deepgram({ apiKey: process.env.DEEPGRAM_API_KEY! }),
257
+ streamPath: '/api/voice/twilio/stream',
258
+ twiml: {
259
+ path: '/api/voice/twilio',
260
+ streamUrl: process.env.TWILIO_STREAM_URL
261
+ },
262
+ webhook: {
263
+ path: '/api/voice/twilio/webhook',
264
+ signingSecret: process.env.TWILIO_AUTH_TOKEN
265
+ },
266
+ async onTurn({ turn }) {
267
+ return { assistantText: `I heard: ${turn.text}` };
268
+ },
269
+ onComplete: async () => {}
270
+ }
271
+ }
272
+ ]
273
+ }).routes
274
+ );
275
+ ```
276
+
277
+ The wrapper mounts selected carrier routes and a readiness matrix. Telnyx and Plivo use the same wrapper with `{ provider: 'telnyx', options: ... }` or `{ provider: 'plivo', options: ... }`. The lower-level `createTwilioVoiceRoutes(...)`, `createTelnyxVoiceRoutes(...)`, and `createPlivoVoiceRoutes(...)` helpers remain available when you need carrier-specific control.
278
+
279
+ ## App Kit And Status Widgets
280
+
281
+ Use `createVoiceAppKitRoutes(...)` when you want a self-hosted operations surface without hand-wiring every dashboard route. It adds the ops console, quality gates, eval routes, provider health, session replay, handoff health, diagnostics, and `GET /app-kit/status`.
282
+
283
+ ```ts
284
+ import { createVoiceAppKitRoutes, createVoiceFileRuntimeStorage } from '@absolutejs/voice';
285
+
286
+ const runtime = createVoiceFileRuntimeStorage({ directory: '.voice-runtime/support' });
287
+
288
+ app.use(
289
+ createVoiceAppKitRoutes({
290
+ store: runtime.traces,
291
+ llmProviders: ['openai', 'anthropic', 'gemini'],
292
+ sttProviders: ['deepgram', 'assemblyai']
293
+ }).routes
294
+ );
295
+ ```
296
+
297
+ The status endpoint is intentionally small enough for customer-facing demos. It can report fixture-backed workflow readiness while leaving deeper live quality/session failures visible on the ops pages.
298
+
299
+ ```ts
300
+ app.use(
301
+ createVoiceAppKitRoutes({
302
+ appStatus: {
303
+ include: { quality: false, sessions: false },
304
+ preferFixtureWorkflows: true
305
+ },
306
+ evals: { fixtures: certificationFixtures, scenarios: workflowScenarios },
307
+ store: runtime.traces
308
+ }).routes
309
+ );
310
+ ```
311
+
312
+ ### React Status Widget
313
+
314
+ ```tsx
315
+ import { VoiceOpsStatus } from '@absolutejs/voice/react';
316
+
317
+ export function OpsBadge() {
318
+ return <VoiceOpsStatus intervalMs={5000} />;
319
+ }
320
+ ```
321
+
322
+ ### Vue Status Widget
323
+
324
+ ```vue
325
+ <script setup lang="ts">
326
+ import { VoiceOpsStatus } from '@absolutejs/voice/vue';
327
+ </script>
328
+
329
+ <template>
330
+ <VoiceOpsStatus :interval-ms="5000" />
331
+ </template>
332
+ ```
333
+
334
+ ### Svelte Status Widget
335
+
336
+ ```svelte
337
+ <script lang="ts">
338
+ import { onDestroy, onMount } from 'svelte';
339
+ import { createVoiceOpsStatus } from '@absolutejs/voice/svelte';
340
+
341
+ const status = createVoiceOpsStatus('/app-kit/status', { intervalMs: 5000 });
342
+ let html = '';
343
+ onMount(() => status.subscribe(() => (html = status.getHTML())));
344
+ onDestroy(() => status.close());
345
+ </script>
346
+
347
+ {@html html}
348
+ ```
349
+
350
+ ### Angular Status Widget
351
+
352
+ ```ts
353
+ import { VoiceAppKitStatusService } from '@absolutejs/voice/angular';
354
+
355
+ status = inject(VoiceAppKitStatusService).connect('/app-kit/status', {
356
+ intervalMs: 5000
357
+ });
358
+ ```
359
+
360
+ ```html
361
+ <h2>{{ status.report()?.status === 'pass' ? 'Passing' : 'Needs attention' }}</h2>
362
+ <p>{{ status.report()?.passed ?? 0 }} passing checks</p>
363
+ ```
364
+
365
+ ### HTML Or HTMX Status Widget
366
+
367
+ ```html
368
+ <div id="voice-ops-status"></div>
369
+ <script type="module">
370
+ import { mountVoiceOpsStatus } from '@absolutejs/voice/client';
371
+
372
+ mountVoiceOpsStatus(document.querySelector('#voice-ops-status'), '/app-kit/status', {
373
+ intervalMs: 5000
374
+ });
375
+ </script>
376
+ ```
377
+
378
+ For custom elements:
379
+
380
+ ```html
381
+ <absolute-voice-ops-status interval-ms="5000"></absolute-voice-ops-status>
382
+ <script type="module">
383
+ import { defineVoiceOpsStatusElement } from '@absolutejs/voice/client';
384
+ defineVoiceOpsStatusElement();
385
+ </script>
386
+ ```
387
+
76
388
  ## Voice Assistants
77
389
 
78
390
  Use `createVoiceAssistant(...)` when you want one product-level surface for a voice agent instead of wiring tools, guardrails, experiments, traces, and ops recipes separately. It returns a standard `onTurn` handler, plus an `ops` object you can pass to `voice(...)`.
@@ -1069,6 +1381,102 @@ app.use(
1069
1381
  - `benchmark-results/sessions-cheap-stt-runs-3.json`
1070
1382
  - `benchmark-results/stt-routing-run-manifest.json`
1071
1383
 
1384
+ ## LLM Provider Routing
1385
+
1386
+ Use `createVoiceProviderRouter(...)` when your assistant can run on more than one LLM provider. The router keeps provider choice inside your app: you define the available model adapters, profile each provider, and choose a policy.
1387
+
1388
+ ```ts
1389
+ import {
1390
+ createAnthropicVoiceAssistantModel,
1391
+ createGeminiVoiceAssistantModel,
1392
+ createOpenAIVoiceAssistantModel,
1393
+ createVoiceProviderRouter,
1394
+ resolveVoiceProviderRoutingPolicyPreset
1395
+ } from '@absolutejs/voice';
1396
+
1397
+ const model = createVoiceProviderRouter({
1398
+ providers: {
1399
+ openai: createOpenAIVoiceAssistantModel({ apiKey: process.env.OPENAI_API_KEY! }),
1400
+ anthropic: createAnthropicVoiceAssistantModel({ apiKey: process.env.ANTHROPIC_API_KEY! }),
1401
+ gemini: createGeminiVoiceAssistantModel({ apiKey: process.env.GEMINI_API_KEY! })
1402
+ },
1403
+ providerHealth: {
1404
+ failureThreshold: 1,
1405
+ cooldownMs: 30_000,
1406
+ rateLimitCooldownMs: 120_000
1407
+ },
1408
+ providerProfiles: {
1409
+ openai: { cost: 6, latencyMs: 650, quality: 0.92, timeoutMs: 3500 },
1410
+ anthropic: { cost: 7, latencyMs: 850, quality: 0.95, timeoutMs: 4500 },
1411
+ gemini: { cost: 2, latencyMs: 700, quality: 0.86, timeoutMs: 3500 }
1412
+ },
1413
+ policy: resolveVoiceProviderRoutingPolicyPreset('balanced')
1414
+ });
1415
+ ```
1416
+
1417
+ Built-in policy presets:
1418
+
1419
+ - `quality-first`: rank by `providerProfiles[provider].quality`, then priority, latency, and cost.
1420
+ - `latency-first`: rank by expected latency.
1421
+ - `cost-first`: rank by expected cost.
1422
+ - `cost-cap`: rank by cost and reject providers above `maxCost`.
1423
+ - `balanced`: weighted score using cost, latency, quality, and priority.
1424
+
1425
+ Budget filters are strict. If you pass `maxCost`, `maxLatencyMs`, or `minQuality`, providers outside those limits are removed before ranking, even if they were selected by the request.
1426
+
1427
+ ```ts
1428
+ const policy = resolveVoiceProviderRoutingPolicyPreset('cost-cap', {
1429
+ maxCost: 3,
1430
+ minQuality: 0.82
1431
+ });
1432
+ ```
1433
+
1434
+ For full control, pass an object policy:
1435
+
1436
+ ```ts
1437
+ const model = createVoiceProviderRouter({
1438
+ providers,
1439
+ providerProfiles,
1440
+ policy: {
1441
+ strategy: 'balanced',
1442
+ maxLatencyMs: 1000,
1443
+ weights: { cost: 1, latencyMs: 0.004, quality: 12 }
1444
+ }
1445
+ });
1446
+ ```
1447
+
1448
+ The same profile and policy shape also works for STT and TTS provider routers, so a self-hosted app can choose the fastest provider for live calls, cap cost for background work, or require a minimum quality score without hard-coding provider branches.
1449
+
1450
+ ```ts
1451
+ const stt = createVoiceSTTProviderRouter({
1452
+ adapters: {
1453
+ deepgram,
1454
+ assemblyai
1455
+ },
1456
+ providerHealth: { cooldownMs: 30_000 },
1457
+ providerProfiles: {
1458
+ deepgram: { cost: 4, latencyMs: 180, quality: 0.93, timeoutMs: 1500 },
1459
+ assemblyai: { cost: 2, latencyMs: 650, quality: 0.88, timeoutMs: 3000 }
1460
+ },
1461
+ policy: resolveVoiceProviderRoutingPolicyPreset('latency-first')
1462
+ });
1463
+
1464
+ const tts = createVoiceTTSProviderRouter({
1465
+ adapters: {
1466
+ elevenlabs,
1467
+ openai
1468
+ },
1469
+ providerProfiles: {
1470
+ elevenlabs: { cost: 5, latencyMs: 220, quality: 0.94 },
1471
+ openai: { cost: 2, latencyMs: 320, quality: 0.87 }
1472
+ },
1473
+ policy: resolveVoiceProviderRoutingPolicyPreset('cost-cap', {
1474
+ maxCost: 3,
1475
+ minQuality: 0.85
1476
+ })
1477
+ });
1478
+ ```
1479
+
1072
1480
  ## Presets
1073
1481
 
1074
1482
  Voice now ships named runtime presets so apps can start from a useful baseline instead of hand-tuning silence and capture settings every time.
package/dist/agent.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { VoiceOnTurnObjectHandler, VoiceRouteResult, VoiceSessionHandle, VoiceSessionRecord, VoiceTurnRecord } from './types';
2
2
  import type { VoiceTraceEventStore } from './trace';
3
+ import type { VoiceToolRuntime } from './toolRuntime';
3
4
  export type VoiceAgentMessageRole = 'assistant' | 'system' | 'tool' | 'user';
4
5
  export type VoiceAgentMessage = {
5
6
  content: string;
@@ -86,6 +87,7 @@ export type VoiceAgentOptions<TContext = unknown, TSession extends VoiceSessionR
86
87
  turn: VoiceTurnRecord;
87
88
  }) => Promise<string | undefined> | string | undefined);
88
89
  trace?: VoiceTraceEventStore;
90
+ toolRuntime?: VoiceToolRuntime<TContext, TSession, TResult>;
89
91
  tools?: Array<VoiceAgentTool<TContext, TSession, Record<string, unknown>, unknown, TResult>>;
90
92
  };
91
93
  export type VoiceAgentSquadOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
@@ -1,2 +1,11 @@
1
+ export { VoiceAppKitStatusService } from './voice-app-kit-status.service';
2
+ export { VoiceCampaignDialerProofService } from './voice-campaign-dialer-proof.service';
1
3
  export { VoiceStreamService } from './voice-stream.service';
2
4
  export { VoiceControllerService } from './voice-controller.service';
5
+ export { VoiceProviderCapabilitiesService } from './voice-provider-capabilities.service';
6
+ export { VoiceProviderStatusService } from './voice-provider-status.service';
7
+ export { VoiceRoutingStatusService } from './voice-routing-status.service';
8
+ export { VoiceTraceTimelineService } from './voice-trace-timeline.service';
9
+ export { VoiceTurnLatencyService } from './voice-turn-latency.service';
10
+ export { VoiceTurnQualityService } from './voice-turn-quality.service';
11
+ export { VoiceWorkflowStatusService } from './voice-workflow-status.service';