voice-runtime 1.1.0 → 2.0.0

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/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import WebSocket from 'ws';
1
+ import * as WebSocket from 'ws';
2
+ import WebSocket__default from 'ws';
2
3
  import { IncomingMessage, ServerResponse } from 'node:http';
3
4
  import { AddressInfo } from 'node:net';
4
5
 
@@ -49,14 +50,8 @@ declare function counterIdGenerator<TId extends string = string>(prefix: string)
49
50
  declare function createDefaultIdGenerator(): IdGenerator;
50
51
 
51
52
  type ErrorCategory = "validation" | "auth" | "provider" | "network" | "timeout" | "rate_limit" | "cancelled" | "interrupted" | "tool" | "media" | "internal";
52
- /**
53
- * Canonical error names used on `NormalizedError.name` and by `tvicErrorFromJSON`
54
- * to identify errors after JSON round-trips (the `Symbol.for('tvic.error')`
55
- * marker on `TvicThrowableError` is lost in JSON).
56
- *
57
- * Frozen at module load so third parties cannot mutate the registry at
58
- * runtime.
59
- */
53
+ declare const MAX_ERROR_CODE_UTF8_BYTES = 128;
54
+ declare function isValidErrorCode(code: unknown): code is string;
60
55
  declare const TVIC_ERROR_NAMES: Readonly<{
61
56
  readonly AuthError: "AuthError";
62
57
  readonly RateLimitError: "RateLimitError";
@@ -75,11 +70,6 @@ declare const TVIC_ERROR_NAMES: Readonly<{
75
70
  }>;
76
71
  type TvicErrorName = (typeof TVIC_ERROR_NAMES)[keyof typeof TVIC_ERROR_NAMES];
77
72
  declare function isTvicErrorName(value: unknown): value is TvicErrorName;
78
- /**
79
- * The cross-realm marker for TVIC errors. Lives on the `TvicThrowableError`
80
- * class instance, not on `NormalizedError`, because `JSON.stringify` strips
81
- * symbol-keyed properties. Use `tvicErrorFromJSON()` to re-hydrate.
82
- */
83
73
  declare const TVIC_ERROR_MARKER: unique symbol;
84
74
  interface NormalizedError {
85
75
  readonly name: TvicErrorName;
@@ -100,20 +90,14 @@ interface ErrorFactoryOptions {
100
90
  }
101
91
  declare function isNormalizedError(value: unknown): value is NormalizedError;
102
92
  declare function unknownErrorMessage(error: unknown): string;
103
- /**
104
- * Recognizes the pre-v2 normalized shape that did not carry `name`, then
105
- * upgrades it to the canonical name for its category. This is deliberately
106
- * separate from `isNormalizedError`: new callers must still be able to tell
107
- * whether a value is already current, while compatibility boundaries can
108
- * preserve old provider/runtime errors instead of reclassifying them.
109
- */
110
- declare function normalizeLegacyError(value: unknown): NormalizedError | null;
111
- declare function normalizeUnknownError(error: unknown, options: {
93
+ type NormalizeUnknownErrorOptions = {
112
94
  readonly code: string;
113
95
  readonly category?: ErrorCategory;
114
96
  readonly provider?: string;
115
97
  readonly retriable?: boolean;
116
- }): NormalizedError;
98
+ };
99
+ declare function normalizeLegacyError(value: unknown): NormalizedError | null;
100
+ declare function normalizeUnknownError(error: unknown, options: NormalizeUnknownErrorOptions): NormalizedError;
117
101
  declare function normalizedError(code: string, message: string, options?: ErrorFactoryOptions): NormalizedError;
118
102
  declare function providerError(code: string, message: string, options?: Omit<ErrorFactoryOptions, "category">): NormalizedError;
119
103
  declare function mediaError(code: string, message?: string, options?: Omit<ErrorFactoryOptions, "category">): NormalizedError;
@@ -127,17 +111,6 @@ declare function signatureError(code: string, message: string, options?: Omit<Er
127
111
  declare function cancelledError(code: string, message: string, options?: Omit<ErrorFactoryOptions, "category" | "retriable">): NormalizedError;
128
112
  declare function interruptedError(code: string, message: string, options?: Omit<ErrorFactoryOptions, "category" | "retriable">): NormalizedError;
129
113
  declare function toolError(code: string, message: string, options?: Omit<ErrorFactoryOptions, "category">): NormalizedError;
130
- /**
131
- * A throwable Error that carries a `NormalizedError` and the cross-realm
132
- * `Symbol.for('tvic.error')` marker. Use `TvicThrowableError.from(value)`
133
- * to construct — it normalizes unknown values, preserves the original cause,
134
- * and reuses already-thrown `TvicThrowableError` instances.
135
- *
136
- * Note: the marker is lost in `JSON.stringify` because symbol-keyed
137
- * properties are dropped. Use `tvicErrorFromJSON()` to re-hydrate.
138
- * Error-like values from another realm in the same JavaScript agent are
139
- * recognized by their intrinsic Error tag, not only by `instanceof`.
140
- */
141
114
  declare class TvicThrowableError extends Error {
142
115
  readonly [TVIC_ERROR_MARKER]: true;
143
116
  readonly error: NormalizedError;
@@ -152,32 +125,9 @@ declare class TvicThrowableError extends Error {
152
125
  static from(value: unknown): TvicThrowableError;
153
126
  toJSON(): NormalizedError;
154
127
  }
155
- /**
156
- * Type guard that detects a `TvicThrowableError` instance *or* any object
157
- * that carries the cross-realm `Symbol.for('tvic.error')` marker. Works
158
- * across Web Workers, iframes, and `vm` contexts because `Symbol.for` is
159
- * the only symbol-sharing primitive within the same JavaScript agent. Separate
160
- * workers require JSON serialization or another explicit transport.
161
- *
162
- * The marker is an *identity tag*, not a security boundary: a hostile party
163
- * who can write into your realm can also fake the marker. The structural
164
- * companion to this guard is `isNormalizedError`, which checks the actual
165
- * `NormalizedError` field shape.
166
- *
167
- * Does NOT work across `JSON.parse` boundaries — use `tvicErrorFromJSON()`.
168
- */
128
+ declare function jsonSerializableNormalizedError(error: NormalizedError, transformString?: (value: string) => string): NormalizedError;
169
129
  declare function isTvicError(value: unknown): value is NormalizedError | TvicThrowableError;
170
- /**
171
- * Re-hydrate a `NormalizedError` after a `JSON.parse` round-trip. The
172
- * `Symbol.for('tvic.error')` marker is lost in JSON, so `isTvicError()`
173
- * returns `false` for parsed values. This factory validates the parsed
174
- * structural payload, including its canonical name/category pairing and
175
- * required field types.
176
- *
177
- * Returns `null` if the value cannot be re-hydrated to a valid
178
- * `NormalizedError` (unknown name, empty message, wrong field types).
179
- * Callers should always null-check the return value.
180
- */
130
+ declare function normalizedErrorFromTvicError(value: unknown): NormalizedError | null;
181
131
  declare function tvicErrorFromJSON(value: unknown): NormalizedError | null;
182
132
 
183
133
  type DurableErrorCode = "RECORD_NOT_FOUND" | "RECORD_CONFLICT" | "LEASE_UNAVAILABLE" | "LEASE_LOST" | "BACKEND_UNAVAILABLE" | "CORRUPT_RECORD" | "INVALID_ARGUMENT" | "MEMORY_BACKEND_UNAVAILABLE" | "MEMORY_ENTRY_TOO_LARGE" | "MEMORY_SESSION_QUOTA_EXCEEDED";
@@ -230,6 +180,9 @@ declare class MemorySessionQuotaExceededError extends DurableError {
230
180
  declare const TVIC_ERROR_CODES: Readonly<{
231
181
  readonly providerAuthFailed: "provider.auth_failed";
232
182
  readonly providerRateLimited: "provider.rate_limited";
183
+ readonly providerQuotaExceeded: "provider.quota_exceeded";
184
+ readonly providerTransportWriteFailed: "provider.transport_write_failed";
185
+ readonly providerTransportTimeout: "provider.transport_timeout";
233
186
  readonly providerModelUnsupported: "provider.model_unsupported";
234
187
  readonly providerVoiceUnsupported: "provider.voice_unsupported";
235
188
  readonly providerInputRejected: "provider.input_rejected";
@@ -247,11 +200,14 @@ declare const TVIC_ERROR_CODES: Readonly<{
247
200
  readonly ttsTransportUnexpectedEof: "tts.transport.unexpected_eof";
248
201
  readonly llmProviderUnexpectedEof: "llm.provider.unexpected_eof";
249
202
  }>;
250
- /** One-release aliases accepted at provider and persisted-data boundaries. */
203
+ /** Legacy aliases accepted at provider and persisted-data boundaries. */
251
204
  declare const TVIC_ERROR_CODE_ALIASES: Readonly<{
252
205
  readonly "stt.provider.auth_failed": "provider.auth_failed";
253
206
  readonly "stt.provider.rate_limited": "provider.rate_limited";
254
- readonly "stt.provider.quota_exceeded": "provider.rate_limited";
207
+ readonly "stt.provider.quota_exceeded": "provider.quota_exceeded";
208
+ readonly "stt.transport.write_failed": "provider.transport_write_failed";
209
+ readonly "stt.send_timeout": "provider.transport_timeout";
210
+ readonly "stt.audio_write_timeout": "provider.transport_timeout";
255
211
  readonly "stt.provider.invalid_request": "provider.invalid_request";
256
212
  readonly "stt.provider.input_rejected": "provider.input_rejected";
257
213
  readonly "stt.provider.session_expired": "provider.session_expired";
@@ -278,9 +234,11 @@ declare const PROVIDER_NAMES: {
278
234
  readonly twilio: "twilio-media-streams";
279
235
  readonly deepgram: "deepgram";
280
236
  readonly cartesia: "cartesia";
237
+ readonly cartesiaStt: "cartesia-stt";
281
238
  readonly elevenlabs: "elevenlabs";
282
239
  readonly elevenlabsStt: "elevenlabs-stt-realtime";
283
240
  readonly sarvam: "sarvam";
241
+ readonly sarvamTts: "sarvam-tts";
284
242
  readonly assemblyaiStt: "assemblyai-stt";
285
243
  readonly sonioxStt: "soniox-stt";
286
244
  readonly groq: "groq-chat-completions";
@@ -294,6 +252,7 @@ declare const PROVIDER_ERROR_CODES: {
294
252
  readonly elevenlabsTts: "elevenlabs.tts.error";
295
253
  readonly elevenlabsStt: "elevenlabs.stt.error";
296
254
  readonly sarvamStt: "sarvam.stt.error";
255
+ readonly sarvamTts: "sarvam.tts.error";
297
256
  readonly assemblyaiStt: "assemblyai.stt.error";
298
257
  readonly sonioxStt: "soniox.stt.error";
299
258
  readonly groqChat: "groq.chat.error";
@@ -304,10 +263,12 @@ declare const PROVIDER_ERROR_CODES: {
304
263
  readonly openaiHttp: "openai.http_error";
305
264
  readonly openaiResponseFailed: "openai.response.failed";
306
265
  readonly webClientAudio: "web_client_audio.error";
266
+ readonly cartesiaStt: "cartesia.stt.error";
307
267
  };
308
268
  /** Stable runtime taxonomy consumed by reconnect and call-failure policy. */
309
269
  declare const STT_ERROR_CODES: {
310
- readonly transportWriteFailed: "stt.transport.write_failed";
270
+ readonly transportWriteFailed: "provider.transport_write_failed";
271
+ readonly transportTimeout: "provider.transport_timeout";
311
272
  readonly unexpectedEof: "stt.transport.unexpected_eof";
312
273
  readonly connectFailed: "stt.transport.connect_failed";
313
274
  readonly connectTimeout: "stt.transport.connect_timeout";
@@ -315,13 +276,13 @@ declare const STT_ERROR_CODES: {
315
276
  readonly invalidRequest: "provider.invalid_request";
316
277
  readonly inputRejected: "provider.input_rejected";
317
278
  readonly rateLimited: "provider.rate_limited";
318
- readonly quotaExceeded: "provider.rate_limited";
279
+ readonly quotaExceeded: "provider.quota_exceeded";
319
280
  readonly serviceUnavailable: "provider.upstream_failed";
320
281
  readonly providerInternal: "provider.upstream_failed";
321
282
  readonly protocolError: "provider.protocol_invalid";
322
283
  readonly sessionExpired: "provider.session_expired";
323
284
  readonly streamEnded: "stt.stream_ended";
324
- readonly audioWriteTimeout: "stt.audio_write_timeout";
285
+ readonly audioWriteTimeout: "provider.transport_timeout";
325
286
  readonly closeTimeout: "stt.close_timeout";
326
287
  readonly bufferOverflow: "stt.reconnect.buffer_overflow";
327
288
  readonly sessionBufferOverflow: "stt.session_buffer_overflow";
@@ -331,11 +292,6 @@ declare const STT_ERROR_CODES: {
331
292
 
332
293
  type MediaDirection = "input" | "output" | "internal";
333
294
  type CallDirection = "inbound" | "outbound";
334
- /**
335
- * Channels TVIC 1.0 can actually execute. `sip` and `whatsapp` are intentionally
336
- * absent until a working transport exists — the union never claims a capability
337
- * the runtime cannot run.
338
- */
339
295
  type ChannelKind = "phone" | "web_audio" | "simulated";
340
296
 
341
297
  /**
@@ -398,6 +354,7 @@ interface IdempotencyPolicy {
398
354
  readonly enabled: boolean;
399
355
  readonly keyTemplate?: string;
400
356
  readonly ttlMs?: number;
357
+ readonly legacyKeyCompatibility?: boolean;
401
358
  }
402
359
 
403
360
  type MediaEventType = "media.stream.started" | "media.stream.ended" | "media.audio.chunk" | "media.audio.committed" | "media.turn.commit_requested" | "media.interrupt.requested" | "dtmf.received" | "media.error";
@@ -496,11 +453,6 @@ type MediaEvent = InputMediaEvent | OutputMediaEvent | InternalMediaEvent;
496
453
  */
497
454
  type WithoutMediaEventKind<T> = T extends MediaEvent ? Omit<T, "kind"> : never;
498
455
  type AnyMediaEventInit = WithoutMediaEventKind<MediaEvent>;
499
- /**
500
- * Adds the required coarse-grained category to a media event. The overload
501
- * keeps the correlated event type available to callers; the implementation
502
- * itself returns the complete `MediaEvent` union and contains no assertion.
503
- */
504
456
  declare function createMediaEvent<T extends AnyMediaEventInit>(init: T): Extract<MediaEvent, {
505
457
  readonly type: T["type"];
506
458
  readonly direction: T["direction"];
@@ -509,24 +461,17 @@ type InputAudioChunk = MediaAudioChunkEvent<"input">;
509
461
  type OutputAudioChunk = MediaAudioChunkEvent<"output">;
510
462
 
511
463
  type JsonSchemaDocument = Readonly<Record<string, unknown>>;
512
- /**
513
- * Optional tenant identity propagated into every tool execution. The runtime
514
- * populates this from the session attachment's `memoryUserId` /
515
- * `organizationId` / `workflowId`. The tool author reads `tenant.userId`
516
- * inside `execute` to enforce their own auth — TVIC ships no RBAC layer
517
- * (that is a tenant concern: the customer has an IdP).
518
- */
519
464
  interface ToolTenant {
520
465
  readonly userId?: UserId;
521
466
  readonly organizationId?: OrganizationId;
522
467
  readonly workflowId?: WorkflowId;
523
- /** Tenant-supplied scopes (e.g., "crm.read", "billing.write"). */
524
468
  readonly scopes?: readonly string[];
525
469
  }
526
470
  interface ToolExecutionContext {
527
471
  readonly sessionId: SessionId;
528
472
  readonly turnId: TurnId;
529
473
  readonly toolCallId: ToolCallId;
474
+ readonly idempotencyKey?: string;
530
475
  readonly attempt: number;
531
476
  readonly signal: AbortSignal;
532
477
  readonly logger: ToolLogger;
@@ -550,11 +495,8 @@ interface ToolDefinition<TInput = unknown, TOutput = unknown> {
550
495
  readonly retry: RetryPolicy;
551
496
  readonly idempotency: IdempotencyPolicy;
552
497
  /**
553
- * @deprecated Use `ctx.tenant` (the `ToolTenant` field on
554
- * `ToolExecutionContext`). The `authScope` field is kept as a no-op
555
- * typedef for one release; the runtime never enforced it. Migration:
556
- * read `ctx.tenant?.scopes` inside `execute` and enforce your own
557
- * auth.
498
+ * @deprecated This field is a no-op. Enforce authorization in `execute`
499
+ * using `ctx.tenant?.scopes`.
558
500
  */
559
501
  readonly authScope?: readonly string[];
560
502
  readonly tags?: readonly string[];
@@ -572,18 +514,20 @@ interface ToolIdempotencyRecord {
572
514
  readonly status: ToolIdempotencyStatus;
573
515
  readonly owner?: string;
574
516
  readonly claimedFence?: number;
517
+ readonly claimedGenerationId?: string;
575
518
  readonly expiresAtMs: number;
576
519
  readonly output?: unknown;
577
520
  readonly error?: NormalizedError;
578
521
  }
579
- /** Ownership context used to fence durable idempotency claims to a session. */
580
522
  interface ToolIdempotencyLease {
581
523
  readonly sessionId: SessionId;
582
524
  readonly holder: string;
583
525
  readonly fence: number;
526
+ readonly generationId: string;
584
527
  }
585
528
  interface ToolIdempotencyClaim {
586
529
  readonly key: string;
530
+ readonly sessionId?: SessionId;
587
531
  readonly lease?: ToolIdempotencyLease;
588
532
  readonly toolId?: ToolId;
589
533
  readonly toolVersion?: string;
@@ -597,25 +541,71 @@ type ToolIdempotencyClaimResult = {
597
541
  } | {
598
542
  readonly status: "succeeded";
599
543
  readonly record: ToolIdempotencyRecord;
544
+ } | {
545
+ readonly status: "terminal";
546
+ readonly record: ToolIdempotencyRecord;
600
547
  } | {
601
548
  readonly status: "in_progress";
602
549
  readonly record: ToolIdempotencyRecord;
603
550
  } | {
604
551
  readonly status: "conflict";
552
+ };
553
+ type ToolIdempotencyLookupResult = {
554
+ readonly status: "found";
605
555
  readonly record: ToolIdempotencyRecord;
556
+ } | {
557
+ readonly status: "conflict";
558
+ } | {
559
+ readonly status: "missing";
606
560
  };
607
561
  interface ToolIdempotencyOutcome {
608
562
  readonly status: Exclude<ToolIdempotencyStatus, "claimed">;
609
563
  readonly ttlMs: number;
610
564
  readonly owner: string;
565
+ readonly sessionId?: SessionId;
611
566
  readonly lease?: ToolIdempotencyLease;
612
567
  readonly output?: unknown;
613
568
  readonly error?: NormalizedError;
614
569
  }
570
+ interface ToolIdempotencyRelease {
571
+ readonly key: string;
572
+ readonly requestHash: string;
573
+ readonly owner: string;
574
+ readonly sessionId?: SessionId;
575
+ readonly lease?: ToolIdempotencyLease;
576
+ }
577
+ interface ToolIdempotencyQuarantine {
578
+ readonly key: string;
579
+ readonly sessionId: SessionId;
580
+ readonly lease: ToolIdempotencyLease;
581
+ readonly toolId: ToolId;
582
+ readonly toolVersion: string;
583
+ readonly requestHash: string;
584
+ readonly owner: string;
585
+ readonly ttlMs: number;
586
+ readonly error: NormalizedError;
587
+ }
588
+ type ToolIdempotencyQuarantineResult = {
589
+ readonly status: "quarantined";
590
+ readonly record: ToolIdempotencyRecord;
591
+ } | {
592
+ readonly status: "succeeded";
593
+ readonly record: ToolIdempotencyRecord;
594
+ } | {
595
+ readonly status: "terminal";
596
+ readonly record: ToolIdempotencyRecord;
597
+ } | {
598
+ readonly status: "in_progress";
599
+ readonly record: ToolIdempotencyRecord;
600
+ } | {
601
+ readonly status: "conflict";
602
+ };
615
603
  interface ToolIdempotencyStore {
616
- lookup(key: string, requestHash: string): Promise<ToolIdempotencyRecord | null>;
604
+ lookup(key: string, requestHash: string, sessionId?: SessionId, lease?: ToolIdempotencyLease): Promise<ToolIdempotencyLookupResult>;
617
605
  claim(input: ToolIdempotencyClaim): Promise<ToolIdempotencyClaimResult>;
606
+ releaseClaim(input: ToolIdempotencyRelease): Promise<boolean>;
618
607
  complete(key: string, requestHash: string, outcome: ToolIdempotencyOutcome): Promise<void>;
608
+ quarantine(input: ToolIdempotencyQuarantine): Promise<ToolIdempotencyQuarantineResult>;
619
609
  }
620
610
  interface ToolCallBase {
621
611
  readonly toolCallId: ToolCallId;
@@ -725,8 +715,8 @@ interface MemoryQuery {
725
715
  readonly tags?: readonly string[];
726
716
  readonly limit?: number;
727
717
  /**
728
- * v0.1 continuation token. Adapters must interpret this as a non-negative
729
- * decimal offset; opaque provider-specific cursors are not portable yet.
718
+ * Opaque continuation token. Built-in adapters use a non-negative decimal
719
+ * offset; callers must treat this value as opaque.
730
720
  */
731
721
  readonly cursor?: string;
732
722
  }
@@ -764,15 +754,7 @@ interface Memory {
764
754
  put<T = unknown>(ref: MemoryRef, key: string, kind: MemoryKind, value: T, options?: MemoryPutOptions): Promise<MemoryEntry<T>>;
765
755
  list<T = unknown>(ref: MemoryRef, query?: MemoryQuery): Promise<readonly MemoryEntry<T>[]>;
766
756
  delete(ref: MemoryRef, key: string, kind?: MemoryKind): Promise<boolean>;
767
- /** Delete every entry under the given `MemoryRef`. Returns the count deleted. */
768
757
  deleteAll(ref: MemoryRef): Promise<number>;
769
- /**
770
- * Delete user-owned data only: the user's `user` scope and session entries
771
- * explicitly attributed to that user by a trusted runtime write. Shared
772
- * organization/workflow scopes are never part of this cascade. This is a
773
- * destructive, privileged erasure primitive; the adapter does not authorize
774
- * the caller or prove that the supplied user id belongs to the requester.
775
- */
776
758
  deleteForUser(userId: UserId): Promise<number>;
777
759
  }
778
760
 
@@ -837,34 +819,22 @@ interface TurnOutput {
837
819
  readonly text?: string;
838
820
  readonly mediaEventIds: readonly MediaEventId[];
839
821
  readonly metadata?: Readonly<Record<string, unknown>>;
822
+ readonly delivery?: TurnOutputDelivery;
823
+ }
824
+ type AudioOutputDeliveryStatus = "not_attempted" | "not_accepted" | "partially_accepted" | "transport_accepted" | "playout_confirmed" | "playout_unconfirmed";
825
+ type TextOutputDeliveryStatus = "not_attempted" | "not_accepted" | "transport_accepted";
826
+ interface TurnOutputDelivery {
827
+ readonly audio: AudioOutputDeliveryStatus;
828
+ readonly text: TextOutputDeliveryStatus;
840
829
  }
841
- /**
842
- * Turn timing on the session's monotonic clock.
843
- *
844
- * Every stage measurement is anchored at the endpoint commit, the moment the runtime
845
- * decided the participant had finished speaking, rather than at internal turn setup.
846
- * That anchor is what a caller actually experiences as the start of waiting.
847
- *
848
- * `endpointMs` is measured before that anchor and is therefore additive: perceived
849
- * caller-to-audio delay is `endpointMs + firstAudioMs`. It is usually the largest
850
- * single contributor, so a report that omits it understates the wait.
851
- */
852
830
  interface TurnLatency {
853
- /** Participant speech start to endpoint commit. Requires a speech-start signal. */
854
831
  readonly listenedMs?: number;
855
- /** Last immutable final segment to endpoint commit, the endpoint wait itself. */
856
832
  readonly endpointMs?: number;
857
- /** Endpoint commit to the first model token. */
858
833
  readonly firstTokenMs?: number;
859
- /** Endpoint commit to the first audio frame accepted by the transport. */
860
834
  readonly firstAudioMs?: number;
861
- /** Total time spent in tool execution during the turn. */
862
835
  readonly toolMs?: number;
863
- /** Interruption decision to queued output being stopped. */
864
836
  readonly interruptionTailMs?: number;
865
- /** Endpoint commit to terminal turn state. */
866
837
  readonly totalMs?: number;
867
- /** Time without an owner during runtime reattachment; excluded from stage timings. */
868
838
  readonly recoveryGapMs?: number;
869
839
  }
870
840
  interface TurnBase {
@@ -912,6 +882,12 @@ interface ProviderStreamingCapabilities {
912
882
  /** Streaming is supported by the provider protocol, not emulated by chunked requests. */
913
883
  readonly native: boolean;
914
884
  }
885
+ interface ProviderBatchCapabilities {
886
+ /** Accepts one complete input payload instead of requiring a live stream. */
887
+ readonly input: boolean;
888
+ /** Returns one complete output payload instead of incremental events. */
889
+ readonly output: boolean;
890
+ }
915
891
  interface ProviderCancellationCapabilities {
916
892
  /** Active provider work can be stopped rather than merely ignored by TVIC. */
917
893
  readonly request: boolean;
@@ -946,12 +922,16 @@ interface ProviderPlayoutCapabilities {
946
922
  */
947
923
  interface ProviderCapabilities {
948
924
  readonly streaming: ProviderStreamingCapabilities;
925
+ readonly batch?: ProviderBatchCapabilities;
949
926
  readonly cancellation: ProviderCancellationCapabilities;
950
927
  readonly transports: readonly ProviderTransport[];
951
928
  readonly audio?: ProviderAudioCapabilities;
952
929
  readonly languages?: readonly string[];
953
930
  readonly models?: readonly string[];
931
+ readonly batchModels?: readonly string[];
954
932
  readonly voices?: readonly string[];
933
+ /** Whether an incremental TTS adapter can honor timestamp/alignment requests. */
934
+ readonly timestamps?: boolean;
955
935
  readonly turnDetection?: readonly TurnDetectionMode[];
956
936
  readonly tools?: ProviderToolCapabilities;
957
937
  readonly playout?: ProviderPlayoutCapabilities;
@@ -965,6 +945,14 @@ interface Provider {
965
945
  readonly kind: ProviderKind;
966
946
  readonly version: string;
967
947
  readonly capabilities: ProviderCapabilities;
948
+ readonly configuredModel?: string;
949
+ /** Skip local model-catalog validation; this does not imply vendor support. */
950
+ readonly allowUnknownModel?: boolean;
951
+ readonly configuredVoice?: string | undefined;
952
+ readonly configuredLanguage?: string | undefined;
953
+ readonly languageWasExplicitlyConfigured?: boolean;
954
+ readonly supportsLanguage?: (language: string, model?: string) => boolean;
955
+ readonly supportsVoice?: (voice: string, model?: string) => boolean;
968
956
  readonly region?: string;
969
957
  readonly metadata?: Readonly<Record<string, unknown>>;
970
958
  }
@@ -979,12 +967,14 @@ type RequiredProviderCapabilities<T extends object> = {
979
967
  interface ProviderRequirements {
980
968
  readonly kind: ProviderKind;
981
969
  readonly streaming?: RequiredProviderCapabilities<ProviderStreamingCapabilities>;
970
+ readonly batch?: RequiredProviderCapabilities<ProviderBatchCapabilities>;
982
971
  readonly cancellation?: RequiredProviderCapabilities<ProviderCancellationCapabilities>;
983
972
  readonly transport?: ProviderTransport;
984
973
  readonly inputFormat?: AudioFormat;
985
974
  readonly outputFormat?: AudioFormat;
986
975
  readonly language?: string;
987
976
  readonly model?: string;
977
+ readonly batchModel?: string;
988
978
  readonly voice?: string;
989
979
  readonly turnDetection?: TurnDetectionMode;
990
980
  readonly functionCalling?: boolean;
@@ -994,7 +984,7 @@ interface ProviderRequirements {
994
984
  readonly region?: string;
995
985
  readonly dataPolicy?: ProviderDataPolicy;
996
986
  }
997
- type ProviderCompatibilityIssueCode = "kind.unsupported" | "streaming.unsupported" | "cancellation.unsupported" | "transport.unsupported" | "audio.input_unsupported" | "audio.output_unsupported" | "language.unsupported" | "provider.model_unsupported" | "provider.voice_unsupported" | "turn_detection.unsupported" | "tools.unsupported" | "playout.unsupported" | "call_control.unsupported" | "region.unsupported" | "data_policy.unsupported";
987
+ type ProviderCompatibilityIssueCode = "kind.unsupported" | "streaming.unsupported" | "batch.unsupported" | "cancellation.unsupported" | "transport.unsupported" | "audio.input_unsupported" | "audio.output_unsupported" | "language.unsupported" | "provider.model_unsupported" | "provider.voice_unsupported" | "turn_detection.unsupported" | "tools.unsupported" | "playout.unsupported" | "call_control.unsupported" | "region.unsupported" | "data_policy.unsupported";
998
988
  interface ProviderCompatibilityIssue {
999
989
  readonly code: ProviderCompatibilityIssueCode;
1000
990
  readonly requirement: string;
@@ -1024,22 +1014,12 @@ type InboundMediaEvent = InputMediaEvent | InternalMediaEvent;
1024
1014
  interface CallHandle {
1025
1015
  readonly callId: CallId;
1026
1016
  readonly events: AsyncIterable<InboundMediaEvent>;
1027
- /**
1028
- * Sends an outbound frame. Returns `true` if it reached the transport, `false`
1029
- * if the socket was closed/closing and the frame was dropped, so the caller can
1030
- * tell "delivered" from "silently swallowed" instead of assuming success.
1031
- */
1017
+ readonly remoteHangup?: Promise<void>;
1032
1018
  send(event: OutputMediaEvent): Promise<boolean>;
1033
- /** Delivers whole-turn assistant text to transports with a text channel. */
1034
1019
  deliverText?(turnId: TurnId, sequence: number, text: string): Promise<boolean>;
1035
1020
  clear(): Promise<void>;
1021
+ endInput?(reason: StreamEndReason): Promise<void>;
1036
1022
  close(reason: StreamEndReason): Promise<void>;
1037
- /**
1038
- * Resolves once the transport confirms the marked output was actually played out
1039
- * to the caller (e.g. a Twilio mark ack): `true` if heard, `false` if the call
1040
- * dropped before playout. Optional: providers that can't observe playout omit it,
1041
- * and callers then fall back to "reached transport" as their delivery signal.
1042
- */
1043
1023
  confirmPlayout?(markId: string, timeoutMs: number): Promise<boolean>;
1044
1024
  }
1045
1025
  interface TelephonyProvider extends Provider {
@@ -1102,6 +1082,37 @@ interface SttOpenRequest {
1102
1082
  readonly metadata?: Readonly<Record<string, unknown>>;
1103
1083
  readonly signal?: AbortSignal;
1104
1084
  }
1085
+ type SttBatchTimestampGranularity = "word";
1086
+ /** A complete audio payload for a non-streaming transcription request. */
1087
+ interface SttBatchTranscriptionRequest {
1088
+ /** Container bytes, or raw bytes when `format` is supplied. */
1089
+ readonly audio: Uint8Array;
1090
+ /** Optional filename used as the multipart upload filename and format hint. */
1091
+ readonly fileName?: string;
1092
+ /** Optional MIME type for the multipart file part. */
1093
+ readonly mimeType?: string;
1094
+ /** Raw PCM format. Omit this when `audio` contains a self-describing container. */
1095
+ readonly format?: AudioFormat;
1096
+ readonly language?: string;
1097
+ readonly model?: string;
1098
+ readonly timestampGranularities?: readonly SttBatchTimestampGranularity[];
1099
+ readonly allowUnknownModel?: boolean;
1100
+ readonly signal?: AbortSignal;
1101
+ }
1102
+ interface SttBatchWord {
1103
+ readonly word: string;
1104
+ readonly startMs: number;
1105
+ readonly endMs: number;
1106
+ }
1107
+ /** A complete transcript returned by a batch STT provider. */
1108
+ interface SttBatchTranscription {
1109
+ readonly text: string;
1110
+ readonly requestId?: string;
1111
+ readonly language?: string;
1112
+ readonly durationMs?: number;
1113
+ readonly words?: readonly SttBatchWord[];
1114
+ readonly metadata?: Readonly<Record<string, unknown>>;
1115
+ }
1105
1116
  type SttCommitMode = "provider" | "none";
1106
1117
  /**
1107
1118
  * Origin of audio offsets emitted by an STT stream. Reconnectable streams must
@@ -1121,6 +1132,8 @@ interface SttStream {
1121
1132
  interface SpeechToTextProvider extends Provider {
1122
1133
  readonly kind: "stt";
1123
1134
  open(request: SttOpenRequest): Promise<SttStream>;
1135
+ /** Optional complete-file transcription capability. */
1136
+ transcribe?(request: SttBatchTranscriptionRequest): Promise<SttBatchTranscription>;
1124
1137
  }
1125
1138
 
1126
1139
  interface TtsSessionOpenRequest {
@@ -1177,9 +1190,7 @@ interface TtsStream {
1177
1190
  /** A single prosody-preserving synthesis context receiving incremental text. */
1178
1191
  interface TtsSession extends TtsStream {
1179
1192
  sendText(text: string): Promise<void>;
1180
- /** Resolves once the provider or transport accepts a synthesis boundary. */
1181
1193
  flush(): Promise<TtsFlushResult>;
1182
- /** Ends input; events continue until the provider emits its completion event. */
1183
1194
  finish(): Promise<void>;
1184
1195
  }
1185
1196
  interface TextToSpeechProvider extends Provider {
@@ -1272,14 +1283,8 @@ interface AgentMemoryPolicy {
1272
1283
  readonly maxBytesPerSession?: number;
1273
1284
  readonly readOnly?: boolean;
1274
1285
  /**
1275
- * If true (default), session-scoped memory is purged on session end. This
1276
- * is Vapi's Zero Data Retention posture: the call's ephemeral transcripts
1277
- * do not outlive the call. User-scoped, organization-scoped, and
1278
- * workflow-scoped memory are *not* affected — they persist across sessions.
1279
- *
1280
- * Pre-1.0, this field was named `deleteOnEnd`. That name was misleading:
1281
- * it sounded like it deleted *all* memory, but the implementation only
1282
- * purges the `session` scope. The rename is the contract-clarity fix.
1286
+ * If true (default), only session-scoped memory is purged on session end.
1287
+ * User, organization, and workflow memory remain available across sessions.
1283
1288
  */
1284
1289
  readonly deleteSessionScopeOnEnd?: boolean;
1285
1290
  /**
@@ -1369,27 +1374,42 @@ interface Agent {
1369
1374
  readonly metadata?: Readonly<Record<string, unknown>>;
1370
1375
  }
1371
1376
 
1377
+ declare const MAX_RECOVERY_PAGE_SIZE = 1000;
1378
+ declare const MAX_SAFE_LEASE_TIMESTAMP: number;
1379
+ declare function assertLeaseTtlMs(ttlMs: number): void;
1380
+ declare function assertLeaseFence(fence: number): void;
1381
+ declare function assertLeaseTimestampMs(timestampMs: number): void;
1382
+ declare function safeLeaseExpiryAt(nowMs: number, ttlMs: number): number;
1383
+ declare function assertRecoveryPageSize(limit: number): void;
1372
1384
  interface SessionLease {
1373
1385
  readonly sessionId: SessionId;
1374
1386
  readonly holder: string;
1375
1387
  readonly fence: number;
1388
+ readonly generationId: string;
1376
1389
  readonly acquiredAtMs: number;
1377
1390
  readonly renewedAtMs: number;
1378
1391
  readonly expiresAtMs: number;
1379
1392
  }
1393
+ interface SessionRecoveryCandidate {
1394
+ readonly sessionId: SessionId;
1395
+ readonly fence: number;
1396
+ readonly generationId: string;
1397
+ }
1380
1398
  interface SessionLeaseStore {
1381
1399
  acquire(sessionId: SessionId, holder: string, ttlMs: number): Promise<SessionLease | null>;
1382
- renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number): Promise<SessionLease | null>;
1383
- release(sessionId: SessionId, holder: string, fence: number): Promise<void>;
1400
+ renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number, generationId: string): Promise<SessionLease | null>;
1401
+ release(sessionId: SessionId, holder: string, fence: number, generationId: string): Promise<void>;
1384
1402
  get(sessionId: SessionId): Promise<SessionLease | null>;
1385
1403
  listRecoveryCandidates(options: {
1386
1404
  readonly nowMs: number;
1387
1405
  readonly limit: number;
1388
1406
  readonly cursor?: string;
1389
1407
  }): Promise<{
1390
- readonly sessionIds: readonly SessionId[];
1408
+ readonly candidates: readonly SessionRecoveryCandidate[];
1409
+ readonly corruptLeaseSessionIds?: readonly SessionId[];
1391
1410
  readonly nextCursor?: string;
1392
1411
  }>;
1412
+ acknowledgeRecoveryCandidate(candidate: SessionRecoveryCandidate): Promise<void>;
1393
1413
  close(): Promise<void>;
1394
1414
  }
1395
1415
  interface DurableOutboxEvent {
@@ -1397,6 +1417,7 @@ interface DurableOutboxEvent {
1397
1417
  readonly aggregateType: "session" | "turn" | "tool_call";
1398
1418
  readonly aggregateId: string;
1399
1419
  readonly sessionId: SessionId;
1420
+ readonly sessionIncarnation?: number;
1400
1421
  readonly version: number;
1401
1422
  readonly fence: number;
1402
1423
  readonly envelope: Readonly<Record<string, unknown>>;
@@ -1417,7 +1438,6 @@ interface ToolCallRuntimeMetadata {
1417
1438
  interface StoredSessionRecord {
1418
1439
  readonly session: Session;
1419
1440
  readonly runtime: SessionRuntimeMetadata;
1420
- /** Persistence-local aggregate version used for outbox ordering/fencing. */
1421
1441
  readonly version?: number;
1422
1442
  }
1423
1443
  interface StoredTurnRecord {
@@ -1471,28 +1491,9 @@ interface DurableRuntimeStore {
1471
1491
  readonly toolCalls: ToolCallStore;
1472
1492
  readonly leases: SessionLeaseStore;
1473
1493
  readonly toolIdempotencyStore?: ToolIdempotencyStore;
1474
- /**
1475
- * Closes adapter-owned resources and background workers. When present,
1476
- * Runtime.stop() delegates the complete durable-store shutdown to this
1477
- * method instead of closing the aggregate stores independently. Adapters
1478
- * that do not own background resources may omit it and retain the legacy
1479
- * component-close behavior.
1480
- */
1481
1494
  close?(): Promise<void>;
1482
- /**
1483
- * Atomically creates a session and acquires its first owner lease when the
1484
- * backend supports that transaction boundary. Runtimes use the fallback
1485
- * start-then-attach path only for adapters that do not implement it.
1486
- */
1487
1495
  createSessionWithLease?(record: StoredSessionRecord, holder: string, ttlMs: number, initialEvent?: (lease: SessionLease) => DurableOutboxEvent): Promise<SessionLease | null>;
1488
- runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
1489
- /**
1490
- * Serialized compatibility boundary for callers that intentionally operate
1491
- * without a live attachment. A store may provide rollback internally, but
1492
- * the legacy CRUD interfaces cannot guarantee atomic rollback for arbitrary
1493
- * custom stores. There is no ownership or fencing guarantee; realtime
1494
- * attached paths must use runSessionTransaction.
1495
- */
1496
+ runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence" | "generationId">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
1496
1497
  runUnfencedSessionTransaction?<T>(sessionId: SessionId, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
1497
1498
  }
1498
1499
 
@@ -1503,140 +1504,41 @@ interface RuntimeOptions {
1503
1504
  readonly clock?: Clock;
1504
1505
  readonly idGenerator?: IdGenerator;
1505
1506
  readonly durableStore?: DurableRuntimeStore;
1506
- /** Whether the runtime may close an injected durable store during stop. */
1507
1507
  readonly durableStoreOwnership?: "runtime" | "caller";
1508
- /** Overrides for the explicit defaults; omitted values use the safe defaults. */
1509
1508
  readonly durablePolicy?: Partial<DurableRuntimePolicy>;
1510
1509
  readonly toolIdempotencyStore?: ToolIdempotencyStore;
1511
1510
  readonly holderId?: string;
1512
1511
  readonly onDurableMetric?: (metric: DurableRuntimeMetric) => void;
1513
- /**
1514
- * Memory adapter used for cross-call memory. Defaults to `InMemoryMemory`
1515
- * (process-local) when omitted. For cross-call recall, wire a durable
1516
- * adapter (e.g., `@tvic/dal-postgres-memory`) or a third-party adapter
1517
- * (Mem0, Supermemory, etc.).
1518
- */
1519
1512
  readonly memory?: Memory;
1520
- /**
1521
- * Maximum time the runtime waits for already-admitted memory writes and the
1522
- * session-scope purge during terminalization. Timing out releases the
1523
- * caller while preserving write-before-purge ordering. The default is 1
1524
- * second; the adapter operation is not cancelled.
1525
- */
1526
1513
  readonly sessionMemoryFinalizeTimeoutMs?: number;
1527
- /**
1528
- * Maximum time the runtime waits for the best-effort `onSessionEnd` observer
1529
- * after the terminal event has been assembled. The default is 5 seconds;
1530
- * the observer is not cancelled when this budget expires.
1531
- */
1532
1514
  readonly sessionEndHookTimeoutMs?: number;
1533
- /**
1534
- * Pre-call context resolver. When a session is created or attached, the
1535
- * runtime calls this hook when a session is attached to populate the agent's
1536
- * context with memory entries for the relevant scopes AND with non-memory
1537
- * context (CRM, feature flags, tenant config). If omitted, the runtime uses a default
1538
- * resolver that reads from `options.memory` for the active `user` /
1539
- * `organization` / `workflow` scopes and returns an empty `static` map.
1540
- *
1541
- * Pre-1.0, this was named `preCallMemoryResolver` and returned a
1542
- * `PreCallMemoryContext`. The rename to `PreCallContextResolver` and
1543
- * the addition of the `static: ReadonlyMap<string, string>` sub-map
1544
- * fixes a real type lie: the customer previously had to stuff CRM
1545
- * data and feature flags into the `Memory` map as `kind: "fact"`
1546
- * entries. The `static` map is the typed input for non-memory context.
1547
- */
1548
1515
  readonly preCallContextResolver?: PreCallContextResolver;
1549
- /** Optional org/workflow ids carried on every session created by this runtime. */
1550
1516
  readonly defaultOrganizationId?: OrganizationId;
1551
1517
  readonly defaultWorkflowId?: WorkflowId;
1552
- /**
1553
- * Optional callback fired after a session is terminalized and after the
1554
- * runtime has made its best-effort memory-finalization attempt. The event
1555
- * reports whether session-scope deletion was skipped, completed, failed, or
1556
- * timed out. Best-effort: a throw or timeout from the hook does not affect
1557
- * the terminal session. The runtime does not retry; if you need durability,
1558
- * call an external system from inside the hook and have that system retry.
1559
- *
1560
- * The hook is the canonical place for: post-call LLM summarization,
1561
- * CRM sync, callback scheduling, escalation, transcript delivery to a
1562
- * CRM. The runtime does not own any of these — the user picks the LLM,
1563
- * the prompt, the schema.
1564
- */
1565
1518
  readonly onSessionEnd?: (event: SessionEndEvent) => void | Promise<void>;
1566
- /**
1567
- * Optional metrics recorder. The runtime emits one `record` call per
1568
- * observable event (session start, turn end, session end) and one
1569
- * `onTurn` call per terminal turn. The user provides the implementation
1570
- * (Earshot-shaped, console.log-shaped, OTel-shaped).
1571
- */
1572
1519
  readonly sessionMetricsRecorder?: SessionMetricsRecorder;
1573
- /**
1574
- * Optional health check consumed by `NodeMediaPlane.healthPath`. The
1575
- * user implements the readiness check (DB ping, recovery-coordinator
1576
- * liveness); the runtime reflects it on the HTTP endpoint. Returns
1577
- * `ok: true` when all checks pass; the runtime responds with HTTP 200.
1578
- */
1579
1520
  readonly healthCheck?: () => Promise<HealthSnapshot>;
1580
- /**
1581
- * Optional callback fired at the start of `runtime.stop()` so the
1582
- * user's deployment wiring (SIGTERM handler, kubernetes preStop hook)
1583
- * can drain the load balancer before the runtime detaches sessions
1584
- * and closes stores. Best-effort; the runtime proceeds after the
1585
- * promise settles or 5s, whichever comes first.
1586
- */
1587
1521
  readonly onShutdownStart?: (state: {
1588
1522
  readonly activeSessions: readonly SessionId[];
1589
1523
  }) => void | Promise<void>;
1590
- /**
1591
- * Optional async provider of the pre-call static context (CRM records,
1592
- * feature flags, tenant config). Called by the runtime when a session is
1593
- * attached; the result is merged into the pre-call context's `static`
1594
- * map. Best-effort: a throw or timeout produces a degraded `static`
1595
- * context (degraded flag set). This is a separate seam from
1596
- * `preCallContextResolver` so a custom resolver can choose to either
1597
- * (a) inline the static fetch into its own resolver, or (b) leave the
1598
- * fetch to the runtime and just augment the result.
1599
- */
1600
1524
  readonly preCallStaticProvider?: () => Promise<ReadonlyMap<string, string>>;
1601
1525
  }
1602
- /**
1603
- * Resolves the pre-call context for a session. The runtime calls this on
1604
- * `startAttachedSession` and `attachSession` after lease acquisition.
1605
- *
1606
- * Pre-1.0, this was named `PreCallMemoryResolver` and returned a
1607
- * `PreCallMemoryContext`. The rename to `PreCallContextResolver` and
1608
- * the addition of the `static` sub-map fixes the type lie.
1609
- */
1610
1526
  type PreCallContextResolver = (input: {
1611
1527
  readonly userId?: UserId;
1612
1528
  readonly organizationId?: OrganizationId;
1613
1529
  readonly workflowId?: WorkflowId;
1614
1530
  readonly sessionId: SessionId;
1615
1531
  readonly memory: Memory;
1616
- /** Wall-clock source supplied by the runtime for deterministic resolution. */
1617
1532
  readonly clock?: () => number;
1618
- /** Scopes permitted by the agent's memory policy for this call. */
1619
1533
  readonly scopes?: readonly MemoryScope[];
1620
- /** Optional kind filter from `memoryPolicy.preCallLoad`. */
1621
1534
  readonly kind?: MemoryKind;
1622
- /** Maximum memory entries the runtime should load from any one scope. */
1623
1535
  readonly maxEntries?: number;
1624
- /** Maximum rendered pre-call context bytes. */
1625
1536
  readonly maxBytes?: number;
1626
1537
  }) => Promise<PreCallContext>;
1627
1538
  interface PreCallContext {
1628
- /** Map of `${scope}:${scopeId}:${kind}:${key}` to entry. Empty on resolver error. */
1629
1539
  readonly memory: ReadonlyMap<string, MemoryEntry>;
1630
- /**
1631
- * Non-memory context: CRM records, feature flags, tenant config, anything
1632
- * the LLM should see in the system prompt that is *not* a memory entry.
1633
- * Rendered into a separate `<context>...</context>` block above the
1634
- * `<memory>...</memory>` block.
1635
- */
1636
1540
  readonly static: ReadonlyMap<string, string>;
1637
- /** When the resolver ran, wall-clock ms. */
1638
1541
  readonly resolvedAtMs: number;
1639
- /** Per-bucket degradation flag. */
1640
1542
  readonly degraded: {
1641
1543
  readonly memory: boolean;
1642
1544
  readonly static: boolean;
@@ -1658,26 +1560,11 @@ interface PreCallMemoryContext {
1658
1560
  readonly resolvedAtMs: number;
1659
1561
  readonly degraded: boolean;
1660
1562
  }
1661
- /**
1662
- * Carries the terminal session, the persisted snapshot, and a snapshot
1663
- * of the memory adapter's state at the moment of endSession. The
1664
- * memory snapshot is the source of truth for "what did we learn about
1665
- * this caller" — the runtime does not try to track per-write
1666
- * `MemoryChangeRecord`s, because most writes are within the session
1667
- * scope and are about to be deleted by `deleteSessionScopeOnEnd`. The
1668
- * snapshot the user actually wants is what survives into `user` /
1669
- * `organization` / `workflow` scopes.
1670
- */
1671
1563
  interface SessionEndEvent {
1672
1564
  readonly session: TerminalSession;
1673
1565
  readonly snapshot: SessionSnapshot;
1674
- /**
1675
- * Memory state at end-of-session, scoped to the user/org/workflow ids
1676
- * the runtime resolved for this session. Empty for sessions that wrote
1677
- * only to `session` scope (which is about to be deleted).
1678
- */
1566
+ readonly snapshotStatus?: "available" | "timed_out" | "unavailable";
1679
1567
  readonly finalMemorySnapshot: SessionEndMemorySnapshot;
1680
- /** Result of the ordered session-memory drain and optional purge. */
1681
1568
  readonly memoryFinalization: SessionMemoryFinalization;
1682
1569
  readonly wallClockMs: number;
1683
1570
  }
@@ -1699,17 +1586,73 @@ interface SessionEndMemorySnapshot {
1699
1586
  readonly organization?: ReadonlyMap<string, MemoryEntry>;
1700
1587
  readonly workflow?: ReadonlyMap<string, MemoryEntry>;
1701
1588
  }
1702
- /**
1703
- * Contract for an external observability consumer. The runtime emits
1704
- * one `record` per observable event and one `onTurn` per terminal
1705
- * turn. Implementations: Earshot-shaped (project into an `earshot.*`
1706
- * event), OTel-shaped (project into a span event), console.log-shaped.
1707
- */
1708
1589
  interface SessionMetricsRecorder {
1709
1590
  record(name: string, attributes?: Readonly<Record<string, string | number | boolean>>): void;
1710
1591
  onTurn(turn: TerminalTurn, sessionId: SessionId): void;
1592
+ onSessionTrace?(trace: RuntimeSessionTrace): void;
1711
1593
  onSessionEnd?(event: SessionEndEvent): void;
1712
1594
  }
1595
+ interface RuntimeTraceError {
1596
+ readonly code: string;
1597
+ readonly category: ErrorCategory;
1598
+ readonly retriable: boolean;
1599
+ }
1600
+ interface RuntimeSessionTrace {
1601
+ readonly schemaVersion: 1;
1602
+ readonly privacy: {
1603
+ readonly classification: "metadata_only";
1604
+ readonly excludes: readonly [
1605
+ "transcripts",
1606
+ "audio",
1607
+ "tool_names",
1608
+ "tool_arguments",
1609
+ "tool_results",
1610
+ "provider_error_messages",
1611
+ "session_metadata",
1612
+ "variables",
1613
+ "memory"
1614
+ ];
1615
+ };
1616
+ readonly session: {
1617
+ readonly id: SessionId;
1618
+ readonly callId?: CallId;
1619
+ readonly agentId: AgentId;
1620
+ readonly channel: ChannelKind;
1621
+ readonly status: TerminalSessionStatus;
1622
+ readonly terminalSource?: TerminalSource;
1623
+ readonly createdAt: Timestamp;
1624
+ readonly startedAt: Timestamp;
1625
+ readonly endedAt: Timestamp;
1626
+ readonly error?: RuntimeTraceError;
1627
+ };
1628
+ readonly snapshot: {
1629
+ readonly status: "available" | "timed_out" | "unavailable";
1630
+ readonly turnCount: number;
1631
+ readonly omittedTurnCount: number;
1632
+ readonly toolCallCount: number;
1633
+ readonly omittedToolCallCount: number;
1634
+ };
1635
+ readonly turns: readonly {
1636
+ readonly id: TurnId;
1637
+ readonly sequence: number;
1638
+ readonly status: TurnStatus;
1639
+ readonly startedAt: Timestamp;
1640
+ readonly endedAt?: Timestamp;
1641
+ readonly latency: TurnLatency;
1642
+ readonly delivery?: TurnOutputDelivery;
1643
+ readonly error?: RuntimeTraceError;
1644
+ }[];
1645
+ readonly toolCalls: readonly {
1646
+ readonly id: ToolCallId;
1647
+ readonly turnId: TurnId;
1648
+ readonly status: ToolCallStatus;
1649
+ readonly attempts: number;
1650
+ readonly queuedAt: Timestamp;
1651
+ readonly startedAt?: Timestamp;
1652
+ readonly endedAt?: Timestamp;
1653
+ readonly error?: RuntimeTraceError;
1654
+ }[];
1655
+ }
1713
1656
  interface HealthSnapshot {
1714
1657
  readonly ok: boolean;
1715
1658
  readonly checks?: Readonly<Record<string, HealthCheckResult>>;
@@ -1718,7 +1661,6 @@ interface HealthCheckResult {
1718
1661
  readonly ok: boolean;
1719
1662
  readonly latencyMs?: number;
1720
1663
  readonly message?: string;
1721
- /** Sanitized diagnostic details supplied by the owning subsystem. */
1722
1664
  readonly details?: Readonly<Record<string, unknown>>;
1723
1665
  }
1724
1666
  interface DurableRuntimeMetric {
@@ -1755,11 +1697,8 @@ interface StartSessionOptions {
1755
1697
  readonly call?: Call;
1756
1698
  readonly variables?: Readonly<Record<string, unknown>>;
1757
1699
  readonly metadata?: Readonly<Record<string, unknown>>;
1758
- /** User scope identity for cross-call memory recall. */
1759
1700
  readonly memoryUserId?: UserId;
1760
- /** Organization scope for cross-call memory recall. */
1761
1701
  readonly organizationId?: OrganizationId;
1762
- /** Workflow scope for cross-call memory recall. */
1763
1702
  readonly workflowId?: WorkflowId;
1764
1703
  }
1765
1704
  type EndSessionReason = "completed" | "cancelled" | "failed" | "timeout";
@@ -1818,41 +1757,19 @@ interface SessionAttachment {
1818
1757
  readonly signal: AbortSignal;
1819
1758
  readonly health: SessionAttachmentHealth;
1820
1759
  readonly detach: () => Promise<void>;
1821
- /**
1822
- * Pre-call context loaded from the runtime's pre-call context resolver
1823
- * before the call starts. Contains both memory entries (rendered as
1824
- * `<memory>...</memory>`) and non-memory static context (rendered as
1825
- * `<context>...</context>`). Pre-1.0, this was `preCallMemory` and
1826
- * carried only the memory entries. The rename is the contract-clarity
1827
- * fix; legacy callers reading `preCallMemory.entries` should switch
1828
- * to `preCallContext.memory`.
1829
- */
1830
1760
  readonly preCallContext?: PreCallContext;
1831
1761
  /**
1832
- * @deprecated Use `preCallContext`. The legacy `preCallMemory` field
1833
- * is kept as a typedef for one release and resolved to a shim that
1834
- * projects `preCallContext.memory`.
1762
+ * @deprecated Use `preCallContext`. This compatibility field projects
1763
+ * `preCallContext.memory`.
1835
1764
  */
1836
1765
  readonly preCallMemory?: PreCallMemoryContext;
1837
1766
  }
1838
1767
  interface RuntimeServiceLifecycle {
1839
- /** Starts the runtime. A runtime can be started once; create a new runtime after stop. */
1840
1768
  start(signal?: AbortSignal): Promise<void>;
1841
- /**
1842
- * Stops the runtime and closes its owned resources. The operation is
1843
- * idempotent and concurrent callers await the same teardown. A stopped
1844
- * runtime cannot be restarted because durable adapters are closed.
1845
- */
1846
1769
  stop(): Promise<void>;
1847
1770
  readonly isRunning: boolean;
1848
1771
  }
1849
1772
  interface Runtime extends RuntimeServiceLifecycle {
1850
- /**
1851
- * Optional execution seam for low-level pipeline users. Registered runs are
1852
- * cancelled and drained by `stop()` before the runtime closes its durable
1853
- * stores. Managed voice agents already provide their own higher-level
1854
- * lifecycle, but direct `PipelineVoiceLoop` callers need this ownership too.
1855
- */
1856
1773
  registerPipelineRun?(run: Promise<unknown>, cancel: () => void): () => void;
1857
1774
  startSession(agent: Agent, options: StartSessionOptions): Promise<ActiveSession>;
1858
1775
  startAttachedSession(agent: Agent, options: StartAttachedSessionOptions): Promise<SessionAttachment>;
@@ -1867,28 +1784,14 @@ interface Runtime extends RuntimeServiceLifecycle {
1867
1784
  startTurn(request: StartTurnRequest): Promise<Turn>;
1868
1785
  endTurn(sessionId: SessionId, turnId: TurnId, request: EndTurnRequest): Promise<TerminalTurn>;
1869
1786
  updateTurnStatus(sessionId: SessionId, turnId: TurnId, status: TurnStatus): Promise<Turn>;
1870
- /** Marks durable persistence health for the live attachment without changing lease ownership. */
1871
1787
  setPersistenceHealth(sessionId: SessionId, degraded: boolean): void;
1872
- /**
1873
- * Serializes memory writes and session-end purge for one session. Built-in
1874
- * runtimes provide this; custom runtimes may omit it for compatibility.
1875
- */
1876
1788
  runSessionMemoryOperation?<T>(sessionId: SessionId, operation: () => Promise<T>): Promise<T>;
1877
1789
  startToolCall(toolCall: QueuedToolCall): Promise<RunningToolCall>;
1878
1790
  finishToolCall(toolCall: TerminalToolCall): Promise<TerminalToolCall>;
1879
1791
  recoverToolCalls(sessionId: SessionId): Promise<readonly ToolCall[]>;
1880
1792
  checkpointTurnInterruption(sessionId: SessionId, turnId: TurnId, reason: TurnCancellationReason): Promise<Turn>;
1881
- /** Session-relative monotonic offset used for turn and media timing. */
1882
1793
  sessionClockMs(id: SessionId): number;
1883
- /** Persists a completed tool call as part of runtime session state. */
1884
1794
  recordToolCall(toolCall: ToolCall): Promise<void>;
1885
- /**
1886
- * Optional health check. The runtime exposes this so the
1887
- * `NodeMediaPlane` (or any other host) can surface readiness via
1888
- * `/healthz`. Returns `ok: true` when the underlying store + leases
1889
- * are healthy; the host responds with HTTP 200 vs 503. Best-effort:
1890
- * a throw produces `ok: false`.
1891
- */
1892
1795
  healthCheck(): Promise<HealthSnapshot>;
1893
1796
  inspectSession(id: SessionId): Promise<SessionSnapshot>;
1894
1797
  readonly durablePolicy?: DurableRuntimePolicy;
@@ -1971,14 +1874,18 @@ declare function isTerminalTurn(turn: Turn): turn is TerminalTurn;
1971
1874
 
1972
1875
  interface ProviderClock {
1973
1876
  now(): Timestamp;
1877
+ /** Optional for backward-compatible injected clocks; adapters fall back to performance.now(). */
1878
+ monotonicNowMs?(): number;
1974
1879
  }
1975
1880
 
1881
+ declare const TWILIO_MAX_AUDIO_EVENT_BYTES = 65536;
1882
+
1976
1883
  interface TwilioMediaStreamSocket {
1977
1884
  readonly readyState: number;
1978
1885
  readonly bufferedAmount?: number;
1979
1886
  send(data: string): void;
1980
1887
  close(code?: number, reason?: string): void;
1981
- on(event: "message", handler: (data: WebSocket.RawData) => void): this;
1888
+ on(event: "message", handler: (data: WebSocket__default.RawData) => void): this;
1982
1889
  on(event: "close", handler: () => void): this;
1983
1890
  on(event: "error", handler: (error: Error) => void): this;
1984
1891
  }
@@ -1988,7 +1895,6 @@ interface TwilioMediaStreamCallHandleOptions {
1988
1895
  readonly sessionId: SessionId;
1989
1896
  readonly inputFormat?: AudioFormat;
1990
1897
  readonly outputFormat?: AudioFormat;
1991
- /** Values authenticated by the host and expected in Twilio's start frame. */
1992
1898
  readonly expectedTwilioCallSid?: string;
1993
1899
  readonly expectedAccountSid?: string;
1994
1900
  readonly clock?: ProviderClock;
@@ -1998,11 +1904,13 @@ declare class TwilioMediaStreamCallHandle implements CallHandle {
1998
1904
  #private;
1999
1905
  readonly options: TwilioMediaStreamCallHandleOptions;
2000
1906
  readonly events: AsyncIterable<InboundMediaEvent>;
1907
+ readonly remoteHangup: Promise<void>;
2001
1908
  constructor(options: TwilioMediaStreamCallHandleOptions);
2002
1909
  readonly callId: CallId;
2003
1910
  send(event: OutputMediaEvent): Promise<boolean>;
2004
1911
  clear(): Promise<void>;
2005
1912
  close(reason: StreamEndReason): Promise<void>;
1913
+ endInput(reason: StreamEndReason): Promise<void>;
2006
1914
  confirmPlayout(markId: string, timeoutMs: number): Promise<boolean>;
2007
1915
  }
2008
1916
 
@@ -2051,27 +1959,33 @@ declare class TwilioMediaStreamsProvider implements TelephonyProvider {
2051
1959
  }
2052
1960
  declare function createTwilioMediaStreamsProvider(): TwilioMediaStreamsProvider;
2053
1961
 
2054
- declare const WEB_CLIENT_AUDIO_CLOSE_CODES: {
2055
- readonly protocol: 4400;
2056
- readonly heartbeatTimeout: 4408;
2057
- readonly superseded: 4409;
2058
- readonly maxDuration: 4410;
2059
- readonly resourceLimit: 4413;
2060
- readonly operatorTerminated: 4500;
2061
- };
2062
1962
  declare const WEB_CLIENT_AUDIO_DEFAULTS: {
2063
- readonly heartbeatIntervalMs: 5000;
2064
- readonly heartbeatTimeoutMs: 10000;
2065
- readonly maxSessionDurationMs: number;
2066
- readonly maxPendingEvents: 512;
2067
- readonly maxInputFramesPerSecond: 200;
2068
- readonly maxPendingAcks: 128;
1963
+ heartbeatIntervalMs: number;
1964
+ heartbeatTimeoutMs: number;
1965
+ maxSessionDurationMs: number;
1966
+ maxBinaryFrameBytes: number;
1967
+ maxInputBytesPerSecond: number;
1968
+ maxPendingEvents: number;
1969
+ maxInputFramesPerSecond: number;
1970
+ maxPendingAcks: number;
2069
1971
  };
1972
+
1973
+ declare const WEB_CLIENT_AUDIO_CLOSE_CODES: {
1974
+ protocol: number;
1975
+ heartbeatTimeout: number;
1976
+ superseded: number;
1977
+ maxDuration: number;
1978
+ resourceLimit: number;
1979
+ operatorTerminated: number;
1980
+ };
1981
+ declare const WEB_CLIENT_AUDIO_ACK_RETENTION_MS = 60000;
1982
+
2070
1983
  interface WebClientAudioSocket {
2071
1984
  readonly readyState: number;
2072
1985
  readonly bufferedAmount?: number;
2073
1986
  send(data: string | Buffer): void;
2074
1987
  close(code?: number, reason?: string): void;
1988
+ terminate?(): void;
2075
1989
  on(event: "message", handler: (data: WebSocket.RawData, isBinary: boolean) => void): this;
2076
1990
  on(event: "close", handler: (code: number, reason: Buffer) => void): this;
2077
1991
  on(event: "error", handler: (error: Error) => void): this;
@@ -2113,57 +2027,27 @@ interface WebClientAudioCallHandleOptions {
2113
2027
  readonly onConnectionEvent?: (event: ConnectionObservabilityEvent) => void;
2114
2028
  readonly onClosed?: () => void;
2115
2029
  }
2116
- declare class WebClientAudioCallHandle implements CallHandle {
2117
- #private;
2030
+ interface WebClientAudioCallHandle extends CallHandle {
2118
2031
  readonly callId: CallId;
2119
2032
  readonly events: AsyncIterable<InboundMediaEvent>;
2120
- constructor(options: WebClientAudioCallHandleOptions);
2121
2033
  send(event: OutputMediaEvent): Promise<boolean>;
2122
2034
  deliverText(turnId: TurnId, sequence: number, text: string): Promise<boolean>;
2123
2035
  clear(): Promise<void>;
2036
+ endInput(reason: StreamEndReason): Promise<void>;
2124
2037
  close(reason: StreamEndReason): Promise<void>;
2125
2038
  terminate(code: number, reason: string): void;
2126
2039
  confirmPlayout(markId: string, timeoutMs: number): Promise<boolean>;
2127
2040
  }
2041
+ declare const WebClientAudioCallHandle: {
2042
+ new (options: WebClientAudioCallHandleOptions): WebClientAudioCallHandle;
2043
+ };
2128
2044
  interface WebClientAudioProviderOptions extends Omit<WebClientAudioCallHandleOptions, "socket" | "callId" | "sessionId" | "onClosed" | "expectedMode"> {
2129
2045
  }
2130
- declare class WebClientAudioProvider implements TelephonyProvider {
2131
- #private;
2046
+ interface WebClientAudioProvider extends TelephonyProvider {
2132
2047
  readonly name: "web-client-audio";
2133
- readonly kind = "telephony";
2134
- readonly version = "0.1.0";
2135
- readonly capabilities: {
2136
- streaming: {
2137
- input: true;
2138
- output: true;
2139
- native: true;
2140
- };
2141
- cancellation: {
2142
- request: true;
2143
- output: true;
2144
- buffer: true;
2145
- truncation: false;
2146
- };
2147
- transports: "websocket"[];
2148
- audio: {
2149
- input: {
2150
- readonly encoding: "pcm_s16le";
2151
- readonly sampleRateHz: 16000;
2152
- readonly channels: 1;
2153
- }[];
2154
- output: {
2155
- readonly encoding: "pcm_s16le";
2156
- readonly sampleRateHz: 16000;
2157
- readonly channels: 1;
2158
- }[];
2159
- };
2160
- playout: {
2161
- clearBuffer: true;
2162
- acknowledgement: true;
2163
- position: false;
2164
- };
2165
- };
2166
- constructor(options?: WebClientAudioProviderOptions);
2048
+ readonly kind: "telephony";
2049
+ readonly version: "0.1.0";
2050
+ readonly capabilities: ProviderCapabilities;
2167
2051
  dial(): Promise<CallHandle>;
2168
2052
  accept(ctx: Parameters<TelephonyProvider["accept"]>[0]): Promise<CallHandle>;
2169
2053
  attachWebSocket(socket: WebClientAudioSocket, callId: CallId, sessionId: SessionId): void;
@@ -2173,6 +2057,9 @@ declare class WebClientAudioProvider implements TelephonyProvider {
2173
2057
  hangup(callId: CallId): Promise<void>;
2174
2058
  supersede(callId: CallId): Promise<void>;
2175
2059
  }
2060
+ declare const WebClientAudioProvider: {
2061
+ new (options?: WebClientAudioProviderOptions): WebClientAudioProvider;
2062
+ };
2176
2063
  declare function createWebClientAudioProvider(options?: WebClientAudioProviderOptions): WebClientAudioProvider;
2177
2064
 
2178
2065
  interface DeepgramSttProviderOptions {
@@ -2183,8 +2070,9 @@ interface DeepgramSttProviderOptions {
2183
2070
  readonly endpointingMs?: number;
2184
2071
  readonly vadEvents?: boolean;
2185
2072
  readonly punctuate?: boolean;
2186
- readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket;
2073
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2187
2074
  }
2075
+ declare const MAX_PROVIDER_AUDIO_OFFSET_MS = 86400000;
2188
2076
  declare class DeepgramSttProvider implements SpeechToTextProvider {
2189
2077
  #private;
2190
2078
  readonly name: "deepgram";
@@ -2219,6 +2107,72 @@ declare class DeepgramSttProvider implements SpeechToTextProvider {
2219
2107
  }
2220
2108
  declare function createDeepgramSttProvider(options: DeepgramSttProviderOptions): DeepgramSttProvider;
2221
2109
 
2110
+ type CartesiaSttMode = "manual" | "auto";
2111
+ interface CartesiaSttProviderOptions {
2112
+ readonly apiKey: string;
2113
+ readonly url?: string;
2114
+ readonly batchUrl?: string;
2115
+ readonly modelId?: string;
2116
+ readonly batchModelId?: string;
2117
+ readonly allowUnknownModel?: boolean;
2118
+ /** `manual` uses `/stt/websocket`; `auto` uses Ink's native turn detector. */
2119
+ readonly mode?: CartesiaSttMode;
2120
+ /** Used when a session request does not provide a language. Ink 2 can auto-detect. */
2121
+ readonly language?: string;
2122
+ readonly turnStartThreshold?: number;
2123
+ readonly turnEagerEndThreshold?: number;
2124
+ readonly turnEndThreshold?: number;
2125
+ readonly turnEndTimeoutMs?: number;
2126
+ readonly clock?: ProviderClock;
2127
+ readonly fetchImpl?: typeof fetch;
2128
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2129
+ }
2130
+ declare class CartesiaSttProvider implements SpeechToTextProvider {
2131
+ #private;
2132
+ readonly name: "cartesia-stt";
2133
+ readonly kind = "stt";
2134
+ readonly version = "0.1.0";
2135
+ readonly capabilities: {
2136
+ streaming: {
2137
+ input: true;
2138
+ output: true;
2139
+ native: true;
2140
+ };
2141
+ batch: {
2142
+ input: true;
2143
+ output: true;
2144
+ };
2145
+ cancellation: {
2146
+ request: true;
2147
+ output: false;
2148
+ buffer: false;
2149
+ truncation: false;
2150
+ };
2151
+ transports: ("http" | "websocket")[];
2152
+ audio: {
2153
+ input: {
2154
+ readonly encoding: "pcm_s16le";
2155
+ readonly sampleRateHz: 16000;
2156
+ readonly channels: 1;
2157
+ }[];
2158
+ };
2159
+ models: readonly ["ink-2", "ink-preview", "ink-whisper-2025-06-04"];
2160
+ batchModels: readonly ["ink-whisper"];
2161
+ turnDetection: ("manual" | "provider")[];
2162
+ metadata: {
2163
+ realtimeModels: string[];
2164
+ autoTurnModels: string[];
2165
+ batchModels: string[];
2166
+ partialTranscripts: boolean;
2167
+ manualFinalize: boolean;
2168
+ };
2169
+ };
2170
+ constructor(options: CartesiaSttProviderOptions);
2171
+ open(request: SttOpenRequest): Promise<SttStream>;
2172
+ transcribe(request: SttBatchTranscriptionRequest): Promise<SttBatchTranscription>;
2173
+ }
2174
+ declare function createCartesiaSttProvider(options: CartesiaSttProviderOptions): CartesiaSttProvider;
2175
+
2222
2176
  type SarvamOutputMode = "transcribe" | "translate" | "verbatim" | "translit" | "codemix";
2223
2177
  interface SarvamSttProviderOptions {
2224
2178
  readonly apiKey: string;
@@ -2230,7 +2184,7 @@ interface SarvamSttProviderOptions {
2230
2184
  readonly flushSignal?: boolean;
2231
2185
  readonly inputAudioCodec?: "pcm_s16le" | "pcm_l16" | "pcm_raw";
2232
2186
  readonly clock?: ProviderClock;
2233
- readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket;
2187
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2234
2188
  }
2235
2189
  declare class SarvamSttProvider implements SpeechToTextProvider {
2236
2190
  #private;
@@ -2263,7 +2217,7 @@ declare class SarvamSttProvider implements SpeechToTextProvider {
2263
2217
  })[];
2264
2218
  };
2265
2219
  models: readonly ["saaras:v3", "saaras:v4"];
2266
- turnDetection: ("vad" | "manual")[];
2220
+ turnDetection: ("manual" | "vad")[];
2267
2221
  metadata: {
2268
2222
  interimResults: boolean;
2269
2223
  outputModes: string[];
@@ -2274,38 +2228,189 @@ declare class SarvamSttProvider implements SpeechToTextProvider {
2274
2228
  }
2275
2229
  declare function createSarvamSttProvider(options: SarvamSttProviderOptions): SarvamSttProvider;
2276
2230
 
2277
- type ElevenLabsSttCommitStrategy = "manual" | "vad";
2278
- interface ElevenLabsSttProviderOptions {
2231
+ interface SarvamTtsProviderOptions {
2279
2232
  readonly apiKey: string;
2280
2233
  readonly url?: string;
2281
- readonly allowUnknownModel?: boolean;
2234
+ readonly voiceId?: string;
2282
2235
  readonly modelId?: string;
2283
- readonly commitStrategy?: ElevenLabsSttCommitStrategy;
2284
- readonly includeTimestamps?: boolean;
2285
- readonly includeLanguageDetection?: boolean;
2286
- readonly vadThreshold?: number;
2287
- readonly vadSilenceThresholdSecs?: number;
2236
+ readonly language?: string;
2237
+ /** Provider pace. Sarvam Bulbul v3 and v4 Flash accept 0.5 through 2.0. */
2238
+ readonly pace?: number;
2239
+ /** Bulbul v3 temperature; Bulbul v4 Flash does not accept this option. */
2240
+ readonly temperature?: number;
2241
+ readonly minBufferSize?: number;
2242
+ readonly maxChunkLength?: number;
2243
+ readonly pronunciationDictionaryId?: string;
2244
+ readonly keepAliveIntervalMs?: number;
2288
2245
  readonly clock?: ProviderClock;
2289
- readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket;
2246
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2290
2247
  }
2291
- declare class ElevenLabsSttProvider implements SpeechToTextProvider {
2248
+ interface SarvamTtsStreamOptions {
2249
+ readonly clock: ProviderClock;
2250
+ readonly model: string;
2251
+ readonly language: string;
2252
+ readonly voice: string;
2253
+ readonly pace: number;
2254
+ readonly temperature?: number;
2255
+ readonly minBufferSize: number;
2256
+ readonly maxChunkLength: number;
2257
+ readonly pronunciationDictionaryId?: string;
2258
+ readonly keepAliveIntervalMs: number;
2259
+ }
2260
+ declare class SarvamTtsProvider implements IncrementalTextToSpeechProvider {
2292
2261
  #private;
2293
- readonly name: "elevenlabs-stt-realtime";
2294
- readonly kind = "stt";
2262
+ readonly name: "sarvam-tts";
2263
+ readonly kind = "tts";
2295
2264
  readonly version = "0.1.0";
2296
- readonly capabilities: {
2297
- streaming: {
2298
- input: true;
2299
- output: true;
2300
- native: true;
2301
- };
2302
- cancellation: {
2303
- request: true;
2265
+ readonly capabilities: ProviderCapabilities;
2266
+ constructor(options: SarvamTtsProviderOptions);
2267
+ get configuredModel(): string;
2268
+ get configuredLanguage(): string;
2269
+ get languageWasExplicitlyConfigured(): boolean;
2270
+ get configuredVoice(): string | undefined;
2271
+ supportsVoice(voice: string, model?: string): boolean;
2272
+ supportsLanguage(language: string, model?: string): boolean;
2273
+ synthesize(request: TtsSynthesisRequest): Promise<TtsStream>;
2274
+ openSession(request: TtsSessionOpenRequest): Promise<SarvamTtsStream>;
2275
+ }
2276
+ declare class SarvamTtsStream implements TtsSession {
2277
+ #private;
2278
+ readonly events: AsyncIterable<TtsEvent>;
2279
+ constructor(socket: WebSocket__default, request: TtsSessionOpenRequest, options: SarvamTtsStreamOptions);
2280
+ sendText(text: string): Promise<void>;
2281
+ flush(): Promise<TtsFlushResult>;
2282
+ finish(): Promise<void>;
2283
+ keepAlive(): Promise<void>;
2284
+ cancel(): Promise<void>;
2285
+ }
2286
+ declare function createSarvamTtsProvider(options: SarvamTtsProviderOptions): SarvamTtsProvider;
2287
+
2288
+ declare const SARVAM_TTS_V4_FLASH_MODEL: "bulbul:v4-flash";
2289
+
2290
+ interface SarvamTtsHttpProviderOptions {
2291
+ readonly apiKey: string;
2292
+ readonly url?: string;
2293
+ readonly voiceId?: string;
2294
+ readonly modelId?: string;
2295
+ readonly language?: string;
2296
+ /** Provider pace. Sarvam Bulbul v3 and v4 Flash accept 0.5 through 2.0. */
2297
+ readonly pace?: number;
2298
+ /** HTTP temperature tuning for Sarvam Bulbul v3 and v4 Flash (0.01 through 1.0). */
2299
+ readonly temperature?: number;
2300
+ readonly pronunciationDictionaryId?: string;
2301
+ /** Maximum time allowed for request headers and the complete response. Defaults to 10 minutes. */
2302
+ readonly requestTimeoutMs?: number;
2303
+ /** Maximum wait for response progress after headers arrive. Defaults to 30 seconds. */
2304
+ readonly responseIdleTimeoutMs?: number;
2305
+ readonly clock?: ProviderClock;
2306
+ /** Fetch override for tests or custom transports. */
2307
+ readonly fetchImpl?: typeof fetch;
2308
+ }
2309
+
2310
+ declare class SarvamTtsRestProvider implements TextToSpeechProvider {
2311
+ #private;
2312
+ readonly name: "sarvam-tts";
2313
+ readonly kind = "tts";
2314
+ readonly version = "0.1.0";
2315
+ readonly capabilities: ProviderCapabilities;
2316
+ constructor(options: SarvamTtsHttpProviderOptions);
2317
+ get configuredModel(): string;
2318
+ get configuredLanguage(): string;
2319
+ get languageWasExplicitlyConfigured(): boolean;
2320
+ get configuredVoice(): string | undefined;
2321
+ supportsVoice(voice: string, model?: string): boolean;
2322
+ supportsLanguage(language: string, model?: string): boolean;
2323
+ synthesize(request: TtsSynthesisRequest): Promise<TtsStream>;
2324
+ }
2325
+ declare class SarvamTtsHttpStreamProvider implements TextToSpeechProvider {
2326
+ #private;
2327
+ readonly name: "sarvam-tts";
2328
+ readonly kind = "tts";
2329
+ readonly version = "0.1.0";
2330
+ readonly capabilities: ProviderCapabilities;
2331
+ constructor(options: SarvamTtsHttpProviderOptions);
2332
+ get configuredModel(): string;
2333
+ get configuredLanguage(): string;
2334
+ get languageWasExplicitlyConfigured(): boolean;
2335
+ get configuredVoice(): string | undefined;
2336
+ supportsVoice(voice: string, model?: string): boolean;
2337
+ supportsLanguage(language: string, model?: string): boolean;
2338
+ synthesize(request: TtsSynthesisRequest): Promise<TtsStream>;
2339
+ }
2340
+ declare function createSarvamTtsRestProvider(options: SarvamTtsHttpProviderOptions): SarvamTtsRestProvider;
2341
+ declare function createSarvamTtsHttpStreamProvider(options: SarvamTtsHttpProviderOptions): SarvamTtsHttpStreamProvider;
2342
+
2343
+ type ElevenLabsBatchTimestampGranularity = "none" | "word" | "character";
2344
+ type ElevenLabsEntityDetection = string | readonly string[];
2345
+ interface ElevenLabsBatchSttRequest {
2346
+ readonly audio: Uint8Array;
2347
+ readonly format: AudioFormat;
2348
+ readonly model?: string;
2349
+ readonly language?: string;
2350
+ readonly keyterms?: readonly string[];
2351
+ readonly tagAudioEvents?: boolean;
2352
+ readonly diarize?: boolean;
2353
+ readonly numSpeakers?: number;
2354
+ readonly timestampsGranularity?: ElevenLabsBatchTimestampGranularity;
2355
+ readonly diarizationThreshold?: number;
2356
+ readonly entityDetection?: ElevenLabsEntityDetection;
2357
+ readonly noVerbatim?: boolean;
2358
+ readonly signal?: AbortSignal;
2359
+ }
2360
+ interface ElevenLabsBatchSttResult {
2361
+ readonly modelId: string;
2362
+ readonly text: string;
2363
+ readonly languageCode?: string;
2364
+ readonly languageProbability?: number;
2365
+ readonly words: readonly Readonly<Record<string, unknown>>[];
2366
+ readonly entities?: readonly Readonly<Record<string, unknown>>[];
2367
+ }
2368
+
2369
+ type ElevenLabsSttCommitStrategy = "manual" | "vad";
2370
+
2371
+ interface ElevenLabsSttProviderOptions {
2372
+ readonly apiKey: string;
2373
+ readonly url?: string;
2374
+ readonly batchUrl?: string;
2375
+ readonly allowUnknownModel?: boolean;
2376
+ readonly modelId?: string;
2377
+ readonly commitStrategy?: ElevenLabsSttCommitStrategy;
2378
+ readonly includeTimestamps?: boolean;
2379
+ readonly includeLanguageDetection?: boolean;
2380
+ readonly vadThreshold?: number;
2381
+ readonly vadSilenceThresholdSecs?: number;
2382
+ readonly secondaryLanguages?: readonly string[];
2383
+ readonly minSpeechDurationMs?: number;
2384
+ readonly minSilenceDurationMs?: number;
2385
+ readonly noVerbatim?: boolean;
2386
+ /** Detect bounded entity records on committed realtime transcript segments. */
2387
+ readonly entityDetection?: ElevenLabsEntityDetection;
2388
+ readonly filterBackgroundAudio?: boolean;
2389
+ readonly enableLogging?: boolean;
2390
+ /** Context sent with the first audio frame; useful after reconnects. */
2391
+ readonly previousText?: string;
2392
+ readonly clock?: ProviderClock;
2393
+ readonly fetchImpl?: typeof fetch;
2394
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2395
+ }
2396
+ declare class ElevenLabsSttProvider implements SpeechToTextProvider {
2397
+ #private;
2398
+ readonly name: "elevenlabs-stt-realtime";
2399
+ readonly kind = "stt";
2400
+ readonly version = "0.1.0";
2401
+ readonly capabilities: {
2402
+ streaming: {
2403
+ input: true;
2404
+ output: true;
2405
+ native: true;
2406
+ };
2407
+ cancellation: {
2408
+ request: true;
2304
2409
  output: false;
2305
2410
  buffer: false;
2306
2411
  truncation: false;
2307
2412
  };
2308
- transports: "websocket"[];
2413
+ transports: ("http" | "websocket")[];
2309
2414
  audio: {
2310
2415
  input: readonly [{
2311
2416
  readonly encoding: "pcm_s16le";
@@ -2333,18 +2438,311 @@ declare class ElevenLabsSttProvider implements SpeechToTextProvider {
2333
2438
  readonly channels: 1;
2334
2439
  }];
2335
2440
  };
2336
- models: readonly ["scribe_v2_realtime"];
2337
- turnDetection: ("vad" | "manual")[];
2441
+ models: readonly ["scribe_v2_realtime", "scribe_v2", "scribe_v2_medical"];
2442
+ turnDetection: ("manual" | "vad")[];
2338
2443
  metadata: {
2339
2444
  realtimeModel: string;
2445
+ realtimeModels: string[];
2446
+ batchModels: string[];
2447
+ batchTranscription: boolean;
2340
2448
  partialTranscripts: boolean;
2341
2449
  };
2342
2450
  };
2343
2451
  constructor(options: ElevenLabsSttProviderOptions);
2344
2452
  open(request: SttOpenRequest): Promise<SttStream>;
2453
+ transcribe(request: ElevenLabsBatchSttRequest): Promise<ElevenLabsBatchSttResult>;
2454
+ transcribe(request: SttBatchTranscriptionRequest): Promise<SttBatchTranscription>;
2345
2455
  }
2346
2456
  declare function createElevenLabsSttProvider(options: ElevenLabsSttProviderOptions): ElevenLabsSttProvider;
2347
2457
 
2458
+ /**
2459
+ * Vendor facts that change on the provider's release schedule rather than ours:
2460
+ * model catalogs and wire protocol versions.
2461
+ *
2462
+ * These deliberately live at the adapter edge instead of in `@tvic/core`. A model
2463
+ * list is not a runtime contract, it is dated evidence. Compiling it into core made
2464
+ * two things invisible: how old the claim was, and the fact that a vendor deprecating
2465
+ * a model silently turns `capabilities.models` into a false statement.
2466
+ *
2467
+ * Every entry carries the date it was verified and the document it came from.
2468
+ * Reverify before relying on an entry for a production or purchasing decision, and
2469
+ * treat a stale `verifiedAt` as a reason to omit a capability rather than assert it.
2470
+ */
2471
+ interface ProviderCatalogEntry {
2472
+ /** ISO date the model list below was last checked against `source`. */
2473
+ readonly verifiedAt: string;
2474
+ /** Official provider documentation the entry was read from. */
2475
+ readonly source: string;
2476
+ /** Model used when the caller does not choose one. */
2477
+ readonly defaultModel: string;
2478
+ /** Models this adapter is known to work with, not the vendor's full catalog. */
2479
+ readonly models: readonly string[];
2480
+ /** Optional transport-specific model groups when one adapter spans transports. */
2481
+ readonly realtimeModels?: readonly string[];
2482
+ readonly preRecordedModels?: readonly string[];
2483
+ readonly syncModels?: readonly string[];
2484
+ /** Models supported by a separate complete-input/batch contract, when present. */
2485
+ readonly batchModels?: readonly string[];
2486
+ /** Official documentation for the separate batch contract, when present. */
2487
+ readonly batchSource?: string;
2488
+ }
2489
+ /**
2490
+ * TVIC maturity labels are our release claim, not a vendor guarantee. They are
2491
+ * ordered from least to most supported as deferred, experimental, validated,
2492
+ * and stable. `validated` means the exact adapter/model path has passed the
2493
+ * small-scale live evidence profile; it is not an uptime or compatibility SLA.
2494
+ */
2495
+ declare const PROVIDER_STABILITY_LEVELS: readonly ["deferred", "experimental", "validated", "stable"];
2496
+ type ProviderStability = (typeof PROVIDER_STABILITY_LEVELS)[number];
2497
+ declare const PROVIDER_STABILITY: Readonly<{
2498
+ readonly deepgram: "experimental";
2499
+ readonly cartesiaStt: "experimental";
2500
+ readonly sarvam: "experimental";
2501
+ readonly elevenlabsStt: "experimental";
2502
+ readonly assemblyai: "experimental";
2503
+ readonly soniox: "experimental";
2504
+ readonly sarvamTts: "experimental";
2505
+ readonly groq: "experimental";
2506
+ readonly openaiResponses: "experimental";
2507
+ readonly cartesia: "experimental";
2508
+ readonly elevenlabs: "experimental";
2509
+ readonly webClientAudio: "stable";
2510
+ readonly twilio: "stable";
2511
+ }>;
2512
+ declare const PROVIDER_CATALOG: {
2513
+ readonly deepgram: {
2514
+ readonly verifiedAt: "2026-09-15";
2515
+ readonly source: "https://developers.deepgram.com/docs/models-languages-overview";
2516
+ readonly defaultModel: "nova-3";
2517
+ readonly models: readonly ["nova-3", "nova-2"];
2518
+ };
2519
+ readonly cartesiaStt: {
2520
+ readonly verifiedAt: "2026-09-27";
2521
+ readonly source: "https://docs.cartesia.ai/build-with-cartesia/stt/latest";
2522
+ readonly defaultModel: "ink-2";
2523
+ readonly models: readonly ["ink-2", "ink-preview", "ink-whisper-2025-06-04"];
2524
+ readonly batchModels: readonly ["ink-whisper"];
2525
+ readonly batchSource: "https://docs.cartesia.ai/api-reference/stt/transcribe";
2526
+ };
2527
+ readonly sarvam: {
2528
+ readonly verifiedAt: "2026-09-15";
2529
+ readonly source: "https://docs.sarvam.ai/api-reference/speech-to-text/transcribe/ws";
2530
+ readonly defaultModel: "saaras:v3";
2531
+ readonly models: readonly ["saaras:v3", "saaras:v4"];
2532
+ };
2533
+ readonly sarvamTts: {
2534
+ readonly verifiedAt: "2026-10-09";
2535
+ readonly source: "https://docs.sarvam.ai/api/getting-started/models/bulbul";
2536
+ readonly defaultModel: "bulbul:v3";
2537
+ readonly models: readonly ["bulbul:v3", "bulbul:v4-flash"];
2538
+ };
2539
+ readonly cartesia: {
2540
+ readonly verifiedAt: "2026-09-25";
2541
+ readonly source: "https://docs.cartesia.ai/build-with-cartesia/tts-models/latest";
2542
+ readonly defaultModel: "sonic-3.6";
2543
+ readonly models: readonly ["sonic-3.6", "sonic-3.6-2026-08-27", "sonic-preview", "sonic-3.5", "sonic-3.5-2026-05-04", "sonic-3", "sonic-3-2026-01-12"];
2544
+ };
2545
+ readonly elevenlabs: {
2546
+ readonly verifiedAt: "2026-09-25";
2547
+ readonly source: "https://elevenlabs.io/docs/overview/models";
2548
+ readonly defaultModel: "eleven_flash_v2_5";
2549
+ readonly models: readonly ["eleven_flash_v2_5", "eleven_flash_v2", "eleven_v3", "eleven_v3_conversational", "eleven_multilingual_v2", "eleven_turbo_v2_5", "eleven_turbo_v2"];
2550
+ };
2551
+ readonly elevenlabsStt: {
2552
+ readonly verifiedAt: "2026-09-24";
2553
+ readonly source: "https://elevenlabs.io/docs/overview/models";
2554
+ readonly defaultModel: "scribe_v2_realtime";
2555
+ readonly models: readonly ["scribe_v2_realtime", "scribe_v2", "scribe_v2_medical"];
2556
+ };
2557
+ readonly assemblyai: {
2558
+ readonly verifiedAt: "2026-09-27";
2559
+ readonly source: "https://www.assemblyai.com/docs/streaming/select-the-speech-model";
2560
+ readonly defaultModel: "universal-3-6-pro";
2561
+ readonly models: readonly string[];
2562
+ readonly realtimeModels: readonly ["universal-3-6-pro", "universal-3-5-pro", "universal-streaming-english", "universal-streaming-multilingual"];
2563
+ readonly preRecordedModels: readonly ["universal-3-5-pro", "universal-2"];
2564
+ readonly syncModels: readonly ["universal-3-5-pro"];
2565
+ };
2566
+ readonly soniox: {
2567
+ readonly verifiedAt: "2026-08-20";
2568
+ readonly source: "https://soniox.com/docs/api-reference/stt/websocket-api";
2569
+ readonly defaultModel: "stt-rt-v5";
2570
+ readonly models: readonly ["stt-rt-v5"];
2571
+ };
2572
+ readonly groq: {
2573
+ readonly verifiedAt: "2026-09-15";
2574
+ readonly source: "https://console.groq.com/docs/models";
2575
+ readonly defaultModel: "openai/gpt-oss-20b";
2576
+ readonly models: readonly ["openai/gpt-oss-20b", "openai/gpt-oss-120b"];
2577
+ };
2578
+ readonly openaiResponses: {
2579
+ readonly verifiedAt: "2026-07-24";
2580
+ readonly source: "https://platform.openai.com/docs/models";
2581
+ readonly defaultModel: "gpt-4.1-mini";
2582
+ readonly models: readonly ["gpt-5", "gpt-5-mini", "gpt-4.1", "gpt-4.1-mini"];
2583
+ };
2584
+ };
2585
+ /**
2586
+ * Provider wire protocol versions. Separate from the model catalog because a
2587
+ * protocol version changes adapter parsing, not just which model is selected.
2588
+ */
2589
+ declare const PROVIDER_API_VERSIONS: {
2590
+ readonly cartesia: "2026-08-14";
2591
+ readonly cartesiaStt: "2026-08-14";
2592
+ };
2593
+ /**
2594
+ * TVIC's own adapter tuning. These are our decisions about how to drive a provider,
2595
+ * not facts about the provider, so they are not dated catalog entries.
2596
+ */
2597
+ declare const ADAPTER_DEFAULTS: {
2598
+ readonly deepgram: {
2599
+ readonly endpointingMs: 300;
2600
+ readonly vadEvents: true;
2601
+ readonly punctuate: true;
2602
+ };
2603
+ readonly sarvam: {
2604
+ readonly mode: "transcribe";
2605
+ readonly highVadSensitivity: true;
2606
+ readonly vadSignals: true;
2607
+ readonly flushSignal: true;
2608
+ readonly inputAudioCodec: "pcm_s16le";
2609
+ };
2610
+ readonly sarvamTts: {
2611
+ readonly language: "en-IN";
2612
+ readonly voice: "shubh";
2613
+ readonly pace: 1;
2614
+ readonly temperature: 0.6;
2615
+ readonly minBufferSize: 50;
2616
+ readonly maxChunkLength: 150;
2617
+ };
2618
+ readonly cartesia: {
2619
+ readonly language: "en";
2620
+ };
2621
+ readonly cartesiaStt: {
2622
+ readonly mode: "manual";
2623
+ };
2624
+ };
2625
+
2626
+ interface AssemblyAiSpeakerOptions {
2627
+ readonly minSpeakersExpected?: number;
2628
+ readonly maxSpeakersExpected?: number;
2629
+ readonly includeSpeakerConfidence?: boolean;
2630
+ }
2631
+ type AssemblyAiPiiSubstitution = "entity_name" | "hash";
2632
+ type AssemblyAiRedactedAudioQuality = "mp3" | "wav";
2633
+ interface AssemblyAiRedactPiiAudioOptions {
2634
+ readonly overrideAudioRedactionMethod?: "beep" | "silence";
2635
+ readonly returnRedactedNoSpeechAudio?: boolean;
2636
+ }
2637
+ interface AssemblyAiPreRecordedSttRequest {
2638
+ /** A complete local file or encoded media payload. */
2639
+ readonly audio?: Uint8Array;
2640
+ /** A public URL or AssemblyAI upload URL. Exactly one audio source is required. */
2641
+ readonly audioUrl?: string;
2642
+ /** Content type used when `audio` is uploaded. */
2643
+ readonly mimeType?: string;
2644
+ /** Filename used as the multipart upload filename. */
2645
+ readonly fileName?: string;
2646
+ /** Convenience single-model selector. Cannot be combined with speechModels. */
2647
+ readonly model?: string;
2648
+ /** Ordered model candidates. AssemblyAI may fall back to the next model. */
2649
+ readonly speechModels?: readonly string[];
2650
+ readonly language?: string;
2651
+ readonly languageDetection?: boolean;
2652
+ readonly prompt?: string;
2653
+ readonly vocabulary?: readonly string[];
2654
+ readonly punctuate?: boolean;
2655
+ readonly formatText?: boolean;
2656
+ readonly disfluencies?: boolean;
2657
+ readonly speakerLabels?: boolean;
2658
+ readonly speakersExpected?: number;
2659
+ readonly speakerOptions?: AssemblyAiSpeakerOptions;
2660
+ /** Current AssemblyAI name for separate-channel transcription. */
2661
+ readonly multichannel?: boolean;
2662
+ /** @deprecated Use `multichannel`. Kept as a compatibility alias. */
2663
+ readonly dualChannel?: boolean;
2664
+ readonly redactPii?: boolean;
2665
+ readonly redactPiiPolicies?: readonly string[];
2666
+ readonly redactPiiSub?: AssemblyAiPiiSubstitution;
2667
+ readonly redactPiiAudio?: boolean;
2668
+ readonly redactPiiAudioQuality?: AssemblyAiRedactedAudioQuality;
2669
+ readonly redactPiiAudioOptions?: AssemblyAiRedactPiiAudioOptions;
2670
+ readonly redactPiiReturnUnredacted?: boolean;
2671
+ readonly redactStaticEntities?: Readonly<Record<string, readonly string[]>>;
2672
+ readonly speechThreshold?: number;
2673
+ readonly webhookUrl?: string;
2674
+ readonly webhookAuthHeaderName?: string;
2675
+ readonly webhookAuthHeaderValue?: string;
2676
+ readonly signal?: AbortSignal;
2677
+ readonly pollIntervalMs?: number;
2678
+ readonly pollTimeoutMs?: number;
2679
+ }
2680
+ interface AssemblyAiSyncSttRequest {
2681
+ /** Raw PCM16LE bytes. The format is sent in the Sync config part. */
2682
+ readonly audio: Uint8Array;
2683
+ readonly format: AudioFormat;
2684
+ readonly model?: string;
2685
+ readonly languageCodes?: readonly string[];
2686
+ readonly prompt?: string;
2687
+ readonly vocabulary?: readonly string[];
2688
+ readonly timestamps?: boolean;
2689
+ readonly fileName?: string;
2690
+ readonly signal?: AbortSignal;
2691
+ }
2692
+ interface AssemblyAiSyncLiveSttRequest {
2693
+ /** Async PCM16LE chunks produced while the recording is in progress. */
2694
+ readonly audio: AsyncIterable<Uint8Array>;
2695
+ readonly format: AudioFormat;
2696
+ readonly model?: string;
2697
+ readonly languageCodes?: readonly string[];
2698
+ readonly prompt?: string;
2699
+ readonly vocabulary?: readonly string[];
2700
+ readonly timestamps?: boolean;
2701
+ readonly fileName?: string;
2702
+ readonly signal?: AbortSignal;
2703
+ }
2704
+ interface AssemblyAiTranscriptWord {
2705
+ readonly text: string;
2706
+ readonly start?: number;
2707
+ readonly end?: number;
2708
+ readonly confidence?: number;
2709
+ readonly speaker?: string;
2710
+ readonly [key: string]: unknown;
2711
+ }
2712
+ interface AssemblyAiTranscriptUtterance {
2713
+ readonly text: string;
2714
+ readonly start?: number;
2715
+ readonly end?: number;
2716
+ readonly confidence?: number;
2717
+ readonly speaker?: string;
2718
+ readonly words?: readonly AssemblyAiTranscriptWord[];
2719
+ readonly [key: string]: unknown;
2720
+ }
2721
+ interface AssemblyAiPreRecordedSttResult {
2722
+ readonly id: string;
2723
+ readonly status: "completed";
2724
+ readonly modelId: string;
2725
+ readonly text: string;
2726
+ readonly languageCode?: string;
2727
+ readonly audioDurationMs?: number;
2728
+ readonly audioChannels?: number;
2729
+ readonly confidence?: number;
2730
+ readonly words: readonly AssemblyAiTranscriptWord[];
2731
+ readonly utterances: readonly AssemblyAiTranscriptUtterance[];
2732
+ /** Bounded provider response for fields not yet promoted into the TVIC shape. */
2733
+ readonly providerResponse: Readonly<Record<string, unknown>>;
2734
+ }
2735
+ interface AssemblyAiSyncSttResult {
2736
+ readonly sessionId: string;
2737
+ readonly modelId: string;
2738
+ readonly text: string;
2739
+ readonly confidence?: number;
2740
+ readonly audioDurationMs?: number;
2741
+ readonly requestTimeMs?: number;
2742
+ readonly words: readonly AssemblyAiTranscriptWord[];
2743
+ readonly providerResponse: Readonly<Record<string, unknown>>;
2744
+ }
2745
+
2348
2746
  interface AssemblyAiSttProviderOptions {
2349
2747
  readonly apiKey: string;
2350
2748
  readonly url?: string;
@@ -2353,10 +2751,17 @@ interface AssemblyAiSttProviderOptions {
2353
2751
  readonly formatTurns?: boolean;
2354
2752
  readonly prompt?: string;
2355
2753
  readonly languageDetection?: boolean;
2754
+ readonly speakerLabels?: boolean;
2755
+ readonly maxSpeakers?: number;
2756
+ readonly speakerLabelsRevisionIntervalMs?: number;
2356
2757
  readonly minTurnSilenceMs?: number;
2357
2758
  readonly maxTurnSilenceMs?: number;
2358
2759
  readonly clock?: ProviderClock;
2359
- readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket;
2760
+ readonly preRecordedUrl?: string;
2761
+ readonly uploadUrl?: string;
2762
+ readonly syncUrl?: string;
2763
+ readonly fetchImpl?: typeof fetch;
2764
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2360
2765
  }
2361
2766
  declare class AssemblyAiSttProvider implements SpeechToTextProvider {
2362
2767
  #private;
@@ -2375,7 +2780,7 @@ declare class AssemblyAiSttProvider implements SpeechToTextProvider {
2375
2780
  buffer: false;
2376
2781
  truncation: false;
2377
2782
  };
2378
- transports: "websocket"[];
2783
+ transports: ("http" | "websocket")[];
2379
2784
  audio: {
2380
2785
  input: {
2381
2786
  readonly encoding: "pcm_s16le";
@@ -2383,16 +2788,30 @@ declare class AssemblyAiSttProvider implements SpeechToTextProvider {
2383
2788
  readonly channels: 1;
2384
2789
  }[];
2385
2790
  };
2386
- models: readonly ["u3-rt-pro"];
2791
+ models: readonly string[];
2387
2792
  turnDetection: "stt_endpointing"[];
2388
2793
  metadata: {
2389
- realtimeModel: "u3-rt-pro";
2794
+ realtimeModel: "universal-3-6-pro";
2795
+ realtimeModels: readonly ["universal-3-6-pro", "universal-3-5-pro", "universal-streaming-english", "universal-streaming-multilingual"];
2796
+ preRecordedModels: readonly ["universal-3-5-pro", "universal-2"];
2797
+ syncModels: readonly ["universal-3-5-pro"];
2798
+ preRecordedTranscription: boolean;
2799
+ syncTranscription: boolean;
2800
+ syncLiveTranscription: boolean;
2390
2801
  partialTranscripts: boolean;
2391
2802
  formattedTurns: boolean;
2803
+ speakerDiarization: boolean;
2804
+ multichannelTranscription: boolean;
2805
+ piiRedaction: boolean;
2392
2806
  };
2393
2807
  };
2394
2808
  constructor(options: AssemblyAiSttProviderOptions);
2395
2809
  open(request: SttOpenRequest): Promise<SttStream>;
2810
+ transcribe(request: AssemblyAiPreRecordedSttRequest): Promise<AssemblyAiPreRecordedSttResult>;
2811
+ transcribe(request: SttBatchTranscriptionRequest): Promise<SttBatchTranscription>;
2812
+ transcribeSync(request: AssemblyAiSyncSttRequest): Promise<AssemblyAiSyncSttResult>;
2813
+ transcribeSyncLive(request: AssemblyAiSyncLiveSttRequest): Promise<AssemblyAiSyncSttResult>;
2814
+ warmSync(model?: string, signal?: AbortSignal): Promise<void>;
2396
2815
  }
2397
2816
  declare function createAssemblyAiSttProvider(options: AssemblyAiSttProviderOptions): AssemblyAiSttProvider;
2398
2817
 
@@ -2416,7 +2835,7 @@ interface SonioxSttProviderOptions {
2416
2835
  readonly endpointLatencyAdjustmentLevel?: number;
2417
2836
  readonly enableLanguageIdentification?: boolean;
2418
2837
  readonly clock?: ProviderClock;
2419
- readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket;
2838
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2420
2839
  }
2421
2840
  declare class SonioxSttProvider implements SpeechToTextProvider {
2422
2841
  #private;
@@ -2448,7 +2867,7 @@ declare class SonioxSttProvider implements SpeechToTextProvider {
2448
2867
  }];
2449
2868
  };
2450
2869
  models: readonly ["stt-rt-v5"];
2451
- turnDetection: ("stt_endpointing" | "manual")[];
2870
+ turnDetection: ("manual" | "stt_endpointing")[];
2452
2871
  metadata: {
2453
2872
  realtimeModel: "stt-rt-v5";
2454
2873
  partialTranscripts: boolean;
@@ -2530,6 +2949,17 @@ declare class GroqChatLlmProvider implements LLMProvider {
2530
2949
  }
2531
2950
  declare function createGroqChatLlmProvider(options: GroqChatLlmProviderOptions): GroqChatLlmProvider;
2532
2951
 
2952
+ interface CartesiaGenerationConfig {
2953
+ /** Relative output volume; Cartesia interprets the value for the selected model. */
2954
+ readonly volume?: number;
2955
+ /** Relative speaking speed; a request-level speed overrides this value. */
2956
+ readonly speed?: number;
2957
+ /** Optional Sonic emotion/style control. */
2958
+ readonly emotion?: string;
2959
+ }
2960
+
2961
+ declare const MAX_CARTESIA_INPUT_UTF16_CODE_UNITS = 1048576;
2962
+ declare const MAX_CARTESIA_INPUT_UTF8_BYTES = 4194304;
2533
2963
  interface CartesiaTtsProviderOptions {
2534
2964
  readonly apiKey: string;
2535
2965
  readonly url?: string;
@@ -2538,8 +2968,16 @@ interface CartesiaTtsProviderOptions {
2538
2968
  /** Allows an explicitly configured compatible endpoint/model outside the dated catalog. */
2539
2969
  readonly allowUnknownModel?: boolean;
2540
2970
  readonly language?: string;
2971
+ /** Cartesia locale is mutually exclusive with language. */
2972
+ readonly locale?: string;
2973
+ readonly accent?: string;
2974
+ readonly normalization?: string;
2975
+ readonly generationConfig?: CartesiaGenerationConfig;
2976
+ readonly pronunciationDictId?: string;
2977
+ /** Cartesia server-side continuation buffering; 0 keeps latency under TVIC control. */
2978
+ readonly maxBufferDelayMs?: number;
2541
2979
  readonly clock?: ProviderClock;
2542
- readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket;
2980
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
2543
2981
  }
2544
2982
  declare class CartesiaTtsProvider implements IncrementalTextToSpeechProvider {
2545
2983
  #private;
@@ -2566,152 +3004,75 @@ declare class CartesiaTtsProvider implements IncrementalTextToSpeechProvider {
2566
3004
  readonly channels: 1;
2567
3005
  }[];
2568
3006
  };
2569
- models: readonly ["sonic-3", "sonic-2"];
3007
+ models: readonly ["sonic-3.6", "sonic-3.6-2026-08-27", "sonic-preview", "sonic-3.5", "sonic-3.5-2026-05-04", "sonic-3", "sonic-3-2026-01-12"];
2570
3008
  };
2571
3009
  constructor(options: CartesiaTtsProviderOptions);
3010
+ get configuredModel(): string;
3011
+ get allowUnknownModel(): boolean;
3012
+ get configuredVoice(): string;
3013
+ get configuredLanguage(): string;
2572
3014
  synthesize(request: TtsSynthesisRequest): Promise<TtsStream>;
2573
3015
  openSession(request: TtsSessionOpenRequest): Promise<TtsSession>;
2574
3016
  }
2575
3017
  declare function createCartesiaTtsProvider(options: CartesiaTtsProviderOptions): CartesiaTtsProvider;
2576
3018
 
2577
- /**
2578
- * Vendor facts that change on the provider's release schedule rather than ours:
2579
- * model catalogs and wire protocol versions.
2580
- *
2581
- * These deliberately live at the adapter edge instead of in `@tvic/core`. A model
2582
- * list is not a runtime contract, it is dated evidence. Compiling it into core made
2583
- * two things invisible: how old the claim was, and the fact that a vendor deprecating
2584
- * a model silently turns `capabilities.models` into a false statement.
2585
- *
2586
- * Every entry carries the date it was verified and the document it came from.
2587
- * Reverify before relying on an entry for a production or purchasing decision, and
2588
- * treat a stale `verifiedAt` as a reason to omit a capability rather than assert it.
2589
- */
2590
- interface ProviderCatalogEntry {
2591
- /** ISO date the model list below was last checked against `source`. */
2592
- readonly verifiedAt: string;
2593
- /** Official provider documentation the entry was read from. */
2594
- readonly source: string;
2595
- /** Model used when the caller does not choose one. */
2596
- readonly defaultModel: string;
2597
- /** Models this adapter is known to work with, not the vendor's full catalog. */
2598
- readonly models: readonly string[];
3019
+ type ElevenLabsTtsProtocol = "tts" | "dialogue";
3020
+ type ElevenLabsTextNormalization = "auto" | "on" | "off";
3021
+ interface ElevenLabsPronunciationDictionaryLocator {
3022
+ readonly id: string;
3023
+ readonly versionId?: string;
3024
+ }
3025
+ interface ElevenLabsTtsSendTextOptions {
3026
+ /** Regular TTS only. Requests generation before the normal chunk schedule. */
3027
+ readonly tryTriggerGeneration?: boolean;
3028
+ }
3029
+ interface ElevenLabsDialogueTurnOptions {
3030
+ readonly voiceId?: string;
3031
+ /** Starts a new speaker/prosody turn without closing the socket. */
3032
+ readonly newTurn?: boolean;
2599
3033
  }
2600
- /**
2601
- * TVIC maturity labels are our release claim, not a vendor guarantee.
2602
- * `experimental` means the adapter has deterministic contract coverage but
2603
- * still needs a credential-gated live-service check before it can be called
2604
- * stable in release notes.
2605
- */
2606
- type ProviderStability = "stable" | "experimental" | "deferred";
2607
- declare const PROVIDER_STABILITY: Readonly<{
2608
- readonly deepgram: "experimental";
2609
- readonly sarvam: "experimental";
2610
- readonly elevenlabsStt: "experimental";
2611
- readonly assemblyai: "experimental";
2612
- readonly soniox: "experimental";
2613
- readonly groq: "experimental";
2614
- readonly openaiResponses: "experimental";
2615
- readonly cartesia: "experimental";
2616
- readonly elevenlabs: "experimental";
2617
- readonly webClientAudio: "stable";
2618
- readonly twilio: "stable";
2619
- }>;
2620
- declare const PROVIDER_CATALOG: {
2621
- readonly deepgram: {
2622
- readonly verifiedAt: "2026-09-15";
2623
- readonly source: "https://developers.deepgram.com/docs/models-languages-overview";
2624
- readonly defaultModel: "nova-3";
2625
- readonly models: readonly ["nova-3", "nova-2"];
2626
- };
2627
- readonly sarvam: {
2628
- readonly verifiedAt: "2026-09-15";
2629
- readonly source: "https://docs.sarvam.ai/api-reference/speech-to-text/transcribe/ws";
2630
- readonly defaultModel: "saaras:v3";
2631
- readonly models: readonly ["saaras:v3", "saaras:v4"];
2632
- };
2633
- readonly cartesia: {
2634
- readonly verifiedAt: "2026-09-15";
2635
- readonly source: "https://docs.cartesia.ai/build-with-cartesia/tts-models/older-models";
2636
- readonly defaultModel: "sonic-3";
2637
- readonly models: readonly ["sonic-3", "sonic-2"];
2638
- };
2639
- readonly elevenlabs: {
2640
- readonly verifiedAt: "2026-07-24";
2641
- readonly source: "https://elevenlabs.io/docs/models";
2642
- readonly defaultModel: "eleven_flash_v2_5";
2643
- readonly models: readonly ["eleven_flash_v2_5", "eleven_turbo_v2_5", "eleven_multilingual_v2"];
2644
- };
2645
- readonly elevenlabsStt: {
2646
- readonly verifiedAt: "2026-08-20";
2647
- readonly source: "https://elevenlabs.io/docs/api-reference/speech-to-text/v-1-speech-to-text-realtime";
2648
- readonly defaultModel: "scribe_v2_realtime";
2649
- readonly models: readonly ["scribe_v2_realtime"];
2650
- };
2651
- readonly assemblyai: {
2652
- readonly verifiedAt: "2026-08-20";
2653
- readonly source: "https://www.assemblyai.com/docs/streaming/message-sequence";
2654
- readonly defaultModel: "u3-rt-pro";
2655
- readonly models: readonly ["u3-rt-pro"];
2656
- };
2657
- readonly soniox: {
2658
- readonly verifiedAt: "2026-08-20";
2659
- readonly source: "https://soniox.com/docs/api-reference/stt/websocket-api";
2660
- readonly defaultModel: "stt-rt-v5";
2661
- readonly models: readonly ["stt-rt-v5"];
2662
- };
2663
- readonly groq: {
2664
- readonly verifiedAt: "2026-09-15";
2665
- readonly source: "https://console.groq.com/docs/models";
2666
- readonly defaultModel: "openai/gpt-oss-20b";
2667
- readonly models: readonly ["openai/gpt-oss-20b", "openai/gpt-oss-120b"];
2668
- };
2669
- readonly openaiResponses: {
2670
- readonly verifiedAt: "2026-07-24";
2671
- readonly source: "https://platform.openai.com/docs/models";
2672
- readonly defaultModel: "gpt-4.1-mini";
2673
- readonly models: readonly ["gpt-5", "gpt-5-mini", "gpt-4.1", "gpt-4.1-mini"];
2674
- };
2675
- };
2676
- /**
2677
- * Provider wire protocol versions. Separate from the model catalog because a
2678
- * protocol version changes adapter parsing, not just which model is selected.
2679
- */
2680
- declare const PROVIDER_API_VERSIONS: {
2681
- readonly cartesia: "2026-03-01";
2682
- };
2683
- /**
2684
- * TVIC's own adapter tuning. These are our decisions about how to drive a provider,
2685
- * not facts about the provider, so they are not dated catalog entries.
2686
- */
2687
- declare const ADAPTER_DEFAULTS: {
2688
- readonly deepgram: {
2689
- readonly endpointingMs: 300;
2690
- readonly vadEvents: true;
2691
- readonly punctuate: true;
2692
- };
2693
- readonly sarvam: {
2694
- readonly mode: "transcribe";
2695
- readonly highVadSensitivity: true;
2696
- readonly vadSignals: true;
2697
- readonly flushSignal: true;
2698
- readonly inputAudioCodec: "pcm_s16le";
2699
- };
2700
- readonly cartesia: {
2701
- readonly language: "en";
2702
- };
2703
- };
2704
-
2705
3034
  interface ElevenLabsTtsProviderOptions {
2706
3035
  readonly apiKey: string;
2707
3036
  readonly voiceId: string;
2708
3037
  readonly modelId?: string;
2709
3038
  readonly language?: string;
2710
3039
  readonly url?: string;
3040
+ /** Allows an explicitly configured compatible endpoint/model outside the dated catalog. */
3041
+ readonly allowUnknownModel?: boolean;
2711
3042
  readonly stability?: number;
2712
3043
  readonly similarityBoost?: number;
3044
+ /** Regular TTS WebSocket speaker boost. */
3045
+ readonly useSpeakerBoost?: boolean;
3046
+ /** Regular TTS WebSocket auto mode; use only when sending complete sentences. */
3047
+ readonly autoMode?: boolean;
3048
+ /** Regular TTS WebSocket generation schedule, in provider character thresholds. */
3049
+ readonly chunkLengthSchedule?: readonly number[];
3050
+ readonly applyTextNormalization?: ElevenLabsTextNormalization;
3051
+ readonly enableLogging?: boolean;
3052
+ readonly enableSsmlParsing?: boolean;
3053
+ readonly seed?: number;
3054
+ readonly inactivityTimeoutSeconds?: number;
3055
+ /** Up to three dictionaries, applied in order on the first provider message. */
3056
+ readonly pronunciationDictionaryLocators?: readonly ElevenLabsPronunciationDictionaryLocator[];
3057
+ /** Voices registered for an Eleven v3 dialogue session. */
3058
+ readonly dialogueVoices?: readonly string[];
2713
3059
  readonly clock?: ProviderClock;
2714
- readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket;
3060
+ readonly webSocketFactory?: (url: string, headers: Readonly<Record<string, string>>) => WebSocket__default;
3061
+ }
3062
+
3063
+ interface ElevenLabsStreamOptions {
3064
+ readonly clock: ProviderClock;
3065
+ readonly modelId?: string;
3066
+ readonly protocol?: ElevenLabsTtsProtocol;
3067
+ readonly voice?: string;
3068
+ readonly voices?: readonly string[];
3069
+ readonly maxCharacters?: number | undefined;
3070
+ readonly stability: number;
3071
+ readonly similarityBoost: number;
3072
+ readonly useSpeakerBoost?: boolean | undefined;
3073
+ readonly applyTextNormalization?: ElevenLabsTextNormalization | undefined;
3074
+ readonly chunkLengthSchedule?: readonly number[] | undefined;
3075
+ readonly pronunciationDictionaryLocators?: readonly ElevenLabsPronunciationDictionaryLocator[] | undefined;
2715
3076
  }
2716
3077
  declare class ElevenLabsTtsProvider implements IncrementalTextToSpeechProvider {
2717
3078
  #private;
@@ -2738,24 +3099,121 @@ declare class ElevenLabsTtsProvider implements IncrementalTextToSpeechProvider {
2738
3099
  readonly channels: 1;
2739
3100
  }[];
2740
3101
  };
2741
- models: readonly ["eleven_flash_v2_5", "eleven_turbo_v2_5", "eleven_multilingual_v2"];
3102
+ models: readonly ["eleven_flash_v2_5", "eleven_flash_v2", "eleven_v3", "eleven_v3_conversational", "eleven_multilingual_v2", "eleven_turbo_v2_5", "eleven_turbo_v2"];
2742
3103
  };
2743
3104
  constructor(options: ElevenLabsTtsProviderOptions);
3105
+ get configuredModel(): string;
3106
+ get allowUnknownModel(): boolean;
3107
+ get configuredVoice(): string;
3108
+ get configuredLanguage(): string | undefined;
3109
+ synthesize(request: TtsSynthesisRequest): Promise<TtsStream>;
3110
+ openSession(request: TtsSessionOpenRequest): Promise<ElevenLabsTtsStream>;
3111
+ }
3112
+ declare class ElevenLabsTtsStream implements TtsSession {
3113
+ #private;
3114
+ readonly events: AsyncIterable<TtsEvent>;
3115
+ constructor(socket: WebSocket__default, request: TtsSessionOpenRequest, options: ElevenLabsStreamOptions);
3116
+ sendText(text: string, options?: ElevenLabsTtsSendTextOptions): Promise<void>;
3117
+ sendDialogueTurn(text: string, options?: ElevenLabsDialogueTurnOptions): Promise<void>;
3118
+ keepAlive(): Promise<void>;
3119
+ flush(): Promise<TtsFlushResult>;
3120
+ finish(): Promise<void>;
3121
+ cancel(): Promise<void>;
3122
+ }
3123
+ declare function createElevenLabsTtsProvider(options: ElevenLabsTtsProviderOptions): ElevenLabsTtsProvider;
3124
+
3125
+ interface ElevenLabsHttpTtsProviderOptions extends Omit<ElevenLabsTtsProviderOptions, "url" | "webSocketFactory"> {
3126
+ /** Overrides the regular text-to-speech endpoint. */
3127
+ readonly url?: string;
3128
+ /** Overrides the text-to-dialogue endpoint. */
3129
+ readonly dialogueUrl?: string;
3130
+ readonly optimizeStreamingLatency?: 0 | 1 | 2 | 3 | 4;
3131
+ readonly applyLanguageTextNormalization?: boolean;
3132
+ readonly fetchImpl?: typeof fetch;
3133
+ }
3134
+ interface ElevenLabsTtsHttpSynthesisRequest extends TtsSynthesisRequest {
3135
+ readonly previousText?: string;
3136
+ readonly nextText?: string;
3137
+ readonly previousRequestIds?: readonly string[];
3138
+ readonly nextRequestIds?: readonly string[];
3139
+ }
3140
+ interface ElevenLabsDialogueInput {
3141
+ readonly text: string;
3142
+ readonly voiceId: string;
3143
+ }
3144
+ interface ElevenLabsDialogueSynthesisRequest extends Omit<TtsSynthesisRequest, "text" | "voice"> {
3145
+ readonly inputs: readonly ElevenLabsDialogueInput[];
3146
+ readonly previousText?: string;
3147
+ readonly futureText?: string;
3148
+ readonly previousRequestIds?: readonly string[];
3149
+ readonly nextRequestIds?: readonly string[];
3150
+ }
3151
+ interface ElevenLabsDialogueProvider extends TextToSpeechProvider {
3152
+ synthesizeDialogue(request: ElevenLabsDialogueSynthesisRequest): Promise<TtsStream>;
3153
+ synthesizeSpeech(request: ElevenLabsTtsHttpSynthesisRequest): Promise<TtsStream>;
3154
+ }
3155
+ declare class ElevenLabsTtsRestProvider implements ElevenLabsDialogueProvider {
3156
+ #private;
3157
+ readonly name: "elevenlabs";
3158
+ readonly kind = "tts";
3159
+ readonly version = "0.1.0";
3160
+ readonly capabilities: ProviderCapabilities;
3161
+ constructor(options: ElevenLabsHttpTtsProviderOptions);
3162
+ get configuredModel(): string;
3163
+ get allowUnknownModel(): boolean;
3164
+ get configuredVoice(): string;
3165
+ get configuredLanguage(): string | undefined;
3166
+ get _httpOptions(): ElevenLabsHttpTtsProviderOptions;
3167
+ get _httpModelId(): string;
3168
+ get _httpAllowUnknownModel(): boolean;
3169
+ get _httpClock(): ProviderClock;
3170
+ get _httpFetch(): typeof fetch;
2744
3171
  synthesize(request: TtsSynthesisRequest): Promise<TtsStream>;
2745
- openSession(request: TtsSessionOpenRequest): Promise<TtsSession>;
3172
+ synthesizeSpeech(request: ElevenLabsTtsHttpSynthesisRequest): Promise<TtsStream>;
3173
+ synthesizeDialogue(request: ElevenLabsDialogueSynthesisRequest): Promise<TtsStream>;
2746
3174
  }
2747
- declare function createElevenLabsTtsProvider(options: ElevenLabsTtsProviderOptions): ElevenLabsTtsProvider;
3175
+ declare class ElevenLabsTtsHttpStreamProvider extends ElevenLabsTtsRestProvider {
3176
+ readonly capabilities: ProviderCapabilities;
3177
+ synthesizeSpeech(request: ElevenLabsTtsHttpSynthesisRequest): Promise<TtsStream>;
3178
+ synthesizeDialogue(request: ElevenLabsDialogueSynthesisRequest): Promise<TtsStream>;
3179
+ private synthesizeSpeechStream;
3180
+ private synthesizeDialogueStream;
3181
+ private executeStreamSpeech;
3182
+ private executeStreamDialogue;
3183
+ private executeViaProtectedPath;
3184
+ }
3185
+ declare function createElevenLabsTtsRestProvider(options: ElevenLabsHttpTtsProviderOptions): ElevenLabsTtsRestProvider;
3186
+ declare function createElevenLabsTtsHttpStreamProvider(options: ElevenLabsHttpTtsProviderOptions): ElevenLabsTtsHttpStreamProvider;
3187
+
3188
+ /** The point at which the primary TTS provider became unavailable. */
3189
+ type TtsFailoverPhase = "synthesize" | "stream";
3190
+ interface TtsFailoverContext {
3191
+ readonly phase: TtsFailoverPhase;
3192
+ readonly primary: TextToSpeechProvider;
3193
+ readonly fallback: TextToSpeechProvider;
3194
+ readonly request: TtsSynthesisRequest;
3195
+ readonly fallbackRequest: TtsSynthesisRequest;
3196
+ readonly error: NormalizedError;
3197
+ }
3198
+ interface TtsFailoverProviderOptions {
3199
+ /** The provider used for the normal request path. */
3200
+ readonly primary: TextToSpeechProvider;
3201
+ /** The provider used only after the failover policy accepts the error. */
3202
+ readonly fallback: TextToSpeechProvider;
3203
+ /** Map provider-specific values; callers own their semantic equivalence. */
3204
+ readonly mapFallbackRequest?: (request: TtsSynthesisRequest, error: NormalizedError) => TtsSynthesisRequest;
3205
+ /** Use only when the caller accepts a locale-to-language-code fallback mapping. */
3206
+ readonly languageMatch?: "exact" | "base-language";
3207
+ readonly shouldFallback?: (error: NormalizedError, request: TtsSynthesisRequest) => boolean;
3208
+ readonly onFallback?: (context: TtsFailoverContext) => void | PromiseLike<void>;
3209
+ readonly name?: string;
3210
+ }
3211
+ declare function createTtsFailoverProvider(options: TtsFailoverProviderOptions): TextToSpeechProvider;
2748
3212
 
2749
3213
  declare function bytesToBase64(bytes: Uint8Array): string;
2750
3214
  declare function base64ToBytes(value: string): Uint8Array;
2751
3215
  declare function mulawToPcm16le(mulaw: Uint8Array): Uint8Array;
2752
3216
  declare function pcm16leToMulaw(pcm: Uint8Array): Uint8Array;
2753
- /**
2754
- * v0.1 normalized audio is frozen to **pcm_s16le, mono**. The frame/duration/
2755
- * resample helpers below compute on interleaved-sample assumptions that only hold
2756
- * for a single channel, so a stereo format would silently corrupt timing. We
2757
- * reject it at the boundary rather than miscompute.
2758
- */
2759
3217
  declare function assertPcm16leFormat(format: AudioFormat): void;
2760
3218
  declare function resamplePcm16le(pcm: Uint8Array, fromSampleRateHz: number, toSampleRateHz: number): Uint8Array;
2761
3219
  declare function frameCountForPcm16le(bytes: Uint8Array): number;
@@ -2773,11 +3231,6 @@ declare class AsyncQueueConsumerError extends Error {
2773
3231
  }
2774
3232
  interface AsyncQueueOptions {
2775
3233
  readonly maxBuffered?: number;
2776
- /**
2777
- * Supplies the terminal error to deliver when a bounded queue is full. When
2778
- * omitted, `push()` keeps its non-throwing boolean-only contract and the
2779
- * caller remains responsible for handling `false`.
2780
- */
2781
3234
  readonly onOverflow?: () => unknown;
2782
3235
  }
2783
3236
  /**
@@ -2803,137 +3256,38 @@ interface AudioNormalizerOptions {
2803
3256
  interface AudioNormalizer {
2804
3257
  readonly inputFormat: AudioFormat;
2805
3258
  readonly outputFormat: AudioFormat;
3259
+ fork(): AudioNormalizer;
2806
3260
  push(bytes: Uint8Array): Uint8Array;
2807
3261
  finishSegment(): Uint8Array;
2808
3262
  finish(): Uint8Array;
2809
3263
  }
2810
- /**
2811
- * Converts supported PCM source frames into PCM16LE mono while preserving
2812
- * sample-clock phase across arbitrary realtime chunk boundaries.
2813
- *
2814
- * The FIR is intentionally small and deterministic. It is causal with a
2815
- * bounded look-ahead: ordinary pushes emit only samples whose filter support is
2816
- * present, while an explicit segment/stream finish uses the final source sample
2817
- * as the endpoint. This prevents packet boundaries from becoming resampling
2818
- * boundaries.
2819
- */
2820
3264
  declare function createAudioNormalizer(options: AudioNormalizerOptions): AudioNormalizer;
2821
3265
 
2822
3266
  declare function isInputMediaEvent(event: MediaEvent): event is InputMediaEvent;
2823
3267
  declare function isOutputMediaEvent(event: MediaEvent): event is OutputMediaEvent;
2824
3268
 
2825
- /**
2826
- * A single param value or an array of repeated param values. Twilio sends
2827
- * each value as a separate URL-encoded occurrence in the POST body, so a
2828
- * key that appears N times in the request will appear N times here.
2829
- */
2830
3269
  type TwilioParamValue = string | readonly string[];
2831
- /**
2832
- * The set of POST parameters signed by Twilio. Twilio sorts by key (NOT by
2833
- * the order they appear in the body), and concatenates `key + value` for
2834
- * each entry, with no separator.
2835
- */
2836
3270
  type TwilioParams = Readonly<Record<string, TwilioParamValue>>;
2837
- /**
2838
- * The simplest form: a single string value per key. Most webhooks fit this
2839
- * shape; use `TwilioParams` directly only when you need to handle repeated
2840
- * keys.
2841
- */
2842
3271
  type TwilioFlatParams = Readonly<Record<string, string>>;
2843
3272
  interface VerifyTwilioOptions {
2844
- /** The X-Twilio-Signature header value. */
2845
3273
  readonly signature: string;
2846
- /** The full request URL (with query string). */
2847
3274
  readonly url: string;
2848
- /** The parsed POST params, as a key-value map. */
2849
3275
  readonly params: TwilioFlatParams | TwilioParams;
2850
- /**
2851
- * The Twilio auth token. Used as the HMAC key. Required.
2852
- *
2853
- * For token rotation, wrap the verifier yourself:
2854
- * const ok = verifyTwilioSignature({...authTokenA}) ||
2855
- * verifyTwilioSignature({...authTokenB});
2856
- */
2857
3276
  readonly authToken: string;
2858
3277
  }
2859
3278
  declare function canonicalizeTwilioData(url: string, params: TwilioFlatParams | TwilioParams): Buffer;
2860
- /**
2861
- * Compute the expected signature for a given auth token, URL, and params.
2862
- * Exposed for tests and golden fixtures. Production code should call
2863
- * `verifyTwilioSignature` instead.
2864
- */
2865
3279
  declare function computeTwilioSignature(authToken: string, url: string, params: TwilioFlatParams | TwilioParams): string;
2866
- /**
2867
- * Verify a Twilio X-Twilio-Signature header. Returns true if the signature
2868
- * matches the configured auth token.
2869
- *
2870
- * Returns false (does not throw) for malformed inputs:
2871
- * - missing or empty signature
2872
- * - signature is not valid base64 of length 28
2873
- * - signature decodes to a byte array that does not match the expected HMAC
2874
- *
2875
- * Throws (programmer error, not attacker error):
2876
- * - when `authToken` is empty string
2877
- *
2878
- * @remarks
2879
- * Twilio's signature does NOT include a timestamp or nonce. To prevent replay,
2880
- * the caller MUST enforce an idempotency check (e.g. dedupe by `CallSid` +
2881
- * `MessageSid` with a TTL).
2882
- *
2883
- * @example
2884
- * ```ts
2885
- * const sig = Array.isArray(req.headers["x-twilio-signature"])
2886
- * ? req.headers["x-twilio-signature"][0]
2887
- * : req.headers["x-twilio-signature"];
2888
- * const ok = verifyTwilioSignature({
2889
- * signature: sig,
2890
- * url: `https://example.com${req.url}`,
2891
- * params: parsedFormBody,
2892
- * authToken: process.env.TWILIO_AUTH_TOKEN!,
2893
- * });
2894
- * if (!ok) return new Response("invalid signature", { status: 403 });
2895
- * ```
2896
- */
2897
3280
  declare function verifyTwilioSignature(options: VerifyTwilioOptions): boolean;
2898
3281
 
2899
3282
  interface VerifyVoiceSessionTokenOptions {
2900
- /** The token from the WebSocket upgrade query string. */
2901
3283
  readonly token: string | null | undefined;
2902
- /** The expected session reference (e.g. "voice_<uuid>"). */
2903
3284
  readonly sessionRef: string;
2904
- /** The expiry as a string of non-negative integer milliseconds. */
2905
3285
  readonly exp: string | null | undefined;
2906
- /** The shared secret used to sign the token. */
2907
3286
  readonly secret: string;
2908
- /** Optional: current time in ms. Defaults to Date.now. Injected for tests. */
2909
3287
  readonly now?: () => number;
2910
- /**
2911
- * Optional: tolerance window in ms for the expiry check. Default 0.
2912
- * Use this if server and client clocks are skewed.
2913
- */
2914
3288
  readonly toleranceMs?: number;
2915
3289
  }
2916
- /**
2917
- * Compute the expected voice-session token for a given session ref
2918
- * and expiry. Exposed for tests and the example app's token generator.
2919
- */
2920
3290
  declare function signVoiceSessionToken(secret: string, sessionRef: string, expMs: number): string;
2921
- /**
2922
- * Verify a voice-session token. Returns true on success, false
2923
- * otherwise. Does NOT throw for invalid input — callers should branch
2924
- * on the boolean.
2925
- *
2926
- * @example
2927
- * ```ts
2928
- * const ok = verifyVoiceSessionToken({
2929
- * token: url.searchParams.get("token"),
2930
- * sessionRef: matchPathParams.url.sessionRef,
2931
- * exp: url.searchParams.get("exp"),
2932
- * secret: process.env.VOICE_TOKEN_SECRET!,
2933
- * });
2934
- * if (!ok) return new Response("invalid token", { status: 401 });
2935
- * ```
2936
- */
2937
3291
  declare function verifyVoiceSessionToken(options: VerifyVoiceSessionTokenOptions): boolean;
2938
3292
 
2939
3293
  type RuntimeProvider = TelephonyProvider | SpeechToTextProvider | TextToSpeechProvider | LLMProvider;
@@ -2943,8 +3297,9 @@ type ProviderForKind<K extends ProviderKind> = Extract<RuntimeProvider, {
2943
3297
  declare function isProviderKind<K extends ProviderKind>(provider: RuntimeProvider, kind: K): provider is ProviderForKind<K>;
2944
3298
  type AudioFormatDirection = "input" | "output";
2945
3299
  declare function supportsAudioFormat(provider: Provider, format: AudioFormat, direction: AudioFormatDirection): boolean;
2946
- declare function supportsLanguage(provider: Provider, language: string): boolean;
3300
+ declare function supportsLanguage(provider: Provider, language: string, model?: string): boolean;
2947
3301
  declare function supportsModel(provider: Provider, model: string): boolean;
3302
+ declare function supportsBatchModel(provider: Provider, model: string): boolean;
2948
3303
  declare function requireProviderKind<K extends ProviderKind>(provider: RuntimeProvider, kind: K): ProviderForKind<K>;
2949
3304
 
2950
3305
  interface DefineToolInput<TInput, TOutput> {
@@ -2957,6 +3312,10 @@ interface DefineToolInput<TInput, TOutput> {
2957
3312
  readonly timeout?: TimeoutPolicy;
2958
3313
  readonly retry?: RetryPolicy;
2959
3314
  readonly idempotency?: IdempotencyPolicy;
3315
+ /**
3316
+ * @deprecated This field is a no-op. Enforce authorization in `execute`
3317
+ * using `ctx.tenant?.scopes`.
3318
+ */
2960
3319
  readonly authScope?: readonly string[];
2961
3320
  readonly tags?: readonly string[];
2962
3321
  readonly metadata?: Readonly<Record<string, unknown>>;
@@ -2984,6 +3343,8 @@ declare function defineAgent(input: DefineAgentInput): Agent;
2984
3343
 
2985
3344
  declare function createRuntime(options?: RuntimeOptions): Runtime;
2986
3345
 
3346
+ declare function toRuntimeSessionTrace(event: SessionEndEvent): RuntimeSessionTrace;
3347
+
2987
3348
  interface ResolvePreCallContextInput {
2988
3349
  readonly memory: Memory;
2989
3350
  readonly resolver?: PreCallContextResolver;
@@ -3001,33 +3362,14 @@ interface ResolvePreCallContextInput {
3001
3362
  readonly maxEntries?: number;
3002
3363
  /** Maximum bytes rendered for the combined static and memory context. */
3003
3364
  readonly maxBytes?: number;
3004
- /**
3005
- * Optional provider of the static (non-memory) context. The default
3006
- * resolver returns an empty static map; the user-provided resolver
3007
- * (via `options.preCallContextResolver`) is the place to inject CRM,
3008
- * feature flags, and tenant config.
3009
- */
3010
3365
  readonly staticProvider?: () => Promise<ReadonlyMap<string, string>>;
3011
3366
  }
3012
3367
  declare function resolvePreCallContext(input: ResolvePreCallContextInput): Promise<PreCallContext>;
3013
- /**
3014
- * Format the pre-call context as a system-prompt block. Renders the
3015
- * `<memory>...</memory>` block and (if non-empty or degraded) the
3016
- * `<context>...</context>` block above it.
3017
- */
3018
3368
  declare function formatPreCallContextAsSystemBlock(context: PreCallContext, maxBytes?: number): string;
3019
- /**
3020
- * @deprecated Use `resolvePreCallContext` and `formatPreCallContextAsSystemBlock`.
3021
- * Kept for one compatibility release as a memory-only projection.
3022
- */
3369
+ /** @deprecated Use `resolvePreCallContext` and `formatPreCallContextAsSystemBlock`. */
3023
3370
  declare function resolvePreCallMemory(input: ResolvePreCallContextInput): Promise<PreCallMemoryContext>;
3024
3371
  declare function formatMemoryContextAsSystemBlock(context: PreCallMemoryContext, maxBytes?: number): string;
3025
3372
 
3026
- /**
3027
- * Fails before a live session starts when the configured memory adapter cannot
3028
- * provide the behavior the agent's policy promises. Memory adapters remain
3029
- * pluggable; the adapter's instance-level declaration is the source of truth.
3030
- */
3031
3373
  declare function assertMemoryPolicySupported(memory: Memory, policy: AgentMemoryPolicy): void;
3032
3374
  declare function assertMemoryCapability(memory: Memory, capability: "search.exact" | "write.explicit" | "write.implicit" | "write.sessionQuota" | "purge.perScope", operation: string): void;
3033
3375
 
@@ -3037,6 +3379,11 @@ interface SessionActivator {
3037
3379
  readonly agent: Agent;
3038
3380
  readonly attachment: SessionAttachment;
3039
3381
  }): Promise<void>;
3382
+ deactivate?(input: {
3383
+ readonly sessionId: SessionId;
3384
+ readonly agent: Agent;
3385
+ readonly attachment: SessionAttachment;
3386
+ }): Promise<void>;
3040
3387
  }
3041
3388
  interface SessionRecoveryCoordinatorOptions {
3042
3389
  readonly runtime: Runtime;
@@ -3052,6 +3399,7 @@ interface SessionRecoveryCoordinatorOptions {
3052
3399
  readonly name: string;
3053
3400
  readonly value: number;
3054
3401
  }) => void;
3402
+ readonly onError?: (error: unknown) => void;
3055
3403
  }
3056
3404
  interface RecoveryPollResult {
3057
3405
  readonly candidates: number;
@@ -3062,7 +3410,7 @@ declare class SessionRecoveryCoordinator {
3062
3410
  #private;
3063
3411
  constructor(options: SessionRecoveryCoordinatorOptions);
3064
3412
  start(): void;
3065
- stop(): Promise<void>;
3413
+ stop(): Promise<boolean>;
3066
3414
  pollOnce(): Promise<RecoveryPollResult>;
3067
3415
  }
3068
3416
  interface SessionReaperOptions {
@@ -3078,12 +3426,13 @@ interface SessionReaperOptions {
3078
3426
  readonly name: string;
3079
3427
  readonly value: number;
3080
3428
  }) => void;
3429
+ readonly onError?: (error: unknown) => void;
3081
3430
  }
3082
3431
  declare class SessionReaper {
3083
3432
  #private;
3084
3433
  constructor(options: SessionReaperOptions);
3085
3434
  start(): void;
3086
- stop(): Promise<void>;
3435
+ stop(): Promise<boolean>;
3087
3436
  reapOnce(): Promise<number>;
3088
3437
  }
3089
3438
 
@@ -3107,25 +3456,11 @@ declare class ConversationPolicy {
3107
3456
  #private;
3108
3457
  constructor(options: ConversationPolicyOptions);
3109
3458
  hydrateTurns(turns: readonly Turn[]): void;
3110
- /**
3111
- * Set the session-level system instruction. Pre-call context and variables
3112
- * remain attached because the system message is rebuilt from canonical state.
3113
- */
3114
3459
  replaceSystemInstruction(instruction: string): void;
3115
- /**
3116
- * Set or clear a per-turn instruction. Clearing it restores the session-level
3117
- * instruction without losing the tenant variables or pre-call context.
3118
- */
3119
3460
  setTurnSystemInstruction(instruction: string | undefined): void;
3120
- /**
3121
- * Replace the static variables map. Values are substituted into `{{name}}`
3122
- * placeholders and also rendered in a dedicated block so the model can see
3123
- * variables that the base instruction did not reference explicitly.
3124
- */
3125
3461
  setStaticVariables(variables: ReadonlyMap<string, string>): void;
3126
3462
  acceptTranscript(event: TranscriptEvent): string | null;
3127
3463
  get hasBufferedTranscript(): boolean;
3128
- /** Commits buffered final segments for an endpoint, timeout, or stream shutdown. */
3129
3464
  flushBufferedTranscript(): string | null;
3130
3465
  messagesForTranscript(transcript: string): readonly LlmMessage[];
3131
3466
  messagesForToolContinuation(messages: readonly LlmMessage[], assistantText: string, toolMessages: readonly LlmMessage[], assistantToolCalls?: readonly LlmInlineToolCall[]): readonly LlmMessage[];
@@ -3137,13 +3472,9 @@ declare class ConversationPolicy {
3137
3472
  interface SttCommandController {
3138
3473
  /** Resolves only when this controller reaches a terminal state. */
3139
3474
  readonly failure: Promise<never>;
3140
- /** Admit audio without waiting for provider I/O. */
3141
3475
  admitAudio(chunk: InputAudioChunk): Promise<void>;
3142
- /** Admit an ordered barrier and settle it after provider command acceptance. */
3143
3476
  admitCommit(): Promise<void>;
3144
- /** Drain admitted commands in order and then close the stream. */
3145
3477
  drain(): Promise<void>;
3146
- /** Abandon queued work and close the stream immediately. */
3147
3478
  abort(error?: unknown): Promise<void>;
3148
3479
  }
3149
3480
 
@@ -3173,11 +3504,6 @@ interface SttReconnectOptions {
3173
3504
  readonly audioWriteTimeoutMs?: number;
3174
3505
  readonly closeTimeoutMs?: number;
3175
3506
  }
3176
- /**
3177
- * Wraps one STT provider with bounded, best-effort reconnect and replay policy.
3178
- * The wrapper is deliberately runtime-owned: adapters only need to expose honest
3179
- * transport and timestamp semantics.
3180
- */
3181
3507
  declare function withSttReconnect(provider: SpeechToTextProvider, options?: SttReconnectOptions): SpeechToTextProvider;
3182
3508
 
3183
3509
  interface AssistantTextRecord {
@@ -3197,7 +3523,6 @@ interface TextDeliveryDecision {
3197
3523
  readonly hasTransport: boolean;
3198
3524
  readonly cancelledByBargeIn: boolean;
3199
3525
  }
3200
- /** Decides whether participant-visible text should be attempted for a terminal turn. */
3201
3526
  declare function shouldDeliverText(decision: TextDeliveryDecision): boolean;
3202
3527
  declare function deliverAssistantText(options: {
3203
3528
  readonly callHandle: CallHandle;
@@ -3210,16 +3535,6 @@ declare function deliverAssistantText(options: {
3210
3535
  readonly timeoutMs?: number;
3211
3536
  }): Promise<boolean | undefined>;
3212
3537
 
3213
- /**
3214
- * Public-facing event emitted by a voice pipeline run. A discriminated
3215
- * union of 8 kinds so consumers can `switch (event.kind)` without
3216
- * runtime guessing.
3217
- *
3218
- * The shape is intentionally a *friendlier* view than the internal
3219
- * `MediaEvent`. The runtime's `MediaEvent` includes IDs, sequence
3220
- * numbers, and provider metadata; `VoiceEvent` strips those and exposes
3221
- * the same data in a UX-friendly form.
3222
- */
3223
3538
  type VoiceEvent = {
3224
3539
  readonly kind: "transcript_delta";
3225
3540
  readonly text: string;
@@ -3239,6 +3554,7 @@ type VoiceEvent = {
3239
3554
  readonly turnId: TurnId;
3240
3555
  readonly status: "completed" | "cancelled" | "failed";
3241
3556
  readonly latencyMs: number;
3557
+ readonly delivery?: TurnOutputDelivery;
3242
3558
  } | {
3243
3559
  readonly kind: "tool_call";
3244
3560
  readonly toolCallId: ToolCallId;
@@ -3248,6 +3564,9 @@ type VoiceEvent = {
3248
3564
  readonly kind: "tool_result";
3249
3565
  readonly toolCallId: ToolCallId;
3250
3566
  readonly output: unknown;
3567
+ readonly status: "succeeded" | "failed" | "timed_out" | "cancelled";
3568
+ readonly error?: Pick<NormalizedError, "code" | "message">;
3569
+ readonly recoveryPolicy?: "do_not_replay";
3251
3570
  readonly latencyMs: number;
3252
3571
  } | {
3253
3572
  readonly kind: "error";
@@ -3258,26 +3577,11 @@ type VoiceEvent = {
3258
3577
  readonly reason: "completed" | "cancelled" | "failed" | "remote_hangup";
3259
3578
  readonly totalTurns: number;
3260
3579
  };
3261
- /**
3262
- * The result of starting a `PipelineVoiceLoop`. Dual-protocol: awaits
3263
- * to a final `PipelineVoiceLoopResult` with an explicit terminal reason and
3264
- * source, AND iterates the per-event
3265
- * stream.
3266
- *
3267
- * Implementation note: the class implements both `PromiseLike<PipelineVoiceLoopResult>`
3268
- * and `AsyncIterable<VoiceEvent>`. Awaiting and iterating are independent
3269
- * — the run starts on the first await/iteration. Subsequent awaits share
3270
- * the same promise. Iteration drains buffered events before completing.
3271
- */
3272
3580
  interface DualProtocolResult extends PromiseLike<PipelineVoiceLoopResult> {
3273
3581
  then<TResult1 = PipelineVoiceLoopResult, TResult2 = never>(onfulfilled?: ((value: PipelineVoiceLoopResult) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2>;
3274
3582
  catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null | undefined): PromiseLike<PipelineVoiceLoopResult | TResult>;
3275
3583
  finally(onfinally?: (() => void) | null | undefined): PromiseLike<PipelineVoiceLoopResult>;
3276
3584
  [Symbol.asyncIterator](): AsyncIterator<VoiceEvent>;
3277
- /**
3278
- * The session ID this result is for. Exposed for consumer convenience
3279
- * (e.g., logging).
3280
- */
3281
3585
  readonly sessionId: SessionId;
3282
3586
  }
3283
3587
  /**
@@ -3305,12 +3609,6 @@ type PipelineVoiceLoopResultLike = PipelineVoiceLoopResult;
3305
3609
  declare class PipelineVoiceLoopBuilder {
3306
3610
  #private;
3307
3611
  constructor(loop: PipelineVoiceLoopLike, overrideSignal?: AbortSignal);
3308
- /**
3309
- * Attach an `AbortSignal` that cancels the run when triggered. Composed
3310
- * with `attachment.signal` (both fire to cancel; the lease-loss reason
3311
- * on the attachment is preserved). Throws if called twice on the same
3312
- * builder.
3313
- */
3314
3612
  abortSignal(signal: AbortSignal): this;
3315
3613
  then<TResult1 = PipelineVoiceLoopResultLike, TResult2 = never>(onfulfilled?: ((value: PipelineVoiceLoopResultLike) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2>;
3316
3614
  catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null | undefined): PromiseLike<PipelineVoiceLoopResultLike | TResult>;
@@ -3327,7 +3625,6 @@ interface PipelineVoiceLoopLike {
3327
3625
  _startInternal(options: {
3328
3626
  readonly overrideSignal?: AbortSignal;
3329
3627
  readonly consumer?: "internal" | "public";
3330
- /** Internal lifecycle hook; does not observe or assimilate the thenable. */
3331
3628
  readonly onRunPromise?: (promise: Promise<PipelineVoiceLoopResult>) => void;
3332
3629
  }): DualProtocolResult;
3333
3630
  }
@@ -3351,7 +3648,6 @@ interface PipelineVoiceLoopOptions {
3351
3648
  readonly callHandle: CallHandle;
3352
3649
  readonly llmModel: string;
3353
3650
  readonly sttModel?: string;
3354
- /** Allows a custom/self-hosted STT endpoint to accept a model outside TVIC's dated catalog. */
3355
3651
  readonly sttAllowUnknownModel?: boolean;
3356
3652
  readonly sttReconnect?: boolean | SttReconnectOptions;
3357
3653
  readonly sttLanguage?: string;
@@ -3366,19 +3662,10 @@ interface PipelineVoiceLoopOptions {
3366
3662
  readonly preCallContext?: PreCallContext;
3367
3663
  readonly safetyIdentifier?: string;
3368
3664
  readonly textDelivery?: TextDeliveryMode;
3369
- /** Max ms a provider stream may stall (no events) before the turn fails. */
3370
3665
  readonly streamStallTimeoutMs?: number;
3371
- /** Inactivity debounce after the latest immutable final segment. */
3372
3666
  readonly turnEndpointTimeoutMs?: number;
3373
- /** Absolute cap from the first immutable final segment in one utterance. */
3374
3667
  readonly turnMaxDurationMs?: number;
3375
- /** Optional managed-owner source for an external cancellation signal. */
3376
3668
  readonly terminalSourceForCancellation?: () => LiveTerminalSource | undefined;
3377
- /**
3378
- * Receives one record per terminal turn. This is an observation seam, not part of
3379
- * execution: it is invoked after the turn is already terminal, its return value is
3380
- * ignored, and a throw from it is swallowed so an observer can never affect a call.
3381
- */
3382
3669
  readonly onTurnLatency?: (record: TurnLatencyRecord) => void;
3383
3670
  readonly onAssistantText?: (record: AssistantTextRecord) => void;
3384
3671
  readonly sessionMetricsRecorder?: SessionMetricsRecorder;
@@ -3390,45 +3677,21 @@ interface PipelineVoiceLoopResult {
3390
3677
  readonly interruptions: number;
3391
3678
  readonly turnsFailed: number;
3392
3679
  readonly firstTurnError: NormalizedError | null;
3393
- /**
3394
- * Terminal reason for RESOLVED runs (additive; existing readers ignore it).
3395
- * Precedence: cancelled (explicit cancel/abort won) > failed (one or more
3396
- * failed turns, or a timeout/error stream end) > remote_hangup >
3397
- * completed. Rejected runs carry their terminal in the rejection instead;
3398
- * unified cancel/remote arbitration with scheduler batches is joint T1
3399
- * work — this field reports the resolved outcome only.
3400
- */
3401
3680
  readonly terminalReason: PipelineVoiceLoopTerminalReason;
3402
3681
  readonly terminalSource: LiveTerminalSource;
3403
3682
  }
3404
- /**
3405
- * Runs a pipeline voice session: media -> STT -> LLM/tools -> TTS -> media.
3406
- * This module owns only live execution and failure handling; telemetry belongs
3407
- * outside the runtime's critical path.
3408
- */
3409
3683
  declare class PipelineVoiceLoop {
3410
3684
  #private;
3411
3685
  constructor(options: PipelineVoiceLoopOptions);
3412
- /** Start a call and expose an awaitable, iterable result. */
3413
3686
  start(options?: {
3414
3687
  readonly overrideSignal?: AbortSignal;
3415
3688
  }): PipelineVoiceLoopBuilder;
3416
- /**
3417
- * Legacy: returns `Promise<PipelineVoiceLoopResult>`. Equivalent to
3418
- * `await this.start(options)`. Convenience wrapper preserved for backward
3419
- * compatibility with the v0.0.x API.
3420
- */
3421
3689
  run(options?: {
3422
3690
  readonly overrideSignal?: AbortSignal;
3423
3691
  }): Promise<PipelineVoiceLoopResult>;
3424
- /**
3425
- * Implementation hook for {@link PipelineVoiceLoopBuilder}. Returns a
3426
- * `DualProtocolResult` that wraps the run promise and event queue.
3427
- */
3428
3692
  _startInternal(options: {
3429
3693
  readonly overrideSignal?: AbortSignal;
3430
3694
  readonly consumer?: "internal" | "public";
3431
- /** Internal lifecycle hook used by managed wrappers without thenable assimilation. */
3432
3695
  readonly onRunPromise?: (promise: Promise<PipelineVoiceLoopResult>) => void;
3433
3696
  }): DualProtocolResult;
3434
3697
  }
@@ -3509,43 +3772,35 @@ type UpgradeAuthorization<TContext> = {
3509
3772
  readonly reason?: string;
3510
3773
  };
3511
3774
  interface NodeMediaPlaneConnection<TContext = unknown> {
3512
- readonly socket: WebSocket;
3775
+ readonly socket: WebSocket__default;
3513
3776
  readonly request: IncomingMessage;
3514
3777
  readonly url: URL;
3515
3778
  readonly params: Readonly<Record<string, string>>;
3516
3779
  readonly upgradeContext?: TContext;
3517
3780
  }
3518
3781
  type NodeMediaPlaneConnectionHandler<TContext = unknown> = (connection: NodeMediaPlaneConnection<TContext>) => Promise<void> | void;
3519
- type NodeMediaPlaneRequestHandler = (request: IncomingMessage, response: ServerResponse) => boolean | Promise<boolean>;
3520
- type NodeMediaPlaneConnectionErrorHandler = (error: unknown, socket: WebSocket) => void | Promise<void>;
3782
+ type NodeMediaPlaneRequestHandler = (request: IncomingMessage, response: ServerResponse, signal: AbortSignal) => boolean | Promise<boolean>;
3783
+ type NodeMediaPlaneConnectionErrorHandler = (error: unknown, socket: WebSocket__default) => void | Promise<void>;
3521
3784
  interface NodeMediaPlaneOptions<TContext = unknown> {
3522
3785
  readonly host?: string;
3523
3786
  readonly port: number;
3524
3787
  readonly path: string;
3525
- /** Maximum inbound WebSocket frame accepted before the connection is closed. */
3526
3788
  readonly maxInboundFrameBytes?: number;
3789
+ readonly maxInboundFrameFragments?: number;
3790
+ readonly webSocketCloseTimeoutMs?: number;
3527
3791
  readonly healthPath?: string;
3528
- /**
3529
- * Optional health check. Called when the plane's `healthPath` endpoint
3530
- * is hit. The plane responds 200 with `{ ok: true }` if the check
3531
- * returns `ok: true`, and 503 with the check details otherwise. This
3532
- * is where the runtime's `RuntimeOptions.healthCheck` plugs in so
3533
- * the load balancer can drain traffic before a replica's Postgres
3534
- * becomes unreachable. See `docs/operations/multi-replica.md`.
3535
- */
3536
- readonly healthCheck?: () => Promise<{
3792
+ readonly healthCheck?: (signal: AbortSignal) => Promise<{
3537
3793
  readonly ok: boolean;
3538
3794
  readonly checks?: Readonly<Record<string, unknown>>;
3539
3795
  }>;
3540
3796
  readonly onConnection: NodeMediaPlaneConnectionHandler<TContext>;
3541
- /** Handle non-WebSocket HTTP requests (e.g. the Twilio TwiML webhook). Return true if handled. */
3542
3797
  readonly onRequest?: NodeMediaPlaneRequestHandler;
3543
- /** Routes failures from an async onConnection handler. Defaults to closing the socket. */
3544
3798
  readonly onConnectionError?: NodeMediaPlaneConnectionErrorHandler;
3545
- /** Synchronous, pre-handshake authorization. Throwing rejects with HTTP 500. */
3546
- readonly authorizeUpgrade?: (request: IncomingMessage, url: URL, params: Readonly<Record<string, string>>) => UpgradeAuthorization<TContext>;
3547
- /** Releases state reserved by a successful authorization if the handshake aborts. */
3548
- readonly onUpgradeAborted?: (context: TContext) => void;
3799
+ readonly authorizeUpgrade?: (request: IncomingMessage, url: URL, params: Readonly<Record<string, string>>, signal: AbortSignal) => UpgradeAuthorization<TContext> | PromiseLike<UpgradeAuthorization<TContext>>;
3800
+ readonly authorizationTimeoutMs?: number;
3801
+ readonly maxPendingAuthorizations?: number;
3802
+ readonly onUpgradeAborted?: (context: TContext) => void | PromiseLike<void>;
3803
+ readonly onUpgradeAbortedError?: (error: unknown, context: TContext) => void | PromiseLike<void>;
3549
3804
  }
3550
3805
  declare class NodeMediaPlane<TContext = unknown> {
3551
3806
  #private;
@@ -3579,17 +3834,21 @@ type AssemblyAiProviderConfig = Omit<AssemblyAiSttProviderOptions, "apiKey" | "m
3579
3834
  readonly apiKey?: string;
3580
3835
  readonly model?: string;
3581
3836
  };
3837
+ type CartesiaSttProviderConfig = Omit<CartesiaSttProviderOptions, "apiKey" | "modelId"> & {
3838
+ readonly provider: "cartesia";
3839
+ readonly apiKey?: string;
3840
+ readonly model?: string;
3841
+ };
3582
3842
  type SonioxProviderConfig = Omit<SonioxSttProviderOptions, "apiKey" | "modelId"> & {
3583
3843
  readonly provider: "soniox";
3584
3844
  readonly apiKey?: string;
3585
3845
  readonly model?: string;
3586
3846
  };
3587
- type SttProviderConfig = DeepgramProviderConfig | SarvamProviderConfig | ElevenLabsSttProviderConfig | AssemblyAiProviderConfig | SonioxProviderConfig;
3847
+ type SttProviderConfig = DeepgramProviderConfig | SarvamProviderConfig | CartesiaSttProviderConfig | ElevenLabsSttProviderConfig | AssemblyAiProviderConfig | SonioxProviderConfig;
3588
3848
  type OpenAiProviderConfig = Omit<OpenAiResponsesLlmProviderOptions, "apiKey"> & {
3589
3849
  readonly provider: "openai" | "openai-responses";
3590
3850
  readonly apiKey?: string;
3591
3851
  readonly model?: string;
3592
- /** Allows a custom OpenAI-compatible endpoint to use a model outside TVIC's dated catalog. */
3593
3852
  readonly allowUnknownModel?: boolean;
3594
3853
  };
3595
3854
  type GroqProviderConfig = Omit<GroqChatLlmProviderOptions, "apiKey"> & {
@@ -3605,13 +3864,33 @@ type CartesiaProviderConfig = Omit<CartesiaTtsProviderOptions, "apiKey" | "voice
3605
3864
  readonly model?: string;
3606
3865
  readonly voiceId?: string;
3607
3866
  };
3608
- type ElevenLabsTtsProviderConfig = Omit<ElevenLabsTtsProviderOptions, "apiKey" | "voiceId" | "modelId"> & {
3867
+ type ElevenLabsTtsProviderConfig = (Omit<ElevenLabsTtsProviderOptions, "apiKey" | "voiceId" | "modelId"> & {
3609
3868
  readonly provider: "elevenlabs";
3869
+ readonly transport?: "websocket";
3610
3870
  readonly apiKey?: string;
3611
3871
  readonly model?: string;
3612
3872
  readonly voiceId?: string;
3613
- };
3614
- type TtsProviderConfig = CartesiaProviderConfig | ElevenLabsTtsProviderConfig;
3873
+ }) | (Omit<ElevenLabsHttpTtsProviderOptions, "apiKey" | "voiceId" | "modelId"> & {
3874
+ readonly provider: "elevenlabs";
3875
+ readonly transport: "rest" | "http-stream";
3876
+ readonly apiKey?: string;
3877
+ readonly model?: string;
3878
+ readonly voiceId?: string;
3879
+ });
3880
+ type SarvamTtsProviderConfig = (Omit<SarvamTtsProviderOptions, "apiKey" | "modelId" | "voiceId"> & {
3881
+ readonly provider: "sarvam";
3882
+ readonly transport?: "websocket";
3883
+ readonly apiKey?: string;
3884
+ readonly model?: string;
3885
+ readonly voiceId?: string;
3886
+ }) | (Omit<SarvamTtsHttpProviderOptions, "apiKey" | "modelId" | "voiceId"> & {
3887
+ readonly provider: "sarvam";
3888
+ readonly transport: "rest" | "http-stream";
3889
+ readonly apiKey?: string;
3890
+ readonly model?: string;
3891
+ readonly voiceId?: string;
3892
+ });
3893
+ type TtsProviderConfig = CartesiaProviderConfig | ElevenLabsTtsProviderConfig | SarvamTtsProviderConfig;
3615
3894
  type TelephonyProviderConfig = {
3616
3895
  readonly provider: "web-client-audio";
3617
3896
  readonly options?: WebClientAudioProviderOptions;
@@ -3637,7 +3916,6 @@ interface CreateVoiceAgentOptions {
3637
3916
  readonly version?: string;
3638
3917
  readonly providers: VoiceAgentProviders;
3639
3918
  readonly models?: VoiceAgentModels;
3640
- /** Tool generics are intentionally erased at the heterogeneous agent boundary. */
3641
3919
  readonly tools?: readonly ToolDefinition<any, any>[];
3642
3920
  readonly audio?: Partial<AgentAudioPolicy>;
3643
3921
  readonly memoryPolicy?: AgentMemoryPolicy;
@@ -3646,13 +3924,7 @@ interface CreateVoiceAgentOptions {
3646
3924
  readonly runtime?: RuntimeOptions;
3647
3925
  }
3648
3926
  interface VoiceAgentRunOptions {
3649
- /**
3650
- * A handle created by a stable TVIC transport adapter or a custom adapter.
3651
- * A factory is useful for transports whose events must be stamped with the
3652
- * runtime-created session id; it runs after the session is created.
3653
- */
3654
3927
  readonly callHandle: CallHandle | VoiceAgentCallHandleFactory;
3655
- /** Optional complete call record. A safe inbound record is synthesized when omitted. */
3656
3928
  readonly call?: Call;
3657
3929
  readonly channel?: ChannelKind;
3658
3930
  readonly variables?: Readonly<Record<string, unknown>>;
@@ -3661,7 +3933,6 @@ interface VoiceAgentRunOptions {
3661
3933
  readonly organizationId?: OrganizationId;
3662
3934
  readonly workflowId?: WorkflowId;
3663
3935
  readonly signal?: AbortSignal;
3664
- /** Maximum time allowed to start the runtime, attach the call, and create the run. */
3665
3936
  readonly startupTimeoutMs?: number;
3666
3937
  readonly safetyIdentifier?: string;
3667
3938
  readonly sttReconnect?: boolean | SttReconnectOptions;
@@ -3673,10 +3944,8 @@ interface VoiceAgentRunOptions {
3673
3944
  }
3674
3945
  interface VoiceAgentCallHandleContext {
3675
3946
  readonly sessionId: SessionId;
3676
- /** A deeply frozen copy of the validated call supplied to start(). */
3677
3947
  readonly call: CallSnapshot;
3678
3948
  readonly channel: ChannelKind;
3679
- /** Aborts when the caller, startup deadline, or global agent shutdown wins. */
3680
3949
  readonly signal: AbortSignal;
3681
3950
  }
3682
3951
  type VoiceAgentCallHandleFactory = (context: VoiceAgentCallHandleContext) => CallHandle | PromiseLike<CallHandle>;
@@ -3686,6 +3955,11 @@ interface VoiceAgentSession {
3686
3955
  readonly sessionId: SessionId;
3687
3956
  readonly run: VoiceAgentRun;
3688
3957
  }
3958
+ interface ManagedVoiceAgentSession extends VoiceAgentSession {
3959
+ readonly finalSession: Promise<TerminalSession>;
3960
+ complete(): Promise<TerminalSession>;
3961
+ stop(): Promise<void>;
3962
+ }
3689
3963
  interface VoiceAgentProviderNames {
3690
3964
  readonly telephony: string;
3691
3965
  readonly stt: string;
@@ -3702,7 +3976,10 @@ interface VoiceAgent {
3702
3976
  stop(): Promise<void>;
3703
3977
  healthCheck(): Promise<HealthSnapshot>;
3704
3978
  }
3705
- declare function createVoiceAgent(options: CreateVoiceAgentOptions): VoiceAgent;
3979
+ interface VoiceAgentWithSessionLifecycle extends VoiceAgent {
3980
+ start(options: VoiceAgentRunOptions): Promise<ManagedVoiceAgentSession>;
3981
+ }
3982
+ declare function createVoiceAgent(options: CreateVoiceAgentOptions): VoiceAgentWithSessionLifecycle;
3706
3983
 
3707
3984
  declare class InMemorySessionStore implements SessionStore {
3708
3985
  #private;
@@ -3711,7 +3988,6 @@ declare class InMemorySessionStore implements SessionStore {
3711
3988
  put(record: StoredSessionRecord): Promise<void>;
3712
3989
  update(id: SessionId, updater: (record: StoredSessionRecord) => StoredSessionRecord): Promise<StoredSessionRecord>;
3713
3990
  close(): Promise<void>;
3714
- /** Internal aggregate-transaction rollback hook. */
3715
3991
  restore(id: SessionId, record: StoredSessionRecord | null): void;
3716
3992
  }
3717
3993
  declare function createInMemorySessionStore(): InMemorySessionStore;
@@ -3722,7 +3998,6 @@ declare class InMemoryTurnStore implements TurnStore {
3722
3998
  put(record: StoredTurnRecord): Promise<void>;
3723
3999
  update(sessionId: SessionId, id: TurnId, updater: (record: StoredTurnRecord) => StoredTurnRecord): Promise<StoredTurnRecord>;
3724
4000
  close(): Promise<void>;
3725
- /** Internal aggregate-transaction rollback hook. */
3726
4001
  restore(sessionId: SessionId, records: readonly StoredTurnRecord[]): void;
3727
4002
  }
3728
4003
  declare function createInMemoryTurnStore(): InMemoryTurnStore;
@@ -3733,7 +4008,6 @@ declare class InMemoryToolCallStore implements ToolCallStore {
3733
4008
  put(record: StoredToolCallRecord): Promise<void>;
3734
4009
  update(sessionId: SessionId, id: ToolCallId, updater: (record: StoredToolCallRecord) => StoredToolCallRecord): Promise<StoredToolCallRecord>;
3735
4010
  close(): Promise<void>;
3736
- /** Internal aggregate-transaction rollback hook. */
3737
4011
  restore(sessionId: SessionId, records: readonly StoredToolCallRecord[]): void;
3738
4012
  }
3739
4013
  declare function createInMemoryToolCallStore(): InMemoryToolCallStore;
@@ -3741,33 +4015,28 @@ declare class InMemorySessionLeaseStore implements SessionLeaseStore {
3741
4015
  #private;
3742
4016
  constructor(now?: () => number);
3743
4017
  acquire(sessionId: SessionId, holder: string, ttlMs: number): Promise<SessionLease | null>;
3744
- renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number): Promise<SessionLease | null>;
3745
- release(sessionId: SessionId, holder: string, fence: number): Promise<void>;
4018
+ renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number, generationId: string): Promise<SessionLease | null>;
4019
+ release(sessionId: SessionId, holder: string, fence: number, generationId: string): Promise<void>;
4020
+ getCurrent(sessionId: SessionId): SessionLease | null;
3746
4021
  get(sessionId: SessionId): Promise<SessionLease | null>;
3747
4022
  listRecoveryCandidates(options: {
3748
4023
  readonly nowMs: number;
3749
4024
  readonly limit: number;
3750
4025
  readonly cursor?: string;
3751
4026
  }): Promise<{
3752
- readonly sessionIds: readonly SessionId[];
4027
+ readonly candidates: readonly SessionRecoveryCandidate[];
3753
4028
  readonly nextCursor?: string;
3754
4029
  }>;
4030
+ acknowledgeRecoveryCandidate(candidate: SessionRecoveryCandidate): Promise<void>;
3755
4031
  close(): Promise<void>;
3756
4032
  }
3757
4033
 
3758
4034
  interface InMemoryDurableRuntimeStore extends DurableRuntimeStore {
3759
4035
  readonly outbox: readonly DurableOutboxEvent[];
4036
+ currentLease(sessionId: SessionId): SessionLease | null;
3760
4037
  }
3761
4038
  interface InMemoryDurableRuntimeStoreOptions {
3762
4039
  readonly nowMs?: () => number;
3763
- /**
3764
- * Legacy stores can be supplied while callers migrate to DurableRuntimeStore.
3765
- * The aggregate transaction facade serializes access to them and uses the
3766
- * optional internal restore hooks when the store provides one. Custom stores
3767
- * without those hooks receive ordering isolation but cannot receive a full
3768
- * rollback guarantee; production adapters should implement DurableRuntimeStore
3769
- * directly when atomicity is required.
3770
- */
3771
4040
  readonly sessionStore?: SessionStore;
3772
4041
  readonly turnStore?: TurnStore;
3773
4042
  readonly toolCallStore?: ToolCallStore;
@@ -3795,78 +4064,57 @@ declare class InMemoryMemory implements Memory {
3795
4064
  }
3796
4065
  declare function createInMemoryMemory(options?: InMemoryMemoryOptions): InMemoryMemory;
3797
4066
 
4067
+ declare function idempotencyKeyFor<TInput, TOutput>(input: ExecuteToolInput<TInput, TOutput>): string | null;
4068
+ declare function idempotencyRequestHashFor<TInput, TOutput>(input: ExecuteToolInput<TInput, TOutput>): string;
4069
+
3798
4070
  declare function stableStringify(value: unknown): string;
3799
4071
 
3800
4072
  interface SchemaValidationResult {
3801
4073
  readonly valid: boolean;
3802
4074
  readonly errors: readonly string[];
3803
4075
  }
3804
- /**
3805
- * Validates a value against a deliberately small, well-defined subset of JSON Schema
3806
- * (Draft-07 keywords): `type` (incl. "integer"), `enum`, `const`, object
3807
- * `properties` / `required` / `additionalProperties: false`, array `items` /
3808
- * `minItems` / `maxItems`, string `minLength` / `maxLength`, and numeric `minimum` /
3809
- * `maximum`. It is intentionally NOT a full validator: unsupported keywords are
3810
- * ignored. Swap in Ajv at the call site if full JSON Schema compliance is required.
3811
- */
3812
4076
  declare function validateJsonSchemaSubset(value: unknown, schema: Readonly<Record<string, unknown>>, path?: string): SchemaValidationResult;
3813
4077
 
4078
+ type InMemoryLeaseSnapshot = {
4079
+ readonly holder: string;
4080
+ readonly fence: number;
4081
+ readonly generationId: string;
4082
+ readonly expiresAtMs: number;
4083
+ };
4084
+ declare class InMemoryToolIdempotencyStore implements ToolIdempotencyStore {
4085
+ #private;
4086
+ constructor(now?: () => number, readLeaseSnapshot?: (sessionId: SessionId) => InMemoryLeaseSnapshot | null);
4087
+ pruneExpired(): number;
4088
+ lookup(key: string, requestHash: string, sessionId?: SessionId, lease?: ToolIdempotencyLease): Promise<ToolIdempotencyLookupResult>;
4089
+ claim(input: ToolIdempotencyClaim): Promise<ToolIdempotencyClaimResult>;
4090
+ releaseClaim(input: ToolIdempotencyRelease): Promise<boolean>;
4091
+ complete(key: string, requestHash: string, outcome: ToolIdempotencyOutcome): Promise<void>;
4092
+ quarantine(input: ToolIdempotencyQuarantine): Promise<ToolIdempotencyQuarantineResult>;
4093
+ }
4094
+
3814
4095
  interface ToolRegistry {
3815
4096
  register(tool: ToolDefinition): void;
3816
4097
  get(id: ToolId): ToolDefinition | null;
3817
4098
  list(): readonly ToolDefinition[];
3818
4099
  }
3819
4100
  declare function createToolRegistry(tools?: readonly ToolDefinition[]): ToolRegistry;
3820
- declare class InMemoryToolIdempotencyStore implements ToolIdempotencyStore {
3821
- #private;
3822
- constructor(now?: () => number, readLease?: (sessionId: SessionId) => Promise<{
3823
- readonly holder: string;
3824
- readonly fence: number;
3825
- readonly expiresAtMs: number;
3826
- } | null>);
3827
- lookup(key: string, requestHash: string): Promise<ToolIdempotencyRecord | null>;
3828
- claim(input: ToolIdempotencyClaim): Promise<ToolIdempotencyClaimResult>;
3829
- complete(key: string, requestHash: string, outcome: ToolIdempotencyOutcome): Promise<void>;
3830
- }
4101
+
3831
4102
  interface ExecuteToolInput<TInput, TOutput> {
3832
4103
  readonly tool: ToolDefinition<TInput, TOutput>;
3833
4104
  readonly input: TInput;
3834
4105
  readonly sessionId: SessionId;
3835
4106
  readonly turnId: TurnId;
3836
4107
  readonly toolCallId: ToolCallId;
3837
- /** Reuses the durable queue timestamp when the runtime has already persisted the call. */
3838
4108
  readonly queuedAt?: Timestamp;
3839
4109
  readonly attempt?: number;
3840
4110
  readonly logger?: ToolLogger;
3841
4111
  readonly now?: () => Date;
3842
- /** Aborts the tool call (e.g. on barge-in). The tool's ctx.signal mirrors this. */
3843
4112
  readonly signal?: AbortSignal;
3844
- /** Current process lease used to fence durable idempotency operations. */
3845
4113
  readonly lease?: ToolIdempotencyLease;
3846
- /** Honours the tool's idempotency policy when provided. */
3847
4114
  readonly idempotencyStore?: ToolIdempotencyStore;
3848
- /**
3849
- * Tenant identity propagated into the tool's `ctx.tenant`. The runtime
3850
- * populates this from the session attachment's `memoryUserId` /
3851
- * `organizationId` / `workflowId` so the tool can enforce its own
3852
- * auth/RBAC. TVIC ships no auth layer; the tool author reads
3853
- * `ctx.tenant` and decides.
3854
- */
3855
4115
  readonly tenant?: ToolTenant;
3856
4116
  }
3857
- /**
3858
- * Performs the input checks that must complete before a tool call reaches a
3859
- * durable store. Keeping this at the tools boundary lets the runtime reject
3860
- * provider-produced values before it creates queued/running records.
3861
- */
3862
4117
  declare function toolInputError(value: unknown, schema: Readonly<Record<string, unknown>>): NormalizedError | null;
3863
- declare function idempotencyKeyFor<TInput, TOutput>(input: ExecuteToolInput<TInput, TOutput>): string | null;
3864
- /**
3865
- * The request hash paired with idempotencyKeyFor. Keep this beside the key
3866
- * builder so execution and crash recovery cannot silently hash different
3867
- * request shapes.
3868
- */
3869
- declare function idempotencyRequestHashFor<TInput, TOutput>(input: ExecuteToolInput<TInput, TOutput>): string;
3870
4118
  declare function executeTool<TInput = unknown, TOutput = unknown>(input: ExecuteToolInput<TInput, TOutput>): Promise<ToolCall>;
3871
4119
 
3872
4120
  interface PersistedErrorCompatibilityDiagnostic {
@@ -3884,9 +4132,31 @@ declare class PostgresToolIdempotencyStore implements ToolIdempotencyStore {
3884
4132
  constructor(client: SqlClient$1, options?: {
3885
4133
  readonly onCompatibilityDiagnostic?: (diagnostic: PersistedErrorCompatibilityDiagnostic) => void;
3886
4134
  });
3887
- lookup(key: string, requestHash: string): Promise<ToolIdempotencyRecord | null>;
4135
+ lookup(key: string, requestHash: string, sessionId?: SessionId, lease?: NonNullable<ToolIdempotencyClaim["lease"]>): Promise<ToolIdempotencyLookupResult>;
3888
4136
  claim(input: ToolIdempotencyClaim): Promise<ToolIdempotencyClaimResult>;
4137
+ releaseClaim(input: ToolIdempotencyRelease): Promise<boolean>;
3889
4138
  complete(key: string, requestHash: string, outcome: ToolIdempotencyOutcome): Promise<void>;
4139
+ quarantine(input: ToolIdempotencyQuarantine): Promise<ToolIdempotencyQuarantineResult>;
4140
+ }
4141
+
4142
+ declare class PostgresSessionLeaseStore implements SessionLeaseStore {
4143
+ readonly client: SqlPool$1;
4144
+ constructor(client: SqlPool$1);
4145
+ acquire(sessionId: SessionId, holder: string, ttlMs: number): Promise<SessionLease | null>;
4146
+ renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number, generationId: string): Promise<SessionLease | null>;
4147
+ release(sessionId: SessionId, holder: string, fence: number, generationId: string): Promise<void>;
4148
+ get(sessionId: SessionId): Promise<SessionLease | null>;
4149
+ listRecoveryCandidates(options: {
4150
+ readonly nowMs: number;
4151
+ readonly limit: number;
4152
+ readonly cursor?: string;
4153
+ }): Promise<{
4154
+ readonly candidates: readonly SessionRecoveryCandidate[];
4155
+ readonly corruptLeaseSessionIds?: readonly SessionId[];
4156
+ readonly nextCursor?: string;
4157
+ }>;
4158
+ acknowledgeRecoveryCandidate(candidate: SessionRecoveryCandidate): Promise<void>;
4159
+ close(): Promise<void>;
3890
4160
  }
3891
4161
 
3892
4162
  interface PostgresOutboxWorkerOptions {
@@ -3901,12 +4171,37 @@ interface PostgresOutboxWorkerOptions {
3901
4171
  }) => void;
3902
4172
  }
3903
4173
 
4174
+ interface PostgresRetentionSessionIdentity {
4175
+ readonly sessionId: string;
4176
+ readonly incarnation: number | string;
4177
+ readonly version: number | string;
4178
+ readonly fence: number | string;
4179
+ }
4180
+ interface PostgresRetentionJobOptions {
4181
+ readonly pool: SqlPool$1;
4182
+ readonly terminalRetentionMs: number;
4183
+ readonly outboxRetentionMs?: number;
4184
+ readonly hasLegalHold: (sessionId: string) => Promise<boolean>;
4185
+ readonly archive?: (sessionId: string) => Promise<void>;
4186
+ readonly beforeSessionDelete?: (candidate: PostgresRetentionSessionIdentity, purgeToken: string) => Promise<void>;
4187
+ readonly afterSessionDeleteFailure?: (candidate: PostgresRetentionSessionIdentity, purgeToken: string) => Promise<void>;
4188
+ }
4189
+ interface RetentionRunResult {
4190
+ readonly sessionsDeleted: number;
4191
+ readonly outboxDeleted: number;
4192
+ readonly idempotencyDeleted: number;
4193
+ }
4194
+ declare class PostgresRetentionJob {
4195
+ #private;
4196
+ constructor(options: PostgresRetentionJobOptions);
4197
+ runOnce(): Promise<RetentionRunResult>;
4198
+ }
4199
+
3904
4200
  interface PostgresMigration$1 {
3905
4201
  readonly version: number;
3906
4202
  readonly name: string;
3907
4203
  readonly sql: string;
3908
4204
  }
3909
- /** Runs the ordered SQL files exactly once and records the applied filename. */
3910
4205
  declare function runPostgresMigrations(pool: SqlPool$1, migrations?: readonly PostgresMigration$1[]): Promise<readonly number[]>;
3911
4206
 
3912
4207
  interface SqlResult<Row extends Record<string, unknown> = Record<string, unknown>> {
@@ -3920,9 +4215,12 @@ interface SqlPool$1 extends SqlClient$1 {
3920
4215
  connect(): Promise<SqlClient$1 & {
3921
4216
  readonly release: () => void;
3922
4217
  }>;
3923
- /** If provided, the durable store owns this pool and calls it once on close. */
3924
4218
  end?(): Promise<void>;
3925
4219
  }
4220
+ interface PostgresSessionChildPage<RecordType> {
4221
+ readonly records: readonly RecordType[];
4222
+ readonly nextCursor: string | undefined;
4223
+ }
3926
4224
  interface PostgresDurableStoreOptions {
3927
4225
  readonly pool: SqlPool$1;
3928
4226
  }
@@ -3940,6 +4238,7 @@ declare class PostgresTurnStore implements TurnStore {
3940
4238
  constructor(client: SqlClient$1);
3941
4239
  get(sessionId: SessionId, id: TurnId): Promise<StoredTurnRecord | null>;
3942
4240
  listBySession(sessionId: SessionId): Promise<readonly StoredTurnRecord[]>;
4241
+ listBySessionPage(sessionId: SessionId, afterId?: string, pageSize?: number): Promise<PostgresSessionChildPage<StoredTurnRecord>>;
3943
4242
  put(record: StoredTurnRecord): Promise<void>;
3944
4243
  update(sessionId: SessionId, id: TurnId, updater: (record: StoredTurnRecord) => StoredTurnRecord): Promise<StoredTurnRecord>;
3945
4244
  close(): Promise<void>;
@@ -3949,27 +4248,11 @@ declare class PostgresToolCallStore implements ToolCallStore {
3949
4248
  constructor(client: SqlClient$1);
3950
4249
  get(sessionId: SessionId, id: ToolCallId): Promise<StoredToolCallRecord | null>;
3951
4250
  listBySession(sessionId: SessionId): Promise<readonly StoredToolCallRecord[]>;
4251
+ listBySessionPage(sessionId: SessionId, afterId?: string, pageSize?: number): Promise<PostgresSessionChildPage<StoredToolCallRecord>>;
3952
4252
  put(record: StoredToolCallRecord): Promise<void>;
3953
4253
  update(sessionId: SessionId, id: ToolCallId, updater: (record: StoredToolCallRecord) => StoredToolCallRecord): Promise<StoredToolCallRecord>;
3954
4254
  close(): Promise<void>;
3955
4255
  }
3956
- declare class PostgresSessionLeaseStore implements SessionLeaseStore {
3957
- readonly client: SqlPool$1;
3958
- constructor(client: SqlPool$1);
3959
- acquire(sessionId: SessionId, holder: string, ttlMs: number): Promise<SessionLease | null>;
3960
- renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number): Promise<SessionLease | null>;
3961
- release(sessionId: SessionId, holder: string, fence: number): Promise<void>;
3962
- get(sessionId: SessionId): Promise<SessionLease | null>;
3963
- listRecoveryCandidates(options: {
3964
- readonly nowMs: number;
3965
- readonly limit: number;
3966
- readonly cursor?: string;
3967
- }): Promise<{
3968
- readonly sessionIds: readonly SessionId[];
3969
- readonly nextCursor?: string;
3970
- }>;
3971
- close(): Promise<void>;
3972
- }
3973
4256
  declare class PostgresDurableRuntimeStore implements DurableRuntimeStore {
3974
4257
  #private;
3975
4258
  readonly pool: SqlPool$1;
@@ -3980,7 +4263,7 @@ declare class PostgresDurableRuntimeStore implements DurableRuntimeStore {
3980
4263
  readonly toolIdempotencyStore: PostgresToolIdempotencyStore;
3981
4264
  constructor(pool: SqlPool$1);
3982
4265
  createSessionWithLease(record: StoredSessionRecord, holder: string, ttlMs: number, initialEvent?: (lease: SessionLease) => DurableOutboxEvent): Promise<SessionLease | null>;
3983
- runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
4266
+ runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence" | "generationId">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
3984
4267
  runUnfencedSessionTransaction<T>(sessionId: SessionId, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
3985
4268
  close(): Promise<void>;
3986
4269
  }
@@ -3990,23 +4273,70 @@ declare class RedisToolIdempotencyStore implements ToolIdempotencyStore {
3990
4273
  #private;
3991
4274
  readonly client: RedisClient;
3992
4275
  constructor(client: RedisClient, options?: RedisStoreOptions);
3993
- lookup(key: string, _requestHash: string): Promise<ToolIdempotencyRecord | null>;
4276
+ lookup(key: string, requestHash: string, sessionId?: SessionId, lease?: ToolIdempotencyClaim["lease"]): Promise<ToolIdempotencyLookupResult>;
3994
4277
  claim(input: ToolIdempotencyClaim): Promise<ToolIdempotencyClaimResult>;
4278
+ releaseClaim(input: ToolIdempotencyRelease): Promise<boolean>;
3995
4279
  complete(key: string, requestHash: string, outcome: ToolIdempotencyOutcome): Promise<void>;
4280
+ quarantine(input: ToolIdempotencyQuarantine): Promise<ToolIdempotencyQuarantineResult>;
4281
+ pruneExpiredIdempotencyPage(cursor?: string, limit?: number): Promise<{
4282
+ readonly cursor: string;
4283
+ readonly scanned: number;
4284
+ readonly deleted: number;
4285
+ }>;
3996
4286
  }
3997
4287
 
3998
- /**
3999
- * Applies Postgres outbox events to Redis as a version/fence guarded cache.
4000
- * Redis is intentionally not a second runtime authority: a cache event can be
4001
- * replayed, duplicated, or delivered out of order without replacing a newer
4002
- * value. Postgres remains the source of truth and the outbox worker supplies
4003
- * the retry boundary.
4004
- */
4288
+ declare class RedisSessionStore implements SessionStore {
4289
+ readonly client: RedisClient;
4290
+ readonly options: RedisStoreOptions;
4291
+ constructor(client: RedisClient, options?: RedisStoreOptions);
4292
+ get(id: SessionId): Promise<StoredSessionRecord | null>;
4293
+ list(): Promise<readonly StoredSessionRecord[]>;
4294
+ put(record: StoredSessionRecord): Promise<void>;
4295
+ update(id: SessionId, updater: (record: StoredSessionRecord) => StoredSessionRecord): Promise<StoredSessionRecord>;
4296
+ close(): Promise<void>;
4297
+ }
4298
+ declare class RedisTurnStore implements TurnStore {
4299
+ readonly client: RedisClient;
4300
+ readonly options: RedisStoreOptions;
4301
+ constructor(client: RedisClient, options?: RedisStoreOptions);
4302
+ get(sessionId: SessionId, id: TurnId): Promise<StoredTurnRecord | null>;
4303
+ listBySession(sessionId: SessionId): Promise<readonly StoredTurnRecord[]>;
4304
+ put(record: StoredTurnRecord): Promise<void>;
4305
+ update(sessionId: SessionId, id: TurnId, updater: (record: StoredTurnRecord) => StoredTurnRecord): Promise<StoredTurnRecord>;
4306
+ close(): Promise<void>;
4307
+ }
4308
+ declare class RedisToolCallStore implements ToolCallStore {
4309
+ readonly client: RedisClient;
4310
+ readonly options: RedisStoreOptions;
4311
+ constructor(client: RedisClient, options?: RedisStoreOptions);
4312
+ get(sessionId: SessionId, id: ToolCallId): Promise<StoredToolCallRecord | null>;
4313
+ listBySession(sessionId: SessionId): Promise<readonly StoredToolCallRecord[]>;
4314
+ put(record: StoredToolCallRecord): Promise<void>;
4315
+ update(sessionId: SessionId, id: ToolCallId, updater: (record: StoredToolCallRecord) => StoredToolCallRecord): Promise<StoredToolCallRecord>;
4316
+ close(): Promise<void>;
4317
+ }
4318
+
4319
+ interface ProjectedSessionRetentionIdentity {
4320
+ readonly sessionId: SessionId;
4321
+ readonly incarnation: number | string;
4322
+ readonly version: number | string;
4323
+ readonly fence: number | string;
4324
+ }
4325
+ interface ProjectedSessionCacheSnapshot {
4326
+ readonly session: StoredSessionRecord;
4327
+ readonly turns: Iterable<StoredTurnRecord> | AsyncIterable<StoredTurnRecord>;
4328
+ readonly toolCalls: Iterable<StoredToolCallRecord> | AsyncIterable<StoredToolCallRecord>;
4329
+ }
4005
4330
  declare class RedisOutboxCacheProjector {
4331
+ #private;
4006
4332
  readonly client: RedisClient;
4007
4333
  readonly options: RedisStoreOptions;
4008
4334
  constructor(client: RedisClient, options?: RedisStoreOptions);
4009
4335
  apply(event: DurableOutboxEvent): Promise<void>;
4336
+ purgeSession(identity: ProjectedSessionRetentionIdentity, purgeToken: string): Promise<void>;
4337
+ resumeSessionPurge(identity: ProjectedSessionRetentionIdentity, purgeToken: string): Promise<boolean>;
4338
+ getSessionPurgeToken(identity: Pick<ProjectedSessionRetentionIdentity, "sessionId" | "incarnation">): Promise<string | null>;
4339
+ restoreSessionProjection(identity: ProjectedSessionRetentionIdentity, purgeToken: string, snapshot: ProjectedSessionCacheSnapshot): Promise<void>;
4010
4340
  }
4011
4341
 
4012
4342
  type RedisSetResult = "OK" | "ok" | boolean | null;
@@ -4018,6 +4348,7 @@ interface RedisClient {
4018
4348
  get(key: string): Promise<string | null>;
4019
4349
  set(key: string, value: string, options?: {
4020
4350
  readonly NX?: boolean;
4351
+ readonly PX?: number;
4021
4352
  }): Promise<RedisSetResult>;
4022
4353
  del(...keys: readonly string[]): Promise<number>;
4023
4354
  eval(script: string, keys: readonly string[], args: readonly string[]): Promise<unknown>;
@@ -4031,7 +4362,9 @@ interface RedisClient {
4031
4362
  quit?(): Promise<void>;
4032
4363
  }
4033
4364
  interface RedisMulti {
4034
- set(key: string, value: string): RedisMulti;
4365
+ set(key: string, value: string, options?: {
4366
+ readonly PX?: number;
4367
+ }): RedisMulti;
4035
4368
  del(...keys: readonly string[]): RedisMulti;
4036
4369
  exec(): Promise<readonly unknown[] | null>;
4037
4370
  }
@@ -4043,52 +4376,24 @@ interface RedisStoreOptions {
4043
4376
  readonly onCompatibilityDiagnostic?: (diagnostic: PersistedErrorCompatibilityDiagnostic) => void;
4044
4377
  }
4045
4378
 
4046
- declare class RedisSessionStore implements SessionStore {
4047
- readonly client: RedisClient;
4048
- readonly options: RedisStoreOptions;
4049
- constructor(client: RedisClient, options?: RedisStoreOptions);
4050
- get(id: SessionId): Promise<StoredSessionRecord | null>;
4051
- list(): Promise<readonly StoredSessionRecord[]>;
4052
- put(record: StoredSessionRecord): Promise<void>;
4053
- update(id: SessionId, updater: (record: StoredSessionRecord) => StoredSessionRecord): Promise<StoredSessionRecord>;
4054
- close(): Promise<void>;
4055
- }
4056
- declare class RedisTurnStore implements TurnStore {
4057
- readonly client: RedisClient;
4058
- readonly options: RedisStoreOptions;
4059
- constructor(client: RedisClient, options?: RedisStoreOptions);
4060
- get(sessionId: SessionId, id: TurnId): Promise<StoredTurnRecord | null>;
4061
- listBySession(sessionId: SessionId): Promise<readonly StoredTurnRecord[]>;
4062
- put(record: StoredTurnRecord): Promise<void>;
4063
- update(sessionId: SessionId, id: TurnId, updater: (record: StoredTurnRecord) => StoredTurnRecord): Promise<StoredTurnRecord>;
4064
- close(): Promise<void>;
4065
- }
4066
- declare class RedisToolCallStore implements ToolCallStore {
4067
- readonly client: RedisClient;
4068
- readonly options: RedisStoreOptions;
4069
- constructor(client: RedisClient, options?: RedisStoreOptions);
4070
- get(sessionId: SessionId, id: ToolCallId): Promise<StoredToolCallRecord | null>;
4071
- listBySession(sessionId: SessionId): Promise<readonly StoredToolCallRecord[]>;
4072
- put(record: StoredToolCallRecord): Promise<void>;
4073
- update(sessionId: SessionId, id: ToolCallId, updater: (record: StoredToolCallRecord) => StoredToolCallRecord): Promise<StoredToolCallRecord>;
4074
- close(): Promise<void>;
4075
- }
4076
4379
  declare class RedisSessionLeaseStore implements SessionLeaseStore {
4077
4380
  #private;
4078
4381
  readonly client: RedisClient;
4079
4382
  constructor(client: RedisClient, options?: RedisStoreOptions);
4080
4383
  acquire(sessionId: SessionId, holder: string, ttlMs: number): Promise<SessionLease | null>;
4081
- renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number): Promise<SessionLease | null>;
4082
- release(sessionId: SessionId, holder: string, fence: number): Promise<void>;
4384
+ renew(sessionId: SessionId, holder: string, fence: number, ttlMs: number, generationId: string): Promise<SessionLease | null>;
4385
+ release(sessionId: SessionId, holder: string, fence: number, generationId: string): Promise<void>;
4083
4386
  get(sessionId: SessionId): Promise<SessionLease | null>;
4084
4387
  listRecoveryCandidates(options: {
4085
4388
  readonly nowMs: number;
4086
4389
  readonly limit: number;
4087
4390
  readonly cursor?: string;
4088
4391
  }): Promise<{
4089
- readonly sessionIds: readonly SessionId[];
4392
+ readonly candidates: readonly SessionRecoveryCandidate[];
4393
+ readonly corruptLeaseSessionIds?: readonly SessionId[];
4090
4394
  readonly nextCursor?: string;
4091
4395
  }>;
4396
+ acknowledgeRecoveryCandidate(candidate: SessionRecoveryCandidate): Promise<void>;
4092
4397
  close(): Promise<void>;
4093
4398
  }
4094
4399
  declare class RedisDurableRuntimeStore implements DurableRuntimeStore {
@@ -4100,7 +4405,7 @@ declare class RedisDurableRuntimeStore implements DurableRuntimeStore {
4100
4405
  readonly toolIdempotencyStore: RedisToolIdempotencyStore;
4101
4406
  constructor(client: RedisClient, options?: RedisStoreOptions);
4102
4407
  createSessionWithLease(record: StoredSessionRecord, holder: string, ttlMs: number, initialEvent?: (lease: SessionLease) => DurableOutboxEvent): Promise<SessionLease | null>;
4103
- runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
4408
+ runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence" | "generationId">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
4104
4409
  runUnfencedSessionTransaction<T>(sessionId: SessionId, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
4105
4410
  close(): Promise<void>;
4106
4411
  }
@@ -4111,12 +4416,6 @@ interface PostgresRedisDurableStoreOptions {
4111
4416
  readonly redis: RedisClient;
4112
4417
  readonly redisOptions?: RedisStoreOptions;
4113
4418
  }
4114
- /**
4115
- * The production composition: PostgreSQL owns all mutations, leases,
4116
- * idempotency, and reads; the outbox asynchronously projects committed
4117
- * envelopes into Redis. A Redis outage therefore cannot turn a committed
4118
- * runtime mutation into a failed domain operation.
4119
- */
4120
4419
  declare class PostgresRedisDurableRuntimeStore implements DurableRuntimeStore {
4121
4420
  #private;
4122
4421
  readonly primary: PostgresDurableRuntimeStore;
@@ -4128,9 +4427,10 @@ declare class PostgresRedisDurableRuntimeStore implements DurableRuntimeStore {
4128
4427
  readonly toolIdempotencyStore: ToolIdempotencyStore;
4129
4428
  constructor(options: PostgresRedisDurableStoreOptions);
4130
4429
  createSessionWithLease(record: StoredSessionRecord, holder: string, ttlMs: number, initialEvent?: (lease: SessionLease) => DurableOutboxEvent): Promise<SessionLease | null>;
4131
- runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
4430
+ runSessionTransaction<T>(sessionId: SessionId, lease: Pick<SessionLease, "holder" | "fence" | "generationId">, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
4132
4431
  runUnfencedSessionTransaction<T>(sessionId: SessionId, operation: (tx: DurableSessionTransaction) => Promise<T>): Promise<T>;
4133
4432
  startOutboxWorker(options: Omit<PostgresOutboxWorkerOptions, "pool" | "deliver">): void;
4433
+ createRetentionJob(options: Omit<PostgresRetentionJobOptions, "pool">): PostgresRetentionJob;
4134
4434
  stopOutboxWorker(): Promise<void>;
4135
4435
  close(): Promise<void>;
4136
4436
  }
@@ -4186,5 +4486,5 @@ declare class PostgresMemory implements Memory {
4186
4486
  }
4187
4487
  declare function createPostgresMemory(options: PostgresMemoryOptions): PostgresMemory;
4188
4488
 
4189
- export { ADAPTER_DEFAULTS, AssemblyAiSttProvider, AsyncQueue, AsyncQueueConsumerError, BackendUnavailableError, CartesiaTtsProvider, ConversationPolicy, CorruptRecordError, DEFAULT_DURABLE_RUNTIME_POLICY, DTMF_DIGITS, DeepgramSttProvider, DurableError, EVENT_KIND_MAP, ElevenLabsSttProvider, ElevenLabsTtsProvider, InMemoryMemory, InMemorySessionLeaseStore, InMemorySessionStore, InMemoryToolCallStore, InMemoryToolIdempotencyStore, InMemoryTurnStore, InvalidArgumentError, LeaseLostError, LeaseUnavailableError, MemoryBackendUnavailableError, MemoryEntryTooLargeError, MemorySessionQuotaExceededError, NodeMediaPlane, PCM16_16K_MONO, PCM16_8K_MONO, PROVIDER_API_VERSIONS, PROVIDER_CATALOG, PROVIDER_ERROR_CODES, PROVIDER_NAMES, PROVIDER_STABILITY, PipelineVoiceLoop, PipelineVoiceLoopBuilder, RUNTIME_SAMPLE_RATE_HZ, RecordConflictError, RecordNotFoundError, STT_ERROR_CODES, STT_STREAM_ENDED_REASON, SarvamSttProvider, SessionReaper, SessionRecoveryCoordinator, SonioxSttProvider, TELEPHONY_SAMPLE_RATE_HZ, TVIC_ERROR_CODES, TVIC_ERROR_CODE_ALIASES, TVIC_ERROR_MARKER, TVIC_ERROR_NAMES, TvicThrowableError, TwilioMediaStreamCallHandle, TwilioMediaStreamsProvider, VoiceRuntimeFinalizationError, WEB_CLIENT_AUDIO_CLOSE_CODES, WEB_CLIENT_AUDIO_DEFAULTS, WebClientAudioCallHandle, WebClientAudioProvider, assertMemoryCapability, assertMemoryPolicySupported, assertPcm16leFormat, authError, base64ToBytes, bytesToBase64, cancelledError, canonicalizeTwilioData, computeTwilioSignature, connectionError, counterIdGenerator, createAssemblyAiSttProvider, createAudioNormalizer, createCartesiaTtsProvider, createDeepgramSttProvider, createDefaultIdGenerator, createElevenLabsSttProvider, createElevenLabsTtsProvider, createGroqChatLlmProvider, createInMemoryDurableRuntimeStore, createInMemoryMemory, createInMemorySessionStore, createInMemoryToolCallStore, createInMemoryTurnStore, createMediaEvent, createNodeMediaPlane, createOpenAiResponsesLlmProvider, createPostgresDurableRuntimeStore, createPostgresMemory, createPostgresRedisDurableRuntimeStore, createRedisDurableRuntimeStore, createRuntime, createSarvamSttProvider, createSonioxSttProvider, createSttSession, createSystemClock, createToolRegistry, createTwilioMediaStreamsProvider, createVoiceAgent, createWebClientAudioProvider, defineAgent, defineTool, deliverAssistantText, durationMsForPcm16le, evaluateProviderCompatibility, executeTool, formatMemoryContextAsSystemBlock, formatPreCallContextAsSystemBlock, frameCountForPcm16le, getSttRecoveryControl, idempotencyKeyFor, idempotencyRequestHashFor, internalError, interruptedError, isDtmfDigit, isIncrementalTextToSpeechProvider, isInputMediaEvent, isNormalizedError, isOutputMediaEvent, isProviderKind, isReconstructableAudioFormat, isSampleRateHz, isTerminalSession, isTerminalTurn, isTranscriptSegmentEvent, isTvicError, isTvicErrorName, kindForMediaEvent, matchPath, mediaError, monotonicOffsetMs, mulawToPcm16le, normalizeLegacyError, normalizeUnknownError, normalizedError, nowTimestamp, pcm16leToMulaw, providerError, rateLimitError, requireProviderKind, resamplePcm16le, resolvePreCallContext, resolvePreCallMemory, runPostgresMemoryMigrations, runPostgresMigrations, sameAudioFormat, shouldDeliverText, signVoiceSessionToken, signatureError, splitPcm16leFrames, stableStringify, supportsAudioFormat, supportsLanguage, supportsModel, terminalSessionFromRequest, terminalSourceForRequest, terminalTurnFromRequest, timeoutError, toTimestamp, toolError, toolInputError, tvicErrorFromJSON, unknownErrorMessage, validateJsonSchemaSubset, validationError, verifyTwilioSignature, verifyVoiceSessionToken, withSttReconnect };
4190
- export type { ActiveSession, ActiveTurn, Agent, AgentAudioPolicy, AgentContextPolicy, AgentId, AgentMemoryPolicy, AgentProviders, AnyMediaEventInit, AssemblyAiProviderConfig, AssemblyAiSttProviderOptions, AssistantTextRecord, AudioFormat, AudioNormalizationMode, AudioNormalizer, AudioNormalizerOptions, AudioPayload, BackoffStrategy, Brand, Call, CallControlCapability, CallDirection, CallHandle, CallId, CallSnapshot, CallStatus, CancelledSession, CancelledTurn, CartesiaProviderConfig, CartesiaTtsProviderOptions, ChannelKind, ChannelLayout, CleanupErrorSummary, CleanupStage, Clock, CompletedSession, CompletedTurn, ConnectedCall, ConnectionObservabilityEvent, ConversationPolicyOptions, CounterIdGenerator, CreateVoiceAgentOptions, CreatedCall, CreatedSession, DeepgramProviderConfig, DeepgramSttProviderOptions, DefineAgentInput, DefineToolInput, DtmfDigit, DtmfReceivedEvent, DualProtocolResult, DurableErrorCode, DurableOutboxEvent, DurableRuntimeMetric, DurableRuntimePolicy, DurableRuntimeStore, DurableSessionTransaction, ElevenLabsSttCommitStrategy, ElevenLabsSttProviderConfig, ElevenLabsSttProviderOptions, ElevenLabsTtsProviderConfig, ElevenLabsTtsProviderOptions, EndSessionReason, EndSessionRequest, EndTurnRequest, EndedCall, ErrorCategory, ExecuteToolInput, FailedCall, FailedSession, FailedToolCall, FailedToolCallStatus, FailedTurn, GroqChatLlmProviderOptions, GroqProviderConfig, HealthCheckResult, HealthSnapshot, IdGenerator, IdempotencyPolicy, InMemoryDurableRuntimeStore, InMemoryDurableRuntimeStoreOptions, InMemoryMemoryOptions, InboundCallContext, InboundMediaEvent, IncrementalTextToSpeechProvider, InputAudioChunk, InputMediaEvent, InternalMediaEvent, InterruptRequestedEvent, InterruptionMode, InterruptionPolicy, JsonSchemaDocument, JsonValue, LLMProvider, LiveTerminalSource, LlmCompletion, LlmCompletionRequest, LlmInlineToolCall, LlmMessage, LlmMessageRole, LlmProviderConfig, LlmStreamEvent, LlmUsage, MediaAudioChunkEvent, MediaAudioCommittedEvent, MediaDirection, MediaErrorEvent, MediaEvent, MediaEventId, MediaEventKind, MediaEventType, MediaStreamEndedEvent, MediaStreamStartedEvent, MediaTransport, MediaTransportKind, Memory, MemoryCapabilities, MemoryEntry, MemoryEntryId, MemoryKind, MemoryPutOptions, MemoryQuery, MemoryRef, MemoryScope, NodeMediaPlaneConnection, NodeMediaPlaneConnectionErrorHandler, NodeMediaPlaneConnectionHandler, NodeMediaPlaneOptions, NodeMediaPlaneRequestHandler, NormalizedAudioEncoding, NormalizedError, OpenAiProviderConfig, OpenAiResponsesLlmProviderOptions, OrganizationId, OutboundCallRequest, OutputAudioChunk, OutputMediaEvent, PersonaConfig, PipelineVoiceLoopOptions, PipelineVoiceLoopResult, PostgresDurableStoreOptions, PostgresMemoryOptions, PostgresMigration, PostgresRedisDurableStoreOptions, PreCallContext, PreCallContextResolver, PreCallMemoryContext, PreCallMemoryResolver, Provider, ProviderAudioCapabilities, ProviderCancellationCapabilities, ProviderCapabilities, ProviderCatalogEntry, ProviderCompatibility, ProviderCompatibilityIssue, ProviderCompatibilityIssueCode, ProviderDataPolicy, ProviderEventId, ProviderForKind, ProviderKind, ProviderPlayoutCapabilities, ProviderRequirements, ProviderStability, ProviderStreamingCapabilities, ProviderToolCapabilities, ProviderTransport, QueuedToolCall, RecoveryPollResult, RedisClient, RedisMulti, RedisScanOptions, RedisSetResult, RedisStoreOptions, RequiredProviderCapabilities, RetryPolicy, RingingCall, RunningToolCall, Runtime, RuntimeOptions, RuntimeProvider, RuntimeServiceLifecycle, SampleRateHz, SarvamOutputMode, SarvamProviderConfig, SarvamSttProviderOptions, SchemaValidationResult, Session, SessionAttachment, SessionAttachmentHealth, SessionCancellationReason, SessionEndEvent, SessionEndMemorySnapshot, SessionId, SessionLease, SessionLeaseStore, SessionMemoryFinalization, SessionMetricsRecorder, SessionReaperOptions, SessionRecoveryCoordinatorOptions, SessionRuntimeMetadata, SessionSnapshot, SessionState, SessionStatus, SessionStore, SonioxProviderConfig, SonioxStructuredContext, SonioxSttProviderOptions, SpeechToTextProvider, SqlClient$1 as SqlClient, SqlPool$1 as SqlPool, SqlResult, StartAttachedSessionOptions, StartSessionOptions, StartTurnRequest, StartingSession, StoredSessionRecord, StoredToolCallRecord, StoredTurnRecord, StreamEndReason, SttCommitMode, SttOpenRequest, SttProviderConfig, SttReconnectOptions, SttRecoveryControl, SttRecoveryState, SttSession, SttSessionInputOptions, SttSessionOptions, SttStream, SttTimestampOrigin, SucceededToolCall, TelephonyProvider, TelephonyProviderConfig, TerminalSession, TerminalSessionDraft, TerminalSessionStatus, TerminalSource, TerminalToolCall, TerminalTurn, TextDeliveryMode, TextToSpeechProvider, TimeoutAction, TimeoutPolicy, Timestamp, ToolCall, ToolCallId, ToolCallRuntimeMetadata, ToolCallStatus, ToolCallStore, ToolDefinition, ToolExecutionContext, ToolExecutor, ToolId, ToolIdempotencyClaim, ToolIdempotencyClaimResult, ToolIdempotencyLease, ToolIdempotencyOutcome, ToolIdempotencyRecord, ToolIdempotencyStatus, ToolIdempotencyStore, ToolLogger, ToolName, ToolRegistry, ToolTenant, TranscriptEndpointEvent, TranscriptEndpointReason, TranscriptEvent, TranscriptEventType, TranscriptSegmentEvent, TranscriptSegmentEventType, TranscriptSpeechStartedEvent, TransportAudioEncoding, TransportAudioFormat, TtsAlignmentEvent, TtsAlignmentUnit, TtsEvent, TtsFlushAcknowledgement, TtsFlushCompletedEvent, TtsFlushId, TtsFlushResult, TtsProviderConfig, TtsSession, TtsSessionOpenRequest, TtsStream, TtsSynthesisRequest, Turn, TurnCancellationReason, TurnCommitRequestedEvent, TurnDetectionMode, TurnId, TurnInput, TurnLatency, TurnLatencyRecord, TurnOutput, TurnRuntimeMetadata, TurnStatus, TurnStore, TvicErrorName, TwilioFlatParams, TwilioMediaStreamCallHandleOptions, TwilioMediaStreamSocket, TwilioParamValue, TwilioParams, UpgradeAuthorization, UserId, VerifyTwilioOptions, VerifyVoiceSessionTokenOptions, VoiceAgent, VoiceAgentCallHandleContext, VoiceAgentCallHandleFactory, VoiceAgentModels, VoiceAgentProviderNames, VoiceAgentProviders, VoiceAgentRun, VoiceAgentRunOptions, VoiceAgentSession, VoiceEvent, VoiceRuntimeFailureMetadata, WebClientAudioCallHandleOptions, WebClientAudioConnectionEvent, WebClientAudioProviderOptions, WebClientAudioSocket, WorkflowId };
4489
+ export { ADAPTER_DEFAULTS, AssemblyAiSttProvider, AsyncQueue, AsyncQueueConsumerError, BackendUnavailableError, CartesiaSttProvider, CartesiaTtsProvider, ConversationPolicy, CorruptRecordError, DEFAULT_DURABLE_RUNTIME_POLICY, DTMF_DIGITS, DeepgramSttProvider, DurableError, EVENT_KIND_MAP, ElevenLabsSttProvider, ElevenLabsTtsHttpStreamProvider, ElevenLabsTtsProvider, ElevenLabsTtsRestProvider, InMemoryMemory, InMemorySessionLeaseStore, InMemorySessionStore, InMemoryToolCallStore, InMemoryToolIdempotencyStore, InMemoryTurnStore, InvalidArgumentError, LeaseLostError, LeaseUnavailableError, MAX_CARTESIA_INPUT_UTF16_CODE_UNITS, MAX_CARTESIA_INPUT_UTF8_BYTES, MAX_ERROR_CODE_UTF8_BYTES, MAX_PROVIDER_AUDIO_OFFSET_MS, MAX_RECOVERY_PAGE_SIZE, MAX_SAFE_LEASE_TIMESTAMP, MemoryBackendUnavailableError, MemoryEntryTooLargeError, MemorySessionQuotaExceededError, NodeMediaPlane, PCM16_16K_MONO, PCM16_8K_MONO, PROVIDER_API_VERSIONS, PROVIDER_CATALOG, PROVIDER_ERROR_CODES, PROVIDER_NAMES, PROVIDER_STABILITY, PROVIDER_STABILITY_LEVELS, PipelineVoiceLoop, PipelineVoiceLoopBuilder, RUNTIME_SAMPLE_RATE_HZ, RecordConflictError, RecordNotFoundError, SARVAM_TTS_V4_FLASH_MODEL, STT_ERROR_CODES, STT_STREAM_ENDED_REASON, SarvamSttProvider, SarvamTtsHttpStreamProvider, SarvamTtsProvider, SarvamTtsRestProvider, SessionReaper, SessionRecoveryCoordinator, SonioxSttProvider, TELEPHONY_SAMPLE_RATE_HZ, TVIC_ERROR_CODES, TVIC_ERROR_CODE_ALIASES, TVIC_ERROR_MARKER, TVIC_ERROR_NAMES, TWILIO_MAX_AUDIO_EVENT_BYTES, TvicThrowableError, TwilioMediaStreamCallHandle, TwilioMediaStreamsProvider, VoiceRuntimeFinalizationError, WEB_CLIENT_AUDIO_ACK_RETENTION_MS, WEB_CLIENT_AUDIO_CLOSE_CODES, WEB_CLIENT_AUDIO_DEFAULTS, WebClientAudioCallHandle, WebClientAudioProvider, assertLeaseFence, assertLeaseTimestampMs, assertLeaseTtlMs, assertMemoryCapability, assertMemoryPolicySupported, assertPcm16leFormat, assertRecoveryPageSize, authError, base64ToBytes, bytesToBase64, cancelledError, canonicalizeTwilioData, computeTwilioSignature, connectionError, counterIdGenerator, createAssemblyAiSttProvider, createAudioNormalizer, createCartesiaSttProvider, createCartesiaTtsProvider, createDeepgramSttProvider, createDefaultIdGenerator, createElevenLabsSttProvider, createElevenLabsTtsHttpStreamProvider, createElevenLabsTtsProvider, createElevenLabsTtsRestProvider, createGroqChatLlmProvider, createInMemoryDurableRuntimeStore, createInMemoryMemory, createInMemorySessionStore, createInMemoryToolCallStore, createInMemoryTurnStore, createMediaEvent, createNodeMediaPlane, createOpenAiResponsesLlmProvider, createPostgresDurableRuntimeStore, createPostgresMemory, createPostgresRedisDurableRuntimeStore, createRedisDurableRuntimeStore, createRuntime, createSarvamSttProvider, createSarvamTtsHttpStreamProvider, createSarvamTtsProvider, createSarvamTtsRestProvider, createSonioxSttProvider, createSttSession, createSystemClock, createToolRegistry, createTtsFailoverProvider, createTwilioMediaStreamsProvider, createVoiceAgent, createWebClientAudioProvider, defineAgent, defineTool, deliverAssistantText, durationMsForPcm16le, evaluateProviderCompatibility, executeTool, formatMemoryContextAsSystemBlock, formatPreCallContextAsSystemBlock, frameCountForPcm16le, getSttRecoveryControl, idempotencyKeyFor, idempotencyRequestHashFor, internalError, interruptedError, isDtmfDigit, isIncrementalTextToSpeechProvider, isInputMediaEvent, isNormalizedError, isOutputMediaEvent, isProviderKind, isReconstructableAudioFormat, isSampleRateHz, isTerminalSession, isTerminalTurn, isTranscriptSegmentEvent, isTvicError, isTvicErrorName, isValidErrorCode, jsonSerializableNormalizedError, kindForMediaEvent, matchPath, mediaError, monotonicOffsetMs, mulawToPcm16le, normalizeLegacyError, normalizeUnknownError, normalizedError, normalizedErrorFromTvicError, nowTimestamp, pcm16leToMulaw, providerError, rateLimitError, requireProviderKind, resamplePcm16le, resolvePreCallContext, resolvePreCallMemory, runPostgresMemoryMigrations, runPostgresMigrations, safeLeaseExpiryAt, sameAudioFormat, shouldDeliverText, signVoiceSessionToken, signatureError, splitPcm16leFrames, stableStringify, supportsAudioFormat, supportsBatchModel, supportsLanguage, supportsModel, terminalSessionFromRequest, terminalSourceForRequest, terminalTurnFromRequest, timeoutError, toRuntimeSessionTrace, toTimestamp, toolError, toolInputError, tvicErrorFromJSON, unknownErrorMessage, validateJsonSchemaSubset, validationError, verifyTwilioSignature, verifyVoiceSessionToken, withSttReconnect };
4490
+ export type { ActiveSession, ActiveTurn, Agent, AgentAudioPolicy, AgentContextPolicy, AgentId, AgentMemoryPolicy, AgentProviders, AnyMediaEventInit, AssemblyAiProviderConfig, AssemblyAiSttProviderOptions, AssistantTextRecord, AudioFormat, AudioNormalizationMode, AudioNormalizer, AudioNormalizerOptions, AudioOutputDeliveryStatus, AudioPayload, BackoffStrategy, Brand, Call, CallControlCapability, CallDirection, CallHandle, CallId, CallSnapshot, CallStatus, CancelledSession, CancelledTurn, CartesiaGenerationConfig, CartesiaProviderConfig, CartesiaSttMode, CartesiaSttProviderConfig, CartesiaSttProviderOptions, CartesiaTtsProviderOptions, ChannelKind, ChannelLayout, CleanupErrorSummary, CleanupStage, Clock, CompletedSession, CompletedTurn, ConnectedCall, ConnectionObservabilityEvent, ConversationPolicyOptions, CounterIdGenerator, CreateVoiceAgentOptions, CreatedCall, CreatedSession, DeepgramProviderConfig, DeepgramSttProviderOptions, DefineAgentInput, DefineToolInput, DtmfDigit, DtmfReceivedEvent, DualProtocolResult, DurableErrorCode, DurableOutboxEvent, DurableRuntimeMetric, DurableRuntimePolicy, DurableRuntimeStore, DurableSessionTransaction, ElevenLabsBatchSttRequest, ElevenLabsBatchSttResult, ElevenLabsBatchTimestampGranularity, ElevenLabsDialogueInput, ElevenLabsDialogueProvider, ElevenLabsDialogueSynthesisRequest, ElevenLabsDialogueTurnOptions, ElevenLabsEntityDetection, ElevenLabsHttpTtsProviderOptions, ElevenLabsPronunciationDictionaryLocator, ElevenLabsSttCommitStrategy, ElevenLabsSttProviderConfig, ElevenLabsSttProviderOptions, ElevenLabsTextNormalization, ElevenLabsTtsHttpSynthesisRequest, ElevenLabsTtsProviderConfig, ElevenLabsTtsProviderOptions, ElevenLabsTtsSendTextOptions, EndSessionReason, EndSessionRequest, EndTurnRequest, EndedCall, ErrorCategory, ExecuteToolInput, FailedCall, FailedSession, FailedToolCall, FailedToolCallStatus, FailedTurn, GroqChatLlmProviderOptions, GroqProviderConfig, HealthCheckResult, HealthSnapshot, IdGenerator, IdempotencyPolicy, InMemoryDurableRuntimeStore, InMemoryDurableRuntimeStoreOptions, InMemoryMemoryOptions, InboundCallContext, InboundMediaEvent, IncrementalTextToSpeechProvider, InputAudioChunk, InputMediaEvent, InternalMediaEvent, InterruptRequestedEvent, InterruptionMode, InterruptionPolicy, JsonSchemaDocument, JsonValue, LLMProvider, LiveTerminalSource, LlmCompletion, LlmCompletionRequest, LlmInlineToolCall, LlmMessage, LlmMessageRole, LlmProviderConfig, LlmStreamEvent, LlmUsage, ManagedVoiceAgentSession, MediaAudioChunkEvent, MediaAudioCommittedEvent, MediaDirection, MediaErrorEvent, MediaEvent, MediaEventId, MediaEventKind, MediaEventType, MediaStreamEndedEvent, MediaStreamStartedEvent, MediaTransport, MediaTransportKind, Memory, MemoryCapabilities, MemoryEntry, MemoryEntryId, MemoryKind, MemoryPutOptions, MemoryQuery, MemoryRef, MemoryScope, NodeMediaPlaneConnection, NodeMediaPlaneConnectionErrorHandler, NodeMediaPlaneConnectionHandler, NodeMediaPlaneOptions, NodeMediaPlaneRequestHandler, NormalizedAudioEncoding, NormalizedError, OpenAiProviderConfig, OpenAiResponsesLlmProviderOptions, OrganizationId, OutboundCallRequest, OutputAudioChunk, OutputMediaEvent, PersonaConfig, PipelineVoiceLoopOptions, PipelineVoiceLoopResult, PostgresDurableStoreOptions, PostgresMemoryOptions, PostgresMigration, PostgresRedisDurableStoreOptions, PreCallContext, PreCallContextResolver, PreCallMemoryContext, PreCallMemoryResolver, Provider, ProviderAudioCapabilities, ProviderBatchCapabilities, ProviderCancellationCapabilities, ProviderCapabilities, ProviderCatalogEntry, ProviderClock, ProviderCompatibility, ProviderCompatibilityIssue, ProviderCompatibilityIssueCode, ProviderDataPolicy, ProviderEventId, ProviderForKind, ProviderKind, ProviderPlayoutCapabilities, ProviderRequirements, ProviderStability, ProviderStreamingCapabilities, ProviderToolCapabilities, ProviderTransport, QueuedToolCall, RecoveryPollResult, RedisClient, RedisMulti, RedisScanOptions, RedisSetResult, RedisStoreOptions, RequiredProviderCapabilities, RetryPolicy, RingingCall, RunningToolCall, Runtime, RuntimeOptions, RuntimeProvider, RuntimeServiceLifecycle, RuntimeSessionTrace, RuntimeTraceError, SampleRateHz, SarvamOutputMode, SarvamProviderConfig, SarvamSttProviderOptions, SarvamTtsHttpProviderOptions, SarvamTtsProviderConfig, SarvamTtsProviderOptions, SchemaValidationResult, Session, SessionAttachment, SessionAttachmentHealth, SessionCancellationReason, SessionEndEvent, SessionEndMemorySnapshot, SessionId, SessionLease, SessionLeaseStore, SessionMemoryFinalization, SessionMetricsRecorder, SessionReaperOptions, SessionRecoveryCandidate, SessionRecoveryCoordinatorOptions, SessionRuntimeMetadata, SessionSnapshot, SessionState, SessionStatus, SessionStore, SonioxProviderConfig, SonioxStructuredContext, SonioxSttProviderOptions, SpeechToTextProvider, SqlClient$1 as SqlClient, SqlPool$1 as SqlPool, SqlResult, StartAttachedSessionOptions, StartSessionOptions, StartTurnRequest, StartingSession, StoredSessionRecord, StoredToolCallRecord, StoredTurnRecord, StreamEndReason, SttBatchTimestampGranularity, SttBatchTranscription, SttBatchTranscriptionRequest, SttBatchWord, SttCommitMode, SttOpenRequest, SttProviderConfig, SttReconnectOptions, SttRecoveryControl, SttRecoveryState, SttSession, SttSessionInputOptions, SttSessionOptions, SttStream, SttTimestampOrigin, SucceededToolCall, TelephonyProvider, TelephonyProviderConfig, TerminalSession, TerminalSessionDraft, TerminalSessionStatus, TerminalSource, TerminalToolCall, TerminalTurn, TextDeliveryMode, TextOutputDeliveryStatus, TextToSpeechProvider, TimeoutAction, TimeoutPolicy, Timestamp, ToolCall, ToolCallId, ToolCallRuntimeMetadata, ToolCallStatus, ToolCallStore, ToolDefinition, ToolExecutionContext, ToolExecutor, ToolId, ToolIdempotencyClaim, ToolIdempotencyClaimResult, ToolIdempotencyLease, ToolIdempotencyLookupResult, ToolIdempotencyOutcome, ToolIdempotencyQuarantine, ToolIdempotencyQuarantineResult, ToolIdempotencyRecord, ToolIdempotencyRelease, ToolIdempotencyStatus, ToolIdempotencyStore, ToolLogger, ToolName, ToolRegistry, ToolTenant, TranscriptEndpointEvent, TranscriptEndpointReason, TranscriptEvent, TranscriptEventType, TranscriptSegmentEvent, TranscriptSegmentEventType, TranscriptSpeechStartedEvent, TransportAudioEncoding, TransportAudioFormat, TtsAlignmentEvent, TtsAlignmentUnit, TtsEvent, TtsFailoverContext, TtsFailoverPhase, TtsFailoverProviderOptions, TtsFlushAcknowledgement, TtsFlushCompletedEvent, TtsFlushId, TtsFlushResult, TtsProviderConfig, TtsSession, TtsSessionOpenRequest, TtsStream, TtsSynthesisRequest, Turn, TurnCancellationReason, TurnCommitRequestedEvent, TurnDetectionMode, TurnId, TurnInput, TurnLatency, TurnLatencyRecord, TurnOutput, TurnOutputDelivery, TurnRuntimeMetadata, TurnStatus, TurnStore, TvicErrorName, TwilioFlatParams, TwilioMediaStreamCallHandleOptions, TwilioMediaStreamSocket, TwilioParamValue, TwilioParams, UpgradeAuthorization, UserId, VerifyTwilioOptions, VerifyVoiceSessionTokenOptions, VoiceAgent, VoiceAgentCallHandleContext, VoiceAgentCallHandleFactory, VoiceAgentModels, VoiceAgentProviderNames, VoiceAgentProviders, VoiceAgentRun, VoiceAgentRunOptions, VoiceAgentSession, VoiceAgentWithSessionLifecycle, VoiceEvent, VoiceRuntimeFailureMetadata, WebClientAudioCallHandleOptions, WebClientAudioConnectionEvent, WebClientAudioProviderOptions, WebClientAudioSocket, WorkflowId };