@ai-sdk/provider 4.0.14 → 4.0.15

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @ai-sdk/provider
2
2
 
3
+ ## 4.0.15
4
+
5
+ ### Patch Changes
6
+
7
+ - 5c0054d: Add optional browser-direct WebRTC for experimental client-delegated Live conversations alongside the existing WebSocket path. Exchange SDP through an application endpoint with `api.session`, configure server-owned data-channel permissions, and preserve committed React session ownership. Capture follows the selected sender track, borrowed tracks remain caller-owned, and disconnect recovery and finalization stay bounded. Applications continue to handle client delegation and submit context; Live session updates and Responses delegation remain unsupported.
8
+
9
+ Serialize microphone sender changes and close the peer if detachment fails, without stopping borrowed tracks. Validate nonempty SDP setup answers with a bounded response body, and document the same-origin broker authentication contract.
10
+
11
+ - 39535af: Add experimental OpenAI Live provider support through the unified `openai.experimental_realtime` factory for server WebSocket sessions with client delegation. Applications own their agents and tools, receive continuous audio/transcript events and delegation metadata, and return context through validated channels. Support immutable startup options, microphone mute controls, graceful session close, and cumulative voice usage. Responses delegation and Live session updates reject before sending.
12
+
13
+ Route known Live model IDs to Live, allow an OpenAI-specific `api` override for early-access models, and preserve legacy Realtime defaults for unknown IDs. Token minting follows the same selection rules and rejects Live before requesting unsupported credentials. Extend the realtime v4 specification with optional server WebSocket configuration, per-connection raw-event parsers, and model-wide startup/finalization capabilities. This provider layer supplies connection settings and protocol mapping for server adapters; browser lifecycle and UI integration belong to the core runtime and framework hooks.
14
+
15
+ Preserve Realtime client event IDs for session updates and audio appends, and correlate server errors with the originating client event.
16
+
3
17
  ## 4.0.14
4
18
 
5
19
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -6997,12 +6997,33 @@ type RealtimeModelV4FunctionCallOutput = {
6997
6997
  type RealtimeModelV4ClientEvent = {
6998
6998
  type: 'session-update';
6999
6999
  config: RealtimeModelV4SessionConfig;
7000
+ eventId?: string;
7001
+ } | {
7002
+ type: 'session-start';
7003
+ config: RealtimeModelV4SessionConfig;
7004
+ eventId?: string;
7005
+ } | {
7006
+ type: 'session-close';
7007
+ eventId?: string;
7008
+ } | {
7009
+ type: 'input-audio-mute';
7010
+ eventId?: string;
7011
+ } | {
7012
+ type: 'input-audio-unmute';
7013
+ eventId?: string;
7014
+ } | {
7015
+ type: 'context-append';
7016
+ content: string;
7017
+ delegationId: string | null;
7018
+ eventId?: string;
7019
+ providerOptions?: SharedV4ProviderOptions;
7000
7020
  } | {
7001
7021
  type: 'input-audio-append';
7002
7022
  /**
7003
7023
  * Base64-encoded audio chunk to append to the input buffer.
7004
7024
  */
7005
7025
  audio: string;
7026
+ eventId?: string;
7006
7027
  } | {
7007
7028
  type: 'input-audio-commit';
7008
7029
  } | {
@@ -7043,6 +7064,51 @@ type RealtimeModelV4ClientEvent = {
7043
7064
  * event data for debugging and provider-specific access.
7044
7065
  */
7045
7066
  type RealtimeModelV4ServerEvent = {
7067
+ type: 'session-started';
7068
+ sessionId: string;
7069
+ delegationMode?: 'client' | 'provider';
7070
+ raw: unknown;
7071
+ } | {
7072
+ type: 'session-closed';
7073
+ sessionId?: string;
7074
+ usage: {
7075
+ seconds: number;
7076
+ };
7077
+ reason: string;
7078
+ raw: unknown;
7079
+ } | {
7080
+ type: 'session-usage';
7081
+ /** Cumulative duration snapshot, not an increment. */
7082
+ usage: {
7083
+ seconds: number;
7084
+ };
7085
+ contextWindowUsageRatio?: number;
7086
+ raw: unknown;
7087
+ } | {
7088
+ type: 'audio-chunk';
7089
+ delta: string;
7090
+ raw: unknown;
7091
+ } | {
7092
+ type: 'transcript-fragment';
7093
+ speaker: 'user' | 'assistant';
7094
+ delta: string;
7095
+ startMs: number;
7096
+ endMs: number;
7097
+ raw: unknown;
7098
+ } | {
7099
+ type: 'delegation-created';
7100
+ delegationId: string;
7101
+ target?: 'client' | 'provider';
7102
+ offsetMs?: number;
7103
+ responseId?: string;
7104
+ raw: unknown;
7105
+ } | {
7106
+ type: 'command-acknowledged';
7107
+ /** Provider-native command name that was acknowledged. */
7108
+ command: string;
7109
+ clientEventId?: string;
7110
+ raw: unknown;
7111
+ } | {
7046
7112
  type: 'session-created';
7047
7113
  sessionId?: string;
7048
7114
  raw: unknown;
@@ -7173,6 +7239,7 @@ type RealtimeModelV4ServerEvent = {
7173
7239
  type: 'error';
7174
7240
  message: string;
7175
7241
  code?: string;
7242
+ clientEventId?: string;
7176
7243
  raw: unknown;
7177
7244
  } | {
7178
7245
  type: 'custom';
@@ -7203,6 +7270,38 @@ type RealtimeModelV4 = {
7203
7270
  * Provider-specific model ID (e.g. 'gpt-4o-realtime', 'grok-3').
7204
7271
  */
7205
7272
  readonly modelId: string;
7273
+ /** Conversation semantics and supported transports, when declared. */
7274
+ readonly capabilities?: {
7275
+ conversation: 'continuous' | 'turn-based';
7276
+ transports: readonly ('websocket' | 'webrtc')[];
7277
+ /** Omission preserves the legacy client-secret WebSocket connection. */
7278
+ connections?: readonly ('client-secret-websocket' | 'server-websocket' | 'webrtc')[];
7279
+ /** Omission preserves session-update startup. WebRTC setup may start the session. */
7280
+ startup?: 'session-start' | 'session-update';
7281
+ /** Omission preserves transport-close finalization. */
7282
+ finalization?: 'session-close' | 'transport-close';
7283
+ };
7284
+ /** Server-only connection settings. Headers can contain long-lived credentials. */
7285
+ getServerWebSocketConfig?(): {
7286
+ url: string;
7287
+ headers: Record<string, string>;
7288
+ } | PromiseLike<{
7289
+ url: string;
7290
+ headers: Record<string, string>;
7291
+ }>;
7292
+ /** Provider-specific setup for the WebRTC event channel. */
7293
+ getWebRTCConfig?(): {
7294
+ dataChannelLabel: string;
7295
+ };
7296
+ /** Server-side SDP exchange. Return only the answer and session ID to the client. */
7297
+ doCreateWebRTCSession?(options: {
7298
+ sdp: string;
7299
+ sessionConfig?: RealtimeModelV4SessionConfig;
7300
+ abortSignal?: AbortSignal;
7301
+ }): PromiseLike<{
7302
+ sessionId: string;
7303
+ sdp: string;
7304
+ }>;
7206
7305
  /**
7207
7306
  * Server-side: Creates an ephemeral client secret for authenticating
7208
7307
  * browser-side WebSocket connections. The secret is short-lived and
@@ -7210,13 +7309,13 @@ type RealtimeModelV4 = {
7210
7309
  *
7211
7310
  * Naming: "do" prefix to prevent accidental direct usage by the user.
7212
7311
  */
7213
- doCreateClientSecret(options: RealtimeModelV4ClientSecretOptions): PromiseLike<RealtimeModelV4ClientSecretResult>;
7312
+ doCreateClientSecret?(options: RealtimeModelV4ClientSecretOptions): PromiseLike<RealtimeModelV4ClientSecretResult>;
7214
7313
  /**
7215
7314
  * Browser-side: Returns the WebSocket URL and subprotocols to use
7216
7315
  * when connecting. Each provider has its own authentication mechanism
7217
7316
  * (e.g. OpenAI uses subprotocol headers, xAI may use query params).
7218
7317
  */
7219
- getWebSocketConfig(options: {
7318
+ getWebSocketConfig?(options: {
7220
7319
  token: string;
7221
7320
  url: string;
7222
7321
  }): {
@@ -7233,6 +7332,8 @@ type RealtimeModelV4 = {
7233
7332
  * text, and turn-complete data in one message).
7234
7333
  */
7235
7334
  parseServerEvent(raw: unknown): RealtimeModelV4ServerEvent | RealtimeModelV4ServerEvent[];
7335
+ /** Create a raw-event parser per connection and discard it on disconnect. */
7336
+ createServerEventParser?(): (raw: unknown) => RealtimeModelV4ServerEvent | RealtimeModelV4ServerEvent[];
7236
7337
  /**
7237
7338
  * Browser-side: Serializes a normalized client event into the
7238
7339
  * provider's native JSON format for sending over the WebSocket.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/provider",
3
- "version": "4.0.14",
3
+ "version": "4.0.15",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -1,3 +1,4 @@
1
+ import type { SharedV4ProviderOptions } from '../../shared/v4/shared-v4-provider-options';
1
2
  import type { RealtimeModelV4ConversationItem } from './realtime-model-v4-conversation-item';
2
3
  import type { RealtimeModelV4SessionConfig } from './realtime-model-v4-session-config';
3
4
 
@@ -12,6 +13,31 @@ export type RealtimeModelV4ClientEvent =
12
13
  | {
13
14
  type: 'session-update';
14
15
  config: RealtimeModelV4SessionConfig;
16
+ eventId?: string;
17
+ }
18
+ | {
19
+ type: 'session-start';
20
+ config: RealtimeModelV4SessionConfig;
21
+ eventId?: string;
22
+ }
23
+ | {
24
+ type: 'session-close';
25
+ eventId?: string;
26
+ }
27
+ | {
28
+ type: 'input-audio-mute';
29
+ eventId?: string;
30
+ }
31
+ | {
32
+ type: 'input-audio-unmute';
33
+ eventId?: string;
34
+ }
35
+ | {
36
+ type: 'context-append';
37
+ content: string;
38
+ delegationId: string | null;
39
+ eventId?: string;
40
+ providerOptions?: SharedV4ProviderOptions;
15
41
  }
16
42
 
17
43
  // ── Input audio buffer ─────────────────────────────────────────────
@@ -22,6 +48,7 @@ export type RealtimeModelV4ClientEvent =
22
48
  * Base64-encoded audio chunk to append to the input buffer.
23
49
  */
24
50
  audio: string;
51
+ eventId?: string;
25
52
  }
26
53
  | {
27
54
  type: 'input-audio-commit';
@@ -6,8 +6,55 @@
6
6
  * event data for debugging and provider-specific access.
7
7
  */
8
8
  export type RealtimeModelV4ServerEvent =
9
+ | {
10
+ type: 'session-started';
11
+ sessionId: string;
12
+ delegationMode?: 'client' | 'provider';
13
+ raw: unknown;
14
+ }
15
+ | {
16
+ type: 'session-closed';
17
+ sessionId?: string;
18
+ usage: { seconds: number };
19
+ reason: string;
20
+ raw: unknown;
21
+ }
22
+ | {
23
+ type: 'session-usage';
24
+ /** Cumulative duration snapshot, not an increment. */
25
+ usage: { seconds: number };
26
+ contextWindowUsageRatio?: number;
27
+ raw: unknown;
28
+ }
29
+ | {
30
+ type: 'audio-chunk';
31
+ delta: string;
32
+ raw: unknown;
33
+ }
34
+ | {
35
+ type: 'transcript-fragment';
36
+ speaker: 'user' | 'assistant';
37
+ delta: string;
38
+ startMs: number;
39
+ endMs: number;
40
+ raw: unknown;
41
+ }
42
+ | {
43
+ type: 'delegation-created';
44
+ delegationId: string;
45
+ target?: 'client' | 'provider';
46
+ offsetMs?: number;
47
+ responseId?: string;
48
+ raw: unknown;
49
+ }
50
+ | {
51
+ type: 'command-acknowledged';
52
+ /** Provider-native command name that was acknowledged. */
53
+ command: string;
54
+ clientEventId?: string;
55
+ raw: unknown;
56
+ }
9
57
  // ── Session lifecycle ──────────────────────────────────────────────
10
-
11
58
  | {
12
59
  type: 'session-created';
13
60
  sessionId?: string;
@@ -184,6 +231,7 @@ export type RealtimeModelV4ServerEvent =
184
231
  type: 'error';
185
232
  message: string;
186
233
  code?: string;
234
+ clientEventId?: string;
187
235
  raw: unknown;
188
236
  }
189
237
 
@@ -29,6 +29,37 @@ export type RealtimeModelV4 = {
29
29
  */
30
30
  readonly modelId: string;
31
31
 
32
+ /** Conversation semantics and supported transports, when declared. */
33
+ readonly capabilities?: {
34
+ conversation: 'continuous' | 'turn-based';
35
+ transports: readonly ('websocket' | 'webrtc')[];
36
+ /** Omission preserves the legacy client-secret WebSocket connection. */
37
+ connections?: readonly (
38
+ | 'client-secret-websocket'
39
+ | 'server-websocket'
40
+ | 'webrtc'
41
+ )[];
42
+ /** Omission preserves session-update startup. WebRTC setup may start the session. */
43
+ startup?: 'session-start' | 'session-update';
44
+ /** Omission preserves transport-close finalization. */
45
+ finalization?: 'session-close' | 'transport-close';
46
+ };
47
+
48
+ /** Server-only connection settings. Headers can contain long-lived credentials. */
49
+ getServerWebSocketConfig?():
50
+ | { url: string; headers: Record<string, string> }
51
+ | PromiseLike<{ url: string; headers: Record<string, string> }>;
52
+
53
+ /** Provider-specific setup for the WebRTC event channel. */
54
+ getWebRTCConfig?(): { dataChannelLabel: string };
55
+
56
+ /** Server-side SDP exchange. Return only the answer and session ID to the client. */
57
+ doCreateWebRTCSession?(options: {
58
+ sdp: string;
59
+ sessionConfig?: RealtimeModelV4SessionConfig;
60
+ abortSignal?: AbortSignal;
61
+ }): PromiseLike<{ sessionId: string; sdp: string }>;
62
+
32
63
  /**
33
64
  * Server-side: Creates an ephemeral client secret for authenticating
34
65
  * browser-side WebSocket connections. The secret is short-lived and
@@ -36,7 +67,7 @@ export type RealtimeModelV4 = {
36
67
  *
37
68
  * Naming: "do" prefix to prevent accidental direct usage by the user.
38
69
  */
39
- doCreateClientSecret(
70
+ doCreateClientSecret?(
40
71
  options: RealtimeModelV4ClientSecretOptions,
41
72
  ): PromiseLike<RealtimeModelV4ClientSecretResult>;
42
73
 
@@ -45,7 +76,7 @@ export type RealtimeModelV4 = {
45
76
  * when connecting. Each provider has its own authentication mechanism
46
77
  * (e.g. OpenAI uses subprotocol headers, xAI may use query params).
47
78
  */
48
- getWebSocketConfig(options: { token: string; url: string }): {
79
+ getWebSocketConfig?(options: { token: string; url: string }): {
49
80
  url: string;
50
81
  protocols?: string[];
51
82
  };
@@ -63,6 +94,11 @@ export type RealtimeModelV4 = {
63
94
  raw: unknown,
64
95
  ): RealtimeModelV4ServerEvent | RealtimeModelV4ServerEvent[];
65
96
 
97
+ /** Create a raw-event parser per connection and discard it on disconnect. */
98
+ createServerEventParser?(): (
99
+ raw: unknown,
100
+ ) => RealtimeModelV4ServerEvent | RealtimeModelV4ServerEvent[];
101
+
66
102
  /**
67
103
  * Browser-side: Serializes a normalized client event into the
68
104
  * provider's native JSON format for sending over the WebSocket.