@absolutejs/voice 0.0.22-beta.306 → 0.0.22-beta.307

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3471,15 +3471,16 @@ app.use(
3471
3471
 
3472
3472
  Client state now exposes `assistantAudio` on the stream/controller helpers, so apps can buffer or play synthesized chunks without inventing a second transport.
3473
3473
 
3474
- ## OpenAI Realtime
3474
+ ## Realtime Adapter Packages
3475
3475
 
3476
- Use `createOpenAIRealtimeAdapter(...)` when you want a direct OpenAI Realtime speech-to-speech output path for live smoke tests, duplex benchmarks, or custom realtime orchestration. It implements the same `RealtimeAdapter` contract used by the benchmark harness, so the provider can stream `response.output_audio.delta` audio chunks into AbsoluteJS voice events while still emitting normalized transcript, error, and close events.
3476
+ Use realtime adapter packages when you want direct speech-to-speech output paths for live smoke tests, duplex benchmarks, or custom realtime orchestration. Core owns the `RealtimeAdapter` contract and `voice({ realtime })` orchestration path; provider protocol code lives in adapter packages such as `@absolutejs/voice-openai` and `@absolutejs/voice-gemini`.
3477
3477
 
3478
3478
  ```ts
3479
- import { createOpenAIRealtimeAdapter } from '@absolutejs/voice';
3479
+ import { voice } from '@absolutejs/voice';
3480
+ import { openai } from '@absolutejs/voice-openai';
3480
3481
  import { runTTSAdapterFixture } from '@absolutejs/voice/testing';
3481
3482
 
3482
- const realtime = createOpenAIRealtimeAdapter({
3483
+ const realtime = openai({
3483
3484
  apiKey: process.env.OPENAI_API_KEY!,
3484
3485
  instructions: 'Answer in one concise sentence.',
3485
3486
  model: 'gpt-realtime',
@@ -3522,7 +3523,33 @@ const report = await runTTSAdapterFixture(
3522
3523
  );
3523
3524
  ```
3524
3525
 
3525
- For server-to-server use, the adapter opens a WebSocket to OpenAI, sends `session.update`, streams text or base64 PCM input, and emits raw 24kHz mono `pcm_s16le` assistant audio. It requires raw 24kHz mono PCM input because that is the OpenAI Realtime PCM format. The main `voice(...)` route can now run in cascaded mode with `stt` plus optional `tts`, or direct realtime mode with `realtime`. Browser demos should make sure the captured PCM format matches `realtimeInputFormat` or resample before sending audio.
3526
+ For server-to-server use, realtime adapters open provider-specific streaming connections, send session configuration, stream text or PCM input, and emit normalized transcript/audio/error/close events. OpenAI Realtime uses raw 24kHz mono `pcm_s16le` audio. The main `voice(...)` route can run in cascaded mode with `stt` plus optional `tts`, or direct realtime mode with `realtime`. Browser demos should make sure the captured PCM format matches `realtimeInputFormat` or resample before sending audio.
3527
+
3528
+ Use `createVoiceRealtimeProviderContractMatrixPreset(...)` to prove which realtime providers are production-ready. Pipecat is represented as an explicit bridge seam by default, not core-owned media infrastructure:
3529
+
3530
+ ```ts
3531
+ import {
3532
+ createVoiceRealtimeProviderContractMatrixPreset,
3533
+ createVoiceRealtimeProviderContractRoutes
3534
+ } from '@absolutejs/voice';
3535
+
3536
+ app.use(
3537
+ createVoiceRealtimeProviderContractRoutes({
3538
+ matrix: createVoiceRealtimeProviderContractMatrixPreset({
3539
+ env: process.env,
3540
+ fallbackProviders: {
3541
+ 'gemini-live': ['openai-realtime'],
3542
+ 'openai-realtime': ['gemini-live']
3543
+ },
3544
+ latencyBudgets: {
3545
+ 'gemini-live': 900,
3546
+ 'openai-realtime': 800
3547
+ },
3548
+ selected: 'openai-realtime'
3549
+ })
3550
+ })
3551
+ );
3552
+ ```
3526
3553
 
3527
3554
  If you want a minimal browser playback path, use the client audio player:
3528
3555
 
package/dist/index.d.ts CHANGED
@@ -12,8 +12,8 @@ export { createVoiceBargeInRoutes, renderVoiceBargeInHTML, summarizeVoiceBargeIn
12
12
  export { createVoiceReconnectContractRoutes, renderVoiceReconnectContractHTML, summarizeVoiceReconnectContractSnapshots, runVoiceReconnectContract } from './reconnectContract';
13
13
  export { assertVoiceRealtimeChannelEvidence, buildVoiceRealtimeChannelRuntimeSamplesFromTrace, buildVoiceRealtimeChannelReport, createVoiceRealtimeChannelRoutes, evaluateVoiceRealtimeChannelEvidence, renderVoiceRealtimeChannelHTML, renderVoiceRealtimeChannelMarkdown } from './realtimeChannel';
14
14
  export type { VoiceRealtimeChannelAssertionInput, VoiceRealtimeChannelAssertionReport, VoiceRealtimeChannelBrowserCapture, VoiceRealtimeChannelIssue, VoiceRealtimeChannelReport, VoiceRealtimeChannelReportOptions, VoiceRealtimeChannelRoutesOptions, VoiceRealtimeChannelRuntimeSample, VoiceRealtimeChannelStatus } from './realtimeChannel';
15
- export { assertVoiceRealtimeProviderContractEvidence, buildVoiceRealtimeProviderContractMatrix, createVoiceRealtimeProviderContractRoutes, evaluateVoiceRealtimeProviderContractEvidence, renderVoiceRealtimeProviderContractHTML } from './realtimeProviderContracts';
16
- export type { VoiceRealtimeProviderContractAssertionInput, VoiceRealtimeProviderContractAssertionReport, VoiceRealtimeProviderContractCapability, VoiceRealtimeProviderContractCheck, VoiceRealtimeProviderContractDefinition, VoiceRealtimeProviderContractMatrixInput, VoiceRealtimeProviderContractMatrixReport, VoiceRealtimeProviderContractRoutesOptions, VoiceRealtimeProviderContractRow, VoiceRealtimeProviderContractStatus } from './realtimeProviderContracts';
15
+ export { assertVoiceRealtimeProviderContractEvidence, buildVoiceRealtimeProviderContractMatrix, createVoiceRealtimeProviderContractMatrixPreset, createVoiceRealtimeProviderContractRoutes, evaluateVoiceRealtimeProviderContractEvidence, renderVoiceRealtimeProviderContractHTML } from './realtimeProviderContracts';
16
+ export type { VoiceRealtimeProviderContractAssertionInput, VoiceRealtimeProviderContractAssertionReport, VoiceRealtimeProviderContractCapability, VoiceRealtimeProviderContractCheck, VoiceRealtimeProviderContractDefinition, VoiceRealtimeProviderContractMatrixPresetOptions, VoiceRealtimeProviderContractMatrixInput, VoiceRealtimeProviderContractMatrixReport, VoiceRealtimeProviderContractRoutesOptions, VoiceRealtimeProviderContractRow, VoiceRealtimeProviderPresetProvider, VoiceRealtimeProviderContractStatus } from './realtimeProviderContracts';
17
17
  export { buildVoiceDiagnosticsMarkdown, createVoiceDiagnosticsRoutes, resolveVoiceDiagnosticsTraceFilter } from './diagnosticsRoutes';
18
18
  export { buildVoiceDemoReadyReport, createVoiceDemoReadyRoutes, renderVoiceDemoReadyHTML } from './demoReadyRoutes';
19
19
  export { buildVoiceDeliverySinkReport, createVoiceDeliverySinkDescriptor, createVoiceDeliverySinkPair, createVoiceDeliverySinkRoutes, createVoiceFileDeliverySink, createVoicePostgresDeliverySink, createVoiceS3DeliverySink, createVoiceSQLiteDeliverySink, createVoiceWebhookDeliverySink, renderVoiceDeliverySinkHTML } from './deliverySinkRoutes';
package/dist/index.js CHANGED
@@ -11256,6 +11256,11 @@ var defaultProviderEnv = {
11256
11256
  "openai-realtime": ["OPENAI_API_KEY"],
11257
11257
  "pipecat-bridge": []
11258
11258
  };
11259
+ var defaultRealtimeProviders = [
11260
+ "openai-realtime",
11261
+ "gemini-live",
11262
+ "pipecat-bridge"
11263
+ ];
11259
11264
  var statusRank = {
11260
11265
  pass: 0,
11261
11266
  warn: 1,
@@ -11264,6 +11269,34 @@ var statusRank = {
11264
11269
  var statusExceeds = (actual, max) => statusRank[actual] > statusRank[max];
11265
11270
  var rollupStatus = (checks) => checks.some((check) => check.status === "fail") ? "fail" : checks.some((check) => check.status === "warn") ? "warn" : "pass";
11266
11271
  var escapeHtml13 = (value) => String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11272
+ var resolveProviderHref = (value, provider) => typeof value === "string" ? value : value?.[provider];
11273
+ var createVoiceRealtimeProviderContractMatrixPreset = (options = {}) => {
11274
+ const providers = options.providers ?? defaultRealtimeProviders;
11275
+ const selected = options.selected ?? providers[0];
11276
+ return {
11277
+ contracts: providers.map((provider) => {
11278
+ const providerKey = String(provider);
11279
+ const requiredEnv = options.requiredEnv?.[providerKey] ?? defaultProviderEnv[providerKey] ?? [];
11280
+ const implementationStatus = options.implementationStatus?.[providerKey] ?? (providerKey === "pipecat-bridge" ? "planned" : "available");
11281
+ const configured = options.configured?.[providerKey] ?? (implementationStatus === "planned" ? false : requiredEnv.every((name) => Boolean(options.env?.[name])));
11282
+ return {
11283
+ capabilities: options.capabilities?.[providerKey] ?? defaultRequiredCapabilities,
11284
+ configured,
11285
+ env: options.env,
11286
+ fallbackProviders: options.fallbackProviders?.[providerKey],
11287
+ implementationStatus,
11288
+ latencyBudgetMs: options.latencyBudgets?.[providerKey],
11289
+ provider,
11290
+ readinessHref: resolveProviderHref(options.readinessHref, provider),
11291
+ realtimeChannel: options.realtimeChannels?.[providerKey],
11292
+ requiredCapabilities: options.requiredCapabilities?.[providerKey] ?? defaultRequiredCapabilities,
11293
+ requiredEnv,
11294
+ selected: provider === selected,
11295
+ traceHref: resolveProviderHref(options.traceHref, provider)
11296
+ };
11297
+ })
11298
+ };
11299
+ };
11267
11300
  var buildVoiceRealtimeProviderContractMatrix = (input) => {
11268
11301
  const rows = input.contracts.map((contract) => {
11269
11302
  const configured = contract.configured !== false;
@@ -34271,6 +34304,7 @@ export {
34271
34304
  createVoiceRedisIdempotencyStore,
34272
34305
  createVoiceReconnectContractRoutes,
34273
34306
  createVoiceRealtimeProviderContractRoutes,
34307
+ createVoiceRealtimeProviderContractMatrixPreset,
34274
34308
  createVoiceRealtimeChannelRoutes,
34275
34309
  createVoiceReadinessProfile,
34276
34310
  createVoiceQualityRoutes,
@@ -17,6 +17,22 @@ export type VoiceRealtimeProviderContractDefinition<TProvider extends string = s
17
17
  selected?: boolean;
18
18
  traceHref?: string;
19
19
  };
20
+ export type VoiceRealtimeProviderPresetProvider = 'gemini-live' | 'openai-realtime' | 'pipecat-bridge' | (string & {});
21
+ export type VoiceRealtimeProviderContractMatrixPresetOptions<TProvider extends string = VoiceRealtimeProviderPresetProvider> = {
22
+ capabilities?: Record<string, readonly VoiceRealtimeProviderContractCapability[]>;
23
+ configured?: Record<string, boolean>;
24
+ env?: Record<string, string | undefined>;
25
+ fallbackProviders?: Record<string, readonly TProvider[]>;
26
+ implementationStatus?: Record<string, 'available' | 'planned'>;
27
+ latencyBudgets?: Record<string, number>;
28
+ providers?: readonly TProvider[];
29
+ readinessHref?: string | Record<string, string | undefined>;
30
+ realtimeChannels?: Record<string, VoiceRealtimeChannelReport | undefined>;
31
+ requiredCapabilities?: Record<string, readonly VoiceRealtimeProviderContractCapability[]>;
32
+ requiredEnv?: Record<string, readonly string[]>;
33
+ selected?: TProvider;
34
+ traceHref?: string | Record<string, string | undefined>;
35
+ };
20
36
  export type VoiceRealtimeProviderContractCheck = {
21
37
  detail?: string;
22
38
  key: string;
@@ -70,6 +86,7 @@ export type VoiceRealtimeProviderContractRoutesOptions<TProvider extends string
70
86
  render?: (report: VoiceRealtimeProviderContractMatrixReport<TProvider>) => Promise<string> | string;
71
87
  title?: string;
72
88
  };
89
+ export declare const createVoiceRealtimeProviderContractMatrixPreset: <TProvider extends string = VoiceRealtimeProviderPresetProvider>(options?: VoiceRealtimeProviderContractMatrixPresetOptions<TProvider>) => VoiceRealtimeProviderContractMatrixInput<TProvider>;
73
90
  export declare const buildVoiceRealtimeProviderContractMatrix: <TProvider extends string = string>(input: VoiceRealtimeProviderContractMatrixInput<TProvider>) => VoiceRealtimeProviderContractMatrixReport<TProvider>;
74
91
  export declare const evaluateVoiceRealtimeProviderContractEvidence: <TProvider extends string = string>(report: VoiceRealtimeProviderContractMatrixReport<TProvider>, input?: VoiceRealtimeProviderContractAssertionInput<TProvider>) => VoiceRealtimeProviderContractAssertionReport<TProvider>;
75
92
  export declare const assertVoiceRealtimeProviderContractEvidence: <TProvider extends string = string>(report: VoiceRealtimeProviderContractMatrixReport<TProvider>, input?: VoiceRealtimeProviderContractAssertionInput<TProvider>) => VoiceRealtimeProviderContractAssertionReport<TProvider>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.306",
3
+ "version": "0.0.22-beta.307",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",