@depup/openai 7.34.0-depup.0 → 7.36.0-depup.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.
Files changed (210) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +2 -2
  3. package/changes.json +1 -1
  4. package/client.d.mts +2 -2
  5. package/client.d.mts.map +1 -1
  6. package/client.d.ts +2 -2
  7. package/client.d.ts.map +1 -1
  8. package/client.js.map +1 -1
  9. package/client.mjs.map +1 -1
  10. package/internal/responses-ws-credentials.d.mts +4 -21
  11. package/internal/responses-ws-credentials.d.mts.map +1 -1
  12. package/internal/responses-ws-credentials.d.ts +4 -21
  13. package/internal/responses-ws-credentials.d.ts.map +1 -1
  14. package/internal/responses-ws-credentials.js +4 -100
  15. package/internal/responses-ws-credentials.js.map +1 -1
  16. package/internal/responses-ws-credentials.mjs +4 -100
  17. package/internal/responses-ws-credentials.mjs.map +1 -1
  18. package/internal/ws-connection-controller.d.mts +95 -0
  19. package/internal/ws-connection-controller.d.mts.map +1 -0
  20. package/internal/ws-connection-controller.d.ts +95 -0
  21. package/internal/ws-connection-controller.d.ts.map +1 -0
  22. package/internal/ws-connection-controller.js +457 -0
  23. package/internal/ws-connection-controller.js.map +1 -0
  24. package/internal/ws-connection-controller.mjs +453 -0
  25. package/internal/ws-connection-controller.mjs.map +1 -0
  26. package/internal/ws-connection.d.mts +18 -0
  27. package/internal/ws-connection.d.mts.map +1 -0
  28. package/internal/ws-connection.d.ts +18 -0
  29. package/internal/ws-connection.d.ts.map +1 -0
  30. package/internal/ws-connection.js +94 -0
  31. package/internal/ws-connection.js.map +1 -0
  32. package/internal/ws-connection.mjs +88 -0
  33. package/internal/ws-connection.mjs.map +1 -0
  34. package/internal/ws-credentials.d.mts +25 -0
  35. package/internal/ws-credentials.d.mts.map +1 -0
  36. package/internal/ws-credentials.d.ts +25 -0
  37. package/internal/ws-credentials.d.ts.map +1 -0
  38. package/internal/ws-credentials.js +109 -0
  39. package/internal/ws-credentials.js.map +1 -0
  40. package/internal/ws-credentials.mjs +105 -0
  41. package/internal/ws-credentials.mjs.map +1 -0
  42. package/lib/live/webrtc.d.mts +5 -1
  43. package/lib/live/webrtc.d.mts.map +1 -1
  44. package/lib/live/webrtc.d.ts +5 -1
  45. package/lib/live/webrtc.d.ts.map +1 -1
  46. package/lib/live/webrtc.js.map +1 -1
  47. package/lib/live/webrtc.mjs.map +1 -1
  48. package/package.json +3 -3
  49. package/resources/admin/organization/projects/api-keys.d.mts +28 -5
  50. package/resources/admin/organization/projects/api-keys.d.mts.map +1 -1
  51. package/resources/admin/organization/projects/api-keys.d.ts +28 -5
  52. package/resources/admin/organization/projects/api-keys.d.ts.map +1 -1
  53. package/resources/admin/organization/projects/api-keys.js +18 -3
  54. package/resources/admin/organization/projects/api-keys.js.map +1 -1
  55. package/resources/admin/organization/projects/api-keys.mjs +18 -3
  56. package/resources/admin/organization/projects/api-keys.mjs.map +1 -1
  57. package/resources/audio/speech.d.mts +2 -1
  58. package/resources/audio/speech.d.mts.map +1 -1
  59. package/resources/audio/speech.d.ts +2 -1
  60. package/resources/audio/speech.d.ts.map +1 -1
  61. package/resources/audio/voices.d.mts +47 -12
  62. package/resources/audio/voices.d.mts.map +1 -1
  63. package/resources/audio/voices.d.ts +47 -12
  64. package/resources/audio/voices.d.ts.map +1 -1
  65. package/resources/audio/voices.js +9 -9
  66. package/resources/audio/voices.mjs +9 -9
  67. package/resources/beta/realtime/realtime.d.mts +4 -0
  68. package/resources/beta/realtime/realtime.d.mts.map +1 -1
  69. package/resources/beta/realtime/realtime.d.ts +4 -0
  70. package/resources/beta/realtime/realtime.d.ts.map +1 -1
  71. package/resources/beta/realtime/realtime.js.map +1 -1
  72. package/resources/beta/realtime/realtime.mjs.map +1 -1
  73. package/resources/beta/responses/responses.d.mts +8 -0
  74. package/resources/beta/responses/responses.d.mts.map +1 -1
  75. package/resources/beta/responses/responses.d.ts +8 -0
  76. package/resources/beta/responses/responses.d.ts.map +1 -1
  77. package/resources/beta/responses/responses.js.map +1 -1
  78. package/resources/beta/responses/responses.mjs.map +1 -1
  79. package/resources/beta/responses/ws-base.d.mts +2 -24
  80. package/resources/beta/responses/ws-base.d.mts.map +1 -1
  81. package/resources/beta/responses/ws-base.d.ts +2 -24
  82. package/resources/beta/responses/ws-base.d.ts.map +1 -1
  83. package/resources/beta/responses/ws-base.js +93 -519
  84. package/resources/beta/responses/ws-base.js.map +1 -1
  85. package/resources/beta/responses/ws-base.mjs +94 -520
  86. package/resources/beta/responses/ws-base.mjs.map +1 -1
  87. package/resources/chat/completions/completions.d.mts +1 -1
  88. package/resources/chat/completions/completions.d.ts +1 -1
  89. package/resources/decisions.d.mts +68 -1
  90. package/resources/decisions.d.mts.map +1 -1
  91. package/resources/decisions.d.ts +68 -1
  92. package/resources/decisions.d.ts.map +1 -1
  93. package/resources/images.d.mts +42 -4
  94. package/resources/images.d.mts.map +1 -1
  95. package/resources/images.d.ts +42 -4
  96. package/resources/images.d.ts.map +1 -1
  97. package/resources/images.js +8 -2
  98. package/resources/images.js.map +1 -1
  99. package/resources/images.mjs +8 -2
  100. package/resources/images.mjs.map +1 -1
  101. package/resources/index.d.mts +1 -1
  102. package/resources/index.d.mts.map +1 -1
  103. package/resources/index.d.ts +1 -1
  104. package/resources/index.d.ts.map +1 -1
  105. package/resources/index.js.map +1 -1
  106. package/resources/index.mjs.map +1 -1
  107. package/resources/live/forks/forks.d.mts +2 -2
  108. package/resources/live/forks/forks.d.mts.map +1 -1
  109. package/resources/live/forks/forks.d.ts +2 -2
  110. package/resources/live/forks/forks.d.ts.map +1 -1
  111. package/resources/live/forks/ws-base.d.mts +2 -23
  112. package/resources/live/forks/ws-base.d.mts.map +1 -1
  113. package/resources/live/forks/ws-base.d.ts +2 -23
  114. package/resources/live/forks/ws-base.d.ts.map +1 -1
  115. package/resources/live/forks/ws-base.js +84 -485
  116. package/resources/live/forks/ws-base.js.map +1 -1
  117. package/resources/live/forks/ws-base.mjs +83 -484
  118. package/resources/live/forks/ws-base.mjs.map +1 -1
  119. package/resources/live/live.d.mts +523 -29
  120. package/resources/live/live.d.mts.map +1 -1
  121. package/resources/live/live.d.ts +523 -29
  122. package/resources/live/live.d.ts.map +1 -1
  123. package/resources/live/live.js.map +1 -1
  124. package/resources/live/live.mjs.map +1 -1
  125. package/resources/live/sessions.d.mts +16 -4
  126. package/resources/live/sessions.d.mts.map +1 -1
  127. package/resources/live/sessions.d.ts +16 -4
  128. package/resources/live/sessions.d.ts.map +1 -1
  129. package/resources/live/sideband/sideband.d.mts +4 -4
  130. package/resources/live/sideband/sideband.d.mts.map +1 -1
  131. package/resources/live/sideband/sideband.d.ts +4 -4
  132. package/resources/live/sideband/sideband.d.ts.map +1 -1
  133. package/resources/live/sideband/ws-base.d.mts +2 -23
  134. package/resources/live/sideband/ws-base.d.mts.map +1 -1
  135. package/resources/live/sideband/ws-base.d.ts +2 -23
  136. package/resources/live/sideband/ws-base.d.ts.map +1 -1
  137. package/resources/live/sideband/ws-base.js +84 -485
  138. package/resources/live/sideband/ws-base.js.map +1 -1
  139. package/resources/live/sideband/ws-base.mjs +83 -484
  140. package/resources/live/sideband/ws-base.mjs.map +1 -1
  141. package/resources/live/ws-base.d.mts +2 -23
  142. package/resources/live/ws-base.d.mts.map +1 -1
  143. package/resources/live/ws-base.d.ts +2 -23
  144. package/resources/live/ws-base.d.ts.map +1 -1
  145. package/resources/live/ws-base.js +84 -485
  146. package/resources/live/ws-base.js.map +1 -1
  147. package/resources/live/ws-base.mjs +83 -484
  148. package/resources/live/ws-base.mjs.map +1 -1
  149. package/resources/realtime/realtime.d.mts +8 -2
  150. package/resources/realtime/realtime.d.mts.map +1 -1
  151. package/resources/realtime/realtime.d.ts +8 -2
  152. package/resources/realtime/realtime.d.ts.map +1 -1
  153. package/resources/realtime/realtime.js.map +1 -1
  154. package/resources/realtime/realtime.mjs.map +1 -1
  155. package/resources/responses/responses.d.mts +8 -0
  156. package/resources/responses/responses.d.mts.map +1 -1
  157. package/resources/responses/responses.d.ts +8 -0
  158. package/resources/responses/responses.d.ts.map +1 -1
  159. package/resources/responses/responses.js.map +1 -1
  160. package/resources/responses/responses.mjs.map +1 -1
  161. package/resources/responses/ws-base.d.mts +2 -24
  162. package/resources/responses/ws-base.d.mts.map +1 -1
  163. package/resources/responses/ws-base.d.ts +2 -24
  164. package/resources/responses/ws-base.d.ts.map +1 -1
  165. package/resources/responses/ws-base.js +93 -519
  166. package/resources/responses/ws-base.js.map +1 -1
  167. package/resources/responses/ws-base.mjs +94 -520
  168. package/resources/responses/ws-base.mjs.map +1 -1
  169. package/resources/shared.d.mts +7 -0
  170. package/resources/shared.d.mts.map +1 -1
  171. package/resources/shared.d.ts +7 -0
  172. package/resources/shared.d.ts.map +1 -1
  173. package/resources/videos.d.mts +8 -0
  174. package/resources/videos.d.mts.map +1 -1
  175. package/resources/videos.d.ts +8 -0
  176. package/resources/videos.d.ts.map +1 -1
  177. package/src/client.ts +2 -0
  178. package/src/internal/responses-ws-credentials.ts +5 -157
  179. package/src/internal/ws-connection-controller.ts +632 -0
  180. package/src/internal/ws-connection.ts +116 -0
  181. package/src/internal/ws-credentials.ts +165 -0
  182. package/src/lib/live/webrtc.ts +4 -1
  183. package/src/resources/admin/organization/projects/api-keys.ts +29 -5
  184. package/src/resources/audio/speech.ts +2 -1
  185. package/src/resources/audio/voices.ts +53 -12
  186. package/src/resources/beta/realtime/realtime.ts +5 -0
  187. package/src/resources/beta/responses/responses.ts +10 -0
  188. package/src/resources/beta/responses/ws-base.ts +106 -604
  189. package/src/resources/chat/completions/completions.ts +1 -1
  190. package/src/resources/decisions.ts +75 -0
  191. package/src/resources/images.ts +57 -6
  192. package/src/resources/index.ts +1 -0
  193. package/src/resources/live/api.md +12 -0
  194. package/src/resources/live/forks/forks.ts +9 -0
  195. package/src/resources/live/forks/ws-base.ts +98 -558
  196. package/src/resources/live/live.ts +668 -26
  197. package/src/resources/live/sessions.ts +19 -4
  198. package/src/resources/live/sideband/sideband.ts +11 -2
  199. package/src/resources/live/sideband/ws-base.ts +98 -562
  200. package/src/resources/live/ws-base.ts +98 -558
  201. package/src/resources/realtime/realtime.ts +9 -2
  202. package/src/resources/responses/responses.ts +10 -0
  203. package/src/resources/responses/ws-base.ts +106 -600
  204. package/src/resources/shared.ts +7 -0
  205. package/src/resources/videos.ts +10 -0
  206. package/src/version.ts +1 -1
  207. package/version.d.mts +1 -1
  208. package/version.d.ts +1 -1
  209. package/version.js +1 -1
  210. package/version.mjs +1 -1
@@ -0,0 +1,116 @@
1
+ import { OpenAIError } from '../core/error';
2
+ import { ReadyState } from './ws-adapter';
3
+ import type { WebSocketLike } from './ws-adapter';
4
+ import { flattenRawData } from './ws';
5
+ import type { RawWebSocketData, SendQueue } from './ws';
6
+
7
+ // Read the public socket on each access; callers may replace it through an accessor.
8
+ interface SocketOwner {
9
+ socket: WebSocketLike;
10
+ }
11
+ type OnError = (message: string, cause?: unknown) => void;
12
+
13
+ /** Sends or queues an application event using the existing connection state. */
14
+ export function sendWebSocketEvent<T>(
15
+ owner: SocketOwner,
16
+ event: T,
17
+ queue: SendQueue<T>,
18
+ isReconnecting: () => boolean,
19
+ onError: OnError,
20
+ ): void {
21
+ if (!owner.socket) {
22
+ throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
23
+ }
24
+
25
+ if (isReconnecting() || owner.socket.readyState === ReadyState.CONNECTING) {
26
+ if (!queue.enqueue(event)) {
27
+ onError('send queue is full, message discarded');
28
+ }
29
+ return;
30
+ }
31
+ if (owner.socket.readyState !== ReadyState.OPEN) {
32
+ onError('cannot send on a closed WebSocket');
33
+ return;
34
+ }
35
+ try {
36
+ owner.socket.send(JSON.stringify(event));
37
+ } catch (error) {
38
+ onError('could not send data', error);
39
+ }
40
+ }
41
+
42
+ /** Sends or snapshots a raw frame using the same admission rules as application events. */
43
+ export function sendRawWebSocketData<T>(
44
+ owner: SocketOwner,
45
+ data: RawWebSocketData,
46
+ queue: SendQueue<T>,
47
+ isReconnecting: () => boolean,
48
+ onError: OnError,
49
+ ): void {
50
+ if (!owner.socket) {
51
+ throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
52
+ }
53
+
54
+ if (isReconnecting() || owner.socket.readyState === ReadyState.CONNECTING) {
55
+ if (!queue.enqueueRaw(data)) {
56
+ onError('send queue is full, message discarded');
57
+ }
58
+ return;
59
+ }
60
+ if (owner.socket.readyState !== ReadyState.OPEN) {
61
+ onError('cannot send on a closed WebSocket');
62
+ return;
63
+ }
64
+ try {
65
+ owner.socket.send(flattenRawData(data));
66
+ } catch (error) {
67
+ onError('could not send data', error);
68
+ }
69
+ }
70
+
71
+ /** Flushes queued frames with the caller's existing failed-send policy. */
72
+ export function flushWebSocketSendQueue<T>(
73
+ owner: SocketOwner,
74
+ queue: SendQueue<T>,
75
+ onError: OnError,
76
+ options?: { requeueFailed?: boolean },
77
+ ): void {
78
+ if (!owner.socket) {
79
+ throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
80
+ }
81
+
82
+ try {
83
+ queue.flush((data) => owner.socket.send(flattenRawData(data)), options);
84
+ } catch (error) {
85
+ onError('could not send queued data', error);
86
+ }
87
+ }
88
+
89
+ /** Resolves when the socket opens, or rejects if it errors or closes first. */
90
+ export function waitForWebSocketOpen(socket: WebSocketLike): Promise<void> {
91
+ // oxlint-disable-next-line promise/avoid-new -- Convert the existing socket event callbacks into the connection attempt's promise.
92
+ return new Promise<void>((resolve, reject) => {
93
+ /* oxlint-disable eslint/no-use-before-define -- All mutually dependent callbacks are initialized before socket listeners are registered. */
94
+ const cleanup = () => {
95
+ socket.off('open', onOpen);
96
+ socket.off('error', onError);
97
+ socket.off('close', onFail);
98
+ };
99
+ /* oxlint-enable eslint/no-use-before-define */
100
+ const onOpen = () => {
101
+ cleanup();
102
+ resolve();
103
+ };
104
+ const onError = (error: Error) => {
105
+ cleanup();
106
+ reject(error);
107
+ };
108
+ const onFail = () => {
109
+ cleanup();
110
+ reject(new Error('socket closed before open'));
111
+ };
112
+ socket.once('open', onOpen);
113
+ socket.once('error', onError);
114
+ socket.once('close', onFail);
115
+ });
116
+ }
@@ -0,0 +1,165 @@
1
+ import { OpenAIError } from '../core/error';
2
+ import type { OpenAI } from '../client';
3
+ import { resolveRealtimeAPIKey } from './realtime-credentials';
4
+ import {
5
+ buildWebSocketOptions,
6
+ mergeWebSocketAuthHeaders,
7
+ snapshotWebSocketCredentials,
8
+ WEBSOCKET_METADATA_HEADERS,
9
+ } from './ws';
10
+ import type { CredentialedWebSocketOptions } from './ws';
11
+
12
+ /**
13
+ * Keep caller credential admission distinct from the hook's final provider-key transform.
14
+ * The latter reuses captured base headers so no caller getters are reread after the refresh.
15
+ */
16
+ function buildCredentialedWebSocketOptions<Options extends CredentialedWebSocketOptions>(
17
+ client: OpenAI,
18
+ authHeaders: Record<string, string>,
19
+ options: Options | null | undefined,
20
+ prepared?: {
21
+ options: ReturnType<typeof buildWebSocketOptions>;
22
+ removedHeaders: Set<string>;
23
+ apiKey?: string | null | undefined;
24
+ },
25
+ ) {
26
+ if (prepared) {
27
+ return prepared.apiKey === undefined
28
+ ? mergeWebSocketAuthHeaders(prepared.options, authHeaders, prepared.removedHeaders)
29
+ : buildWebSocketOptions(client, authHeaders, prepared.options, prepared.removedHeaders, true);
30
+ }
31
+ if (!client._hasApiKeyProvider()) {
32
+ return buildWebSocketOptions(client, authHeaders, options);
33
+ }
34
+ const removedHeaders = new Set<string>();
35
+ const provided = buildWebSocketOptions(client, {}, options, removedHeaders);
36
+ return snapshotWebSocketCredentials(provided, WEBSOCKET_METADATA_HEADERS)
37
+ ? provided
38
+ : buildWebSocketOptions(client, authHeaders, provided, removedHeaders, true);
39
+ }
40
+
41
+ /**
42
+ * Classify reconnect credentials without treating the previous SDK key as a caller override.
43
+ * Capture routing and caller options before any asynchronous key refresh.
44
+ */
45
+ function prepareWebSocketReconnect<Options extends CredentialedWebSocketOptions>(
46
+ client: OpenAI,
47
+ socketOptions: Options | null | undefined,
48
+ initialAuthUsedAPIKey: boolean,
49
+ ) {
50
+ const removedHeaders = new Set<string>();
51
+ const options = buildWebSocketOptions(client, {}, socketOptions, removedHeaders);
52
+ let authentication: 'provided' | 'cached' | 'refresh';
53
+ if (snapshotWebSocketCredentials(options, WEBSOCKET_METADATA_HEADERS)) {
54
+ authentication = 'provided';
55
+ } else if (
56
+ removedHeaders.has('authorization') ||
57
+ options.headers?.['authorization'] !== undefined ||
58
+ !initialAuthUsedAPIKey
59
+ ) {
60
+ authentication = 'cached';
61
+ } else {
62
+ authentication = 'refresh';
63
+ }
64
+ return { options, removedHeaders, authentication };
65
+ }
66
+
67
+ /** Per-connection credential snapshots shared by Node WebSocket bindings. */
68
+ export class WebSocketCredentials {
69
+ private readonly connectionName: string;
70
+
71
+ constructor(connectionName: string) {
72
+ this.connectionName = connectionName;
73
+ }
74
+ private initialAuthUsedAPIKey = false;
75
+ private initialAPIKey: string | undefined;
76
+ private prepared:
77
+ | {
78
+ options: ReturnType<typeof buildWebSocketOptions>;
79
+ removedHeaders: Set<string>;
80
+ apiKey?: string | null | undefined;
81
+ }
82
+ | undefined;
83
+
84
+ get preparedAPIKey(): string | null | undefined {
85
+ return this.prepared?.apiKey;
86
+ }
87
+
88
+ trackInitialHeaders(client: OpenAI, headers: Record<string, string>, hasSocket: () => boolean): void {
89
+ if (!hasSocket() && client._hasApiKeyProvider()) {
90
+ this.initialAPIKey = headers['Authorization']?.slice('Bearer '.length);
91
+ }
92
+ }
93
+
94
+ usesAPIKey(client: OpenAI, headers: Record<string, string>): boolean {
95
+ // Hooks can read the SDK key without delegating. Only use an ordinary cached property here:
96
+ // invoking custom/Bedrock getters could validate credentials a caller-owned socket never sends.
97
+ const apiKey =
98
+ this.initialAPIKey ??
99
+ (client._hasApiKeyProvider() ? Object.getOwnPropertyDescriptor(client, 'apiKey')?.value : undefined);
100
+ if (!apiKey) {
101
+ return false;
102
+ }
103
+ // Metadata containing a copy of a credential does not make it the socket's authentication.
104
+ return snapshotWebSocketCredentials(
105
+ {
106
+ headers: Object.fromEntries(
107
+ Object.entries(headers).map(([name, value]) => [name, value?.includes(apiKey) ? value : '']),
108
+ ),
109
+ },
110
+ WEBSOCKET_METADATA_HEADERS,
111
+ );
112
+ }
113
+
114
+ build<Options extends CredentialedWebSocketOptions>(
115
+ client: OpenAI,
116
+ authHeaders: Record<string, string>,
117
+ options: Options | null | undefined,
118
+ initialAuthUsedAPIKey?: boolean,
119
+ ) {
120
+ if (initialAuthUsedAPIKey !== undefined) {
121
+ this.initialAuthUsedAPIKey = initialAuthUsedAPIKey;
122
+ this.initialAPIKey = undefined;
123
+ }
124
+ const socketOptions = buildCredentialedWebSocketOptions(client, authHeaders, options, this.prepared);
125
+ if (
126
+ client._hasApiKeyProvider() &&
127
+ !authHeaders['Authorization'] &&
128
+ !snapshotWebSocketCredentials(socketOptions, WEBSOCKET_METADATA_HEADERS)
129
+ ) {
130
+ throw new OpenAIError(
131
+ `Cannot open a ${this.connectionName} WebSocket with an unresolved function-based apiKey. Resolve it before constructing the WebSocket or provide explicit WebSocket credentials.`,
132
+ );
133
+ }
134
+ return socketOptions;
135
+ }
136
+
137
+ async prepare<Socket, Options extends CredentialedWebSocketOptions>(
138
+ client: OpenAI,
139
+ socketOptions: Options | null | undefined,
140
+ authHeaders: (apiKey?: string | null) => Record<string, string>,
141
+ createSocket: (url: URL, headers: Record<string, string>) => Socket,
142
+ ): Promise<(url: URL) => Socket> {
143
+ const { options, removedHeaders, authentication } = prepareWebSocketReconnect(
144
+ client,
145
+ socketOptions,
146
+ this.initialAuthUsedAPIKey,
147
+ );
148
+ const createPreparedSocket = (url: URL, headers: Record<string, string>, apiKey?: string | null) => {
149
+ const previous = this.prepared;
150
+ this.prepared = { options, removedHeaders, apiKey };
151
+ try {
152
+ // Resolve headers inside the scope so legacy zero-argument overrides see this attempt's key.
153
+ return createSocket(url, apiKey === undefined ? headers : authHeaders(apiKey));
154
+ } finally {
155
+ this.prepared = previous;
156
+ }
157
+ };
158
+ if (authentication !== 'refresh') {
159
+ const headers = authentication === 'provided' ? {} : authHeaders();
160
+ return (url) => createPreparedSocket(url, headers);
161
+ }
162
+ const { commit } = await resolveRealtimeAPIKey(client, true);
163
+ return (url) => createPreparedSocket(url, {}, commit());
164
+ }
165
+ }
@@ -1,6 +1,6 @@
1
1
  /* oxlint-disable max-classes-per-file -- Both thin facades belong to the same public Live WebRTC entrypoint. */
2
2
  import type {
3
- ConnectClientEvent as ClientEvent,
3
+ ConnectClientEvent,
4
4
  ConnectServerEvent as ServerEvent,
5
5
  } from '../../resources/live/sideband/sideband';
6
6
  import { WebRTCConnection } from '../webrtc/connection';
@@ -16,6 +16,9 @@ export type {
16
16
  WebRTCState,
17
17
  } from '../webrtc/types';
18
18
 
19
+ /** Fixture playback requires a primary WebSocket or server sideband. */
20
+ type ClientEvent = Exclude<ConnectClientEvent, { type: 'session.output_audio.fixture.play' }>;
21
+
19
22
  /** Browser Live connection with application-owned SDP exchange and typed server-event subscriptions. */
20
23
  export class OpenAILiveWebRTC extends WebRTCConnection<ClientEvent, ServerEvent> {}
21
24
 
@@ -153,8 +153,20 @@ export class APIKeys extends APIResource {
153
153
  }
154
154
 
155
155
  /**
156
- * Updates the expiration of an existing API key in the project, including a
157
- * service-account-owned key. Requires permission to write project API keys.
156
+ * Updates the scopes and/or expiration of an existing API key in the project,
157
+ * including a service-account-owned key. Requires permission to write project API
158
+ * keys.
159
+ *
160
+ * Provide at least one of `scopes` or `expires_in_seconds`. Omitted fields stay
161
+ * unchanged; neither field accepts `null`. Both changes are saved together.
162
+ *
163
+ * `scopes` replaces the key's scope restrictions using the same scope identifiers
164
+ * as the dashboard. An empty array means All permissions, subject to the owner's
165
+ * effective access; it does not mean no access. Use `["api.all.read"]` for
166
+ * read-only access or specific scopes such as `["api.files.read"]` for restricted
167
+ * access. This does not change user or service-account roles or grant admin
168
+ * permissions. Scope changes follow the same authentication-cache propagation as
169
+ * dashboard edits.
158
170
  *
159
171
  * Provide `expires_in_seconds` to set the expiration relative to this request. The
160
172
  * value must satisfy the organization's and project's expiry policies. Expired
@@ -166,7 +178,10 @@ export class APIKeys extends APIResource {
166
178
  * const projectAPIKey =
167
179
  * await client.admin.organization.projects.apiKeys.update(
168
180
  * 'api_key_id',
169
- * { project_id: 'project_id', expires_in_seconds: 1 },
181
+ * {
182
+ * project_id: 'project_id',
183
+ * scopes: ['api.all.read'],
184
+ * },
170
185
  * );
171
186
  * ```
172
187
  */
@@ -486,9 +501,18 @@ export interface APIKeyUpdateParams {
486
501
  /**
487
502
  * Body param: Number of seconds from this request until the API key expires. Must
488
503
  * comply with the organization and project expiry policies. Expired keys cannot be
489
- * updated. Retrying resets the expiry relative to the new request.
504
+ * updated. Retrying resets the expiry relative to the new request. Omit to keep
505
+ * the current expiration.
506
+ */
507
+ expires_in_seconds?: number;
508
+
509
+ /**
510
+ * Body param: Replace the API key scope restrictions. Omit to leave scopes
511
+ * unchanged. An empty array removes key restrictions (All permissions), subject to
512
+ * the owner's effective permissions. Use ["api.all.read"] for read-only access.
513
+ * Scopes do not change the owner's roles or grant administrative permissions.
490
514
  */
491
- expires_in_seconds: number;
515
+ scopes?: Array<string>;
492
516
  }
493
517
 
494
518
  export interface APIKeyListParams extends ConversationCursorPageParams {
@@ -69,7 +69,8 @@ export interface SpeechCreateParams {
69
69
  * object with an `id`, for example `{ "id": "voice_1234" }`. Previews of the
70
70
  * voices are available in the
71
71
  * [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
72
- * Custom voices must be created from audio samples.
72
+ * Custom voices must be created from audio samples. Voices created from text
73
+ * prompts are supported only in Live.
73
74
  */
74
75
  voice:
75
76
  | string
@@ -18,17 +18,17 @@ function resolveResourceRequestOptions(
18
18
  */
19
19
  export class Voices extends APIResource {
20
20
  /**
21
- * Create a custom voice you can use for audio output (for example, in
22
- * Text-to-Speech and the Realtime API). This requires an audio sample and a
23
- * previously uploaded consent recording.
21
+ * Creates a voice from a text prompt or from a consent recording and an audio
22
+ * sample.
24
23
  *
25
- * Send `name`, `audio_sample`, and the `consent` recording ID as multipart form
26
- * data. The optional `type` defaults to `audio_sample`.
24
+ * For prompt-based creation, send `type: "prompt"` with a `name` and `prompt` as
25
+ * JSON or multipart form data. For creation from an audio sample, send
26
+ * `type: "audio_sample"` with a `name`, `audio_sample`, and `consent` recording ID
27
+ * as multipart form data. The type defaults to `audio_sample` when omitted.
27
28
  *
28
- * Returns the saved voice's metadata. See the
29
- * [custom voices guide](https://developers.openai.com/api/docs/guides/text-to-speech#custom-voices)
30
- * for requirements and best practices. Custom voices are limited to eligible
31
- * customers.
29
+ * Returns the saved voice's metadata. Voices created from text prompts are
30
+ * supported only in Live, not in Realtime or the speech endpoint. The response
31
+ * does not include preview audio.
32
32
  *
33
33
  * @example
34
34
  * ```ts
@@ -50,7 +50,8 @@ export class Voices extends APIResource {
50
50
  }
51
51
 
52
52
  /**
53
- * A custom voice that can be used for audio output.
53
+ * A custom voice that can be used for audio output. Voices created from text
54
+ * prompts are supported only in Live.
54
55
  */
55
56
  export interface Voice {
56
57
  /**
@@ -76,10 +77,17 @@ export interface Voice {
76
77
  /**
77
78
  * How the voice was created.
78
79
  */
79
- type: 'audio_sample';
80
+ type: 'audio_sample' | 'prompt';
81
+
82
+ /**
83
+ * The original text prompt used to create the voice. Present for prompt-generated
84
+ * voices with a stored prompt; omitted for audio-sample voices and older voices
85
+ * without a stored prompt.
86
+ */
87
+ prompt?: string;
80
88
  }
81
89
 
82
- export type VoiceCreateParams = VoiceCreateParams.Consent;
90
+ export type VoiceCreateParams = VoiceCreateParams.Consent | VoiceCreateParams.Prompt;
83
91
 
84
92
  export declare namespace VoiceCreateParams {
85
93
  /**
@@ -110,6 +118,39 @@ export declare namespace VoiceCreateParams {
110
118
  */
111
119
  type?: 'audio_sample';
112
120
  }
121
+
122
+ /**
123
+ * Creates a synthetic voice from a text description. Supports application/json or
124
+ * multipart/form-data.
125
+ */
126
+ export interface Prompt {
127
+ /**
128
+ * The name of the new voice.
129
+ */
130
+ name: string;
131
+
132
+ /**
133
+ * A description of the desired voice. Must not contain only whitespace.
134
+ */
135
+ prompt: string;
136
+
137
+ /**
138
+ * Set to `prompt` to create a voice from a text description.
139
+ */
140
+ type: 'prompt';
141
+
142
+ /**
143
+ * The voice creation model to use. Defaults to `auto`.
144
+ */
145
+ model?: string | 'auto' | '2026-10-08';
146
+
147
+ /**
148
+ * Optional text for the voice to speak during creation. If omitted, a script is
149
+ * generated from the prompt. Must not be blank after trimming whitespace; scripts
150
+ * that are too short are rejected.
151
+ */
152
+ script_hint?: string;
153
+ }
113
154
  }
114
155
 
115
156
  export declare namespace Voices {
@@ -1173,6 +1173,11 @@ export namespace RealtimeResponseStatus {
1173
1173
  */
1174
1174
  code?: string;
1175
1175
 
1176
+ /**
1177
+ * A human-readable error message.
1178
+ */
1179
+ message?: string;
1180
+
1176
1181
  /**
1177
1182
  * The type of error.
1178
1183
  */
@@ -3706,6 +3706,16 @@ export interface BetaResponseError {
3706
3706
  message: string;
3707
3707
 
3708
3708
  misalignment?: BetaResponseError.Misalignment;
3709
+
3710
+ /**
3711
+ * The request parameter associated with the error, or null if none was recorded.
3712
+ */
3713
+ param?: string | null;
3714
+
3715
+ /**
3716
+ * The original error type, or null if it was not recorded.
3717
+ */
3718
+ type?: string | null;
3709
3719
  }
3710
3720
 
3711
3721
  export namespace BetaResponseError {