openai 7.25.0 → 7.26.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 (308) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/client.d.mts +5 -6
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +5 -6
  5. package/client.d.ts.map +1 -1
  6. package/client.js +38 -10
  7. package/client.js.map +1 -1
  8. package/client.mjs +39 -11
  9. package/client.mjs.map +1 -1
  10. package/core/streaming.d.mts +4 -0
  11. package/core/streaming.d.mts.map +1 -1
  12. package/core/streaming.d.ts +4 -0
  13. package/core/streaming.d.ts.map +1 -1
  14. package/core/streaming.js +6 -0
  15. package/core/streaming.js.map +1 -1
  16. package/core/streaming.mjs +6 -0
  17. package/core/streaming.mjs.map +1 -1
  18. package/helpers/beta/agents/standard-schema.d.mts +7 -0
  19. package/helpers/beta/agents/standard-schema.d.mts.map +1 -0
  20. package/helpers/beta/agents/standard-schema.d.ts +7 -0
  21. package/helpers/beta/agents/standard-schema.d.ts.map +1 -0
  22. package/helpers/beta/agents/standard-schema.js +12 -0
  23. package/helpers/beta/agents/standard-schema.js.map +1 -0
  24. package/helpers/beta/agents/standard-schema.mjs +9 -0
  25. package/helpers/beta/agents/standard-schema.mjs.map +1 -0
  26. package/helpers/beta/agents/zod.d.mts +10 -0
  27. package/helpers/beta/agents/zod.d.mts.map +1 -0
  28. package/helpers/beta/agents/zod.d.ts +10 -0
  29. package/helpers/beta/agents/zod.d.ts.map +1 -0
  30. package/helpers/beta/agents/zod.js +12 -0
  31. package/helpers/beta/agents/zod.js.map +1 -0
  32. package/helpers/beta/agents/zod.mjs +9 -0
  33. package/helpers/beta/agents/zod.mjs.map +1 -0
  34. package/internal/realtime-credentials.d.mts +22 -1
  35. package/internal/realtime-credentials.d.mts.map +1 -1
  36. package/internal/realtime-credentials.d.ts +22 -1
  37. package/internal/realtime-credentials.d.ts.map +1 -1
  38. package/internal/realtime-credentials.js +48 -4
  39. package/internal/realtime-credentials.js.map +1 -1
  40. package/internal/realtime-credentials.mjs +45 -4
  41. package/internal/realtime-credentials.mjs.map +1 -1
  42. package/internal/responses-ws-credentials.d.mts +23 -0
  43. package/internal/responses-ws-credentials.d.mts.map +1 -0
  44. package/internal/responses-ws-credentials.d.ts +23 -0
  45. package/internal/responses-ws-credentials.d.ts.map +1 -0
  46. package/internal/responses-ws-credentials.js +108 -0
  47. package/internal/responses-ws-credentials.js.map +1 -0
  48. package/internal/responses-ws-credentials.mjs +104 -0
  49. package/internal/responses-ws-credentials.mjs.map +1 -0
  50. package/internal/ws-adapter-node.d.mts +4 -0
  51. package/internal/ws-adapter-node.d.mts.map +1 -1
  52. package/internal/ws-adapter-node.d.ts +4 -0
  53. package/internal/ws-adapter-node.d.ts.map +1 -1
  54. package/internal/ws-adapter-node.js +56 -0
  55. package/internal/ws-adapter-node.js.map +1 -1
  56. package/internal/ws-adapter-node.mjs +55 -0
  57. package/internal/ws-adapter-node.mjs.map +1 -1
  58. package/internal/ws.d.mts +27 -4
  59. package/internal/ws.d.mts.map +1 -1
  60. package/internal/ws.d.ts +27 -4
  61. package/internal/ws.d.ts.map +1 -1
  62. package/internal/ws.js +105 -5
  63. package/internal/ws.js.map +1 -1
  64. package/internal/ws.mjs +102 -4
  65. package/internal/ws.mjs.map +1 -1
  66. package/lib/agents/agent-session-stream.d.mts +13 -4
  67. package/lib/agents/agent-session-stream.d.mts.map +1 -1
  68. package/lib/agents/agent-session-stream.d.ts +13 -4
  69. package/lib/agents/agent-session-stream.d.ts.map +1 -1
  70. package/lib/agents/agent-session-stream.js +24 -21
  71. package/lib/agents/agent-session-stream.js.map +1 -1
  72. package/lib/agents/agent-session-stream.mjs +24 -21
  73. package/lib/agents/agent-session-stream.mjs.map +1 -1
  74. package/lib/beta/agents/agent-session-create-stream.d.mts +15 -0
  75. package/lib/beta/agents/agent-session-create-stream.d.mts.map +1 -0
  76. package/lib/beta/agents/agent-session-create-stream.d.ts +15 -0
  77. package/lib/beta/agents/agent-session-create-stream.d.ts.map +1 -0
  78. package/lib/beta/agents/agent-session-create-stream.js +25 -0
  79. package/lib/beta/agents/agent-session-create-stream.js.map +1 -0
  80. package/lib/beta/agents/agent-session-create-stream.mjs +22 -0
  81. package/lib/beta/agents/agent-session-create-stream.mjs.map +1 -0
  82. package/lib/beta/agents/agent-turn-result-collector.d.mts +17 -0
  83. package/lib/beta/agents/agent-turn-result-collector.d.mts.map +1 -0
  84. package/lib/beta/agents/agent-turn-result-collector.d.ts +17 -0
  85. package/lib/beta/agents/agent-turn-result-collector.d.ts.map +1 -0
  86. package/lib/beta/agents/agent-turn-result-collector.js +99 -0
  87. package/lib/beta/agents/agent-turn-result-collector.js.map +1 -0
  88. package/lib/beta/agents/agent-turn-result-collector.mjs +95 -0
  89. package/lib/beta/agents/agent-turn-result-collector.mjs.map +1 -0
  90. package/lib/beta/agents/agent-turn-result-error.d.mts +16 -0
  91. package/lib/beta/agents/agent-turn-result-error.d.mts.map +1 -0
  92. package/lib/beta/agents/agent-turn-result-error.d.ts +16 -0
  93. package/lib/beta/agents/agent-turn-result-error.d.ts.map +1 -0
  94. package/lib/beta/agents/agent-turn-result-error.js +22 -0
  95. package/lib/beta/agents/agent-turn-result-error.js.map +1 -0
  96. package/lib/beta/agents/agent-turn-result-error.mjs +18 -0
  97. package/lib/beta/agents/agent-turn-result-error.mjs.map +1 -0
  98. package/lib/beta/agents/agent-turn-result.d.mts +12 -0
  99. package/lib/beta/agents/agent-turn-result.d.mts.map +1 -0
  100. package/lib/beta/agents/agent-turn-result.d.ts +12 -0
  101. package/lib/beta/agents/agent-turn-result.d.ts.map +1 -0
  102. package/lib/beta/agents/agent-turn-result.js +22 -0
  103. package/lib/beta/agents/agent-turn-result.js.map +1 -0
  104. package/lib/beta/agents/agent-turn-result.mjs +18 -0
  105. package/lib/beta/agents/agent-turn-result.mjs.map +1 -0
  106. package/lib/beta/agents/function-tool.d.mts +27 -0
  107. package/lib/beta/agents/function-tool.d.mts.map +1 -0
  108. package/lib/beta/agents/function-tool.d.ts +27 -0
  109. package/lib/beta/agents/function-tool.d.ts.map +1 -0
  110. package/lib/beta/agents/function-tool.js +48 -0
  111. package/lib/beta/agents/function-tool.js.map +1 -0
  112. package/lib/beta/agents/function-tool.mjs +45 -0
  113. package/lib/beta/agents/function-tool.mjs.map +1 -0
  114. package/lib/beta/agents/output-format-types.d.mts +11 -0
  115. package/lib/beta/agents/output-format-types.d.mts.map +1 -0
  116. package/lib/beta/agents/output-format-types.d.ts +11 -0
  117. package/lib/beta/agents/output-format-types.d.ts.map +1 -0
  118. package/lib/beta/agents/output-format-types.js +3 -0
  119. package/lib/beta/agents/output-format-types.js.map +1 -0
  120. package/lib/beta/agents/output-format-types.mjs +2 -0
  121. package/lib/beta/agents/output-format-types.mjs.map +1 -0
  122. package/lib/beta/agents/output-format.d.mts +8 -0
  123. package/lib/beta/agents/output-format.d.mts.map +1 -0
  124. package/lib/beta/agents/output-format.d.ts +8 -0
  125. package/lib/beta/agents/output-format.d.ts.map +1 -0
  126. package/lib/beta/agents/output-format.js +20 -0
  127. package/lib/beta/agents/output-format.js.map +1 -0
  128. package/lib/beta/agents/output-format.mjs +14 -0
  129. package/lib/beta/agents/output-format.mjs.map +1 -0
  130. package/lib/beta/agents/output-parse-error.d.mts +11 -0
  131. package/lib/beta/agents/output-parse-error.d.mts.map +1 -0
  132. package/lib/beta/agents/output-parse-error.d.ts +11 -0
  133. package/lib/beta/agents/output-parse-error.d.ts.map +1 -0
  134. package/lib/beta/agents/output-parse-error.js +22 -0
  135. package/lib/beta/agents/output-parse-error.js.map +1 -0
  136. package/lib/beta/agents/output-parse-error.mjs +18 -0
  137. package/lib/beta/agents/output-parse-error.mjs.map +1 -0
  138. package/lib/beta/agents/parse-result.d.mts +95 -0
  139. package/lib/beta/agents/parse-result.d.mts.map +1 -0
  140. package/lib/beta/agents/parse-result.d.ts +95 -0
  141. package/lib/beta/agents/parse-result.d.ts.map +1 -0
  142. package/lib/beta/agents/parse-result.js +116 -0
  143. package/lib/beta/agents/parse-result.js.map +1 -0
  144. package/lib/beta/agents/parse-result.mjs +110 -0
  145. package/lib/beta/agents/parse-result.mjs.map +1 -0
  146. package/lib/beta/agents/parsed-agent-turn-result.d.mts +8 -0
  147. package/lib/beta/agents/parsed-agent-turn-result.d.mts.map +1 -0
  148. package/lib/beta/agents/parsed-agent-turn-result.d.ts +8 -0
  149. package/lib/beta/agents/parsed-agent-turn-result.d.ts.map +1 -0
  150. package/lib/beta/agents/parsed-agent-turn-result.js +14 -0
  151. package/lib/beta/agents/parsed-agent-turn-result.js.map +1 -0
  152. package/lib/beta/agents/parsed-agent-turn-result.mjs +10 -0
  153. package/lib/beta/agents/parsed-agent-turn-result.mjs.map +1 -0
  154. package/lib/beta/agents/result-collection.d.mts +15 -0
  155. package/lib/beta/agents/result-collection.d.mts.map +1 -0
  156. package/lib/beta/agents/result-collection.d.ts +15 -0
  157. package/lib/beta/agents/result-collection.d.ts.map +1 -0
  158. package/lib/beta/agents/result-collection.js +110 -0
  159. package/lib/beta/agents/result-collection.js.map +1 -0
  160. package/lib/beta/agents/result-collection.mjs +106 -0
  161. package/lib/beta/agents/result-collection.mjs.map +1 -0
  162. package/lib/beta/agents/tool-output.d.mts +7 -0
  163. package/lib/beta/agents/tool-output.d.mts.map +1 -0
  164. package/lib/beta/agents/tool-output.d.ts +7 -0
  165. package/lib/beta/agents/tool-output.d.ts.map +1 -0
  166. package/lib/beta/agents/tool-output.js +26 -0
  167. package/lib/beta/agents/tool-output.js.map +1 -0
  168. package/lib/beta/agents/tool-output.mjs +23 -0
  169. package/lib/beta/agents/tool-output.mjs.map +1 -0
  170. package/lib/responses/responses-websocket-session.d.mts +1 -1
  171. package/lib/responses/responses-websocket-session.d.mts.map +1 -1
  172. package/lib/responses/responses-websocket-session.d.ts +1 -1
  173. package/lib/responses/responses-websocket-session.d.ts.map +1 -1
  174. package/lib/responses/responses-websocket-session.js +12 -2
  175. package/lib/responses/responses-websocket-session.js.map +1 -1
  176. package/lib/responses/responses-websocket-session.mjs +12 -2
  177. package/lib/responses/responses-websocket-session.mjs.map +1 -1
  178. package/package.json +1 -1
  179. package/resources/beta/agents/agents.d.mts +9 -0
  180. package/resources/beta/agents/agents.d.mts.map +1 -1
  181. package/resources/beta/agents/agents.d.ts +9 -0
  182. package/resources/beta/agents/agents.d.ts.map +1 -1
  183. package/resources/beta/agents/agents.js.map +1 -1
  184. package/resources/beta/agents/agents.mjs.map +1 -1
  185. package/resources/beta/agents/sessions/events.d.mts +6 -5
  186. package/resources/beta/agents/sessions/events.d.mts.map +1 -1
  187. package/resources/beta/agents/sessions/events.d.ts +6 -5
  188. package/resources/beta/agents/sessions/events.d.ts.map +1 -1
  189. package/resources/beta/agents/sessions/events.js +6 -5
  190. package/resources/beta/agents/sessions/events.js.map +1 -1
  191. package/resources/beta/agents/sessions/events.mjs +6 -5
  192. package/resources/beta/agents/sessions/events.mjs.map +1 -1
  193. package/resources/beta/agents/sessions/index.d.mts +1 -0
  194. package/resources/beta/agents/sessions/index.d.mts.map +1 -1
  195. package/resources/beta/agents/sessions/index.d.ts +1 -0
  196. package/resources/beta/agents/sessions/index.d.ts.map +1 -1
  197. package/resources/beta/agents/sessions/index.js +3 -1
  198. package/resources/beta/agents/sessions/index.js.map +1 -1
  199. package/resources/beta/agents/sessions/index.mjs +1 -0
  200. package/resources/beta/agents/sessions/index.mjs.map +1 -1
  201. package/resources/beta/agents/sessions/sessions.d.mts +16 -4
  202. package/resources/beta/agents/sessions/sessions.d.mts.map +1 -1
  203. package/resources/beta/agents/sessions/sessions.d.ts +16 -4
  204. package/resources/beta/agents/sessions/sessions.d.ts.map +1 -1
  205. package/resources/beta/agents/sessions/sessions.js +17 -4
  206. package/resources/beta/agents/sessions/sessions.js.map +1 -1
  207. package/resources/beta/agents/sessions/sessions.mjs +17 -4
  208. package/resources/beta/agents/sessions/sessions.mjs.map +1 -1
  209. package/resources/beta/agents/sessions/traces.d.mts +68 -0
  210. package/resources/beta/agents/sessions/traces.d.mts.map +1 -0
  211. package/resources/beta/agents/sessions/traces.d.ts +68 -0
  212. package/resources/beta/agents/sessions/traces.d.ts.map +1 -0
  213. package/resources/beta/agents/sessions/traces.js +81 -0
  214. package/resources/beta/agents/sessions/traces.js.map +1 -0
  215. package/resources/beta/agents/sessions/traces.mjs +77 -0
  216. package/resources/beta/agents/sessions/traces.mjs.map +1 -0
  217. package/resources/beta/responses/ws-base.d.mts +3 -1
  218. package/resources/beta/responses/ws-base.d.mts.map +1 -1
  219. package/resources/beta/responses/ws-base.d.ts +3 -1
  220. package/resources/beta/responses/ws-base.d.ts.map +1 -1
  221. package/resources/beta/responses/ws-base.js +35 -6
  222. package/resources/beta/responses/ws-base.js.map +1 -1
  223. package/resources/beta/responses/ws-base.mjs +35 -6
  224. package/resources/beta/responses/ws-base.mjs.map +1 -1
  225. package/resources/beta/responses/ws.d.mts +10 -0
  226. package/resources/beta/responses/ws.d.mts.map +1 -1
  227. package/resources/beta/responses/ws.d.ts +10 -0
  228. package/resources/beta/responses/ws.d.ts.map +1 -1
  229. package/resources/beta/responses/ws.js +23 -22
  230. package/resources/beta/responses/ws.js.map +1 -1
  231. package/resources/beta/responses/ws.mjs +24 -23
  232. package/resources/beta/responses/ws.mjs.map +1 -1
  233. package/resources/chat/completions/completions.d.mts +1 -1
  234. package/resources/chat/completions/completions.d.mts.map +1 -1
  235. package/resources/chat/completions/completions.d.ts +1 -1
  236. package/resources/chat/completions/completions.d.ts.map +1 -1
  237. package/resources/evals/runs/runs.js +1 -1
  238. package/resources/evals/runs/runs.js.map +1 -1
  239. package/resources/evals/runs/runs.mjs +1 -1
  240. package/resources/evals/runs/runs.mjs.map +1 -1
  241. package/resources/live/forks/forks.d.mts +5 -1
  242. package/resources/live/forks/forks.d.mts.map +1 -1
  243. package/resources/live/forks/forks.d.ts +5 -1
  244. package/resources/live/forks/forks.d.ts.map +1 -1
  245. package/resources/live/live.d.mts +5 -1
  246. package/resources/live/live.d.mts.map +1 -1
  247. package/resources/live/live.d.ts +5 -1
  248. package/resources/live/live.d.ts.map +1 -1
  249. package/resources/live/live.js.map +1 -1
  250. package/resources/live/live.mjs.map +1 -1
  251. package/resources/responses/ws-base.d.mts +3 -1
  252. package/resources/responses/ws-base.d.mts.map +1 -1
  253. package/resources/responses/ws-base.d.ts +3 -1
  254. package/resources/responses/ws-base.d.ts.map +1 -1
  255. package/resources/responses/ws-base.js +35 -6
  256. package/resources/responses/ws-base.js.map +1 -1
  257. package/resources/responses/ws-base.mjs +35 -6
  258. package/resources/responses/ws-base.mjs.map +1 -1
  259. package/resources/responses/ws.d.mts +10 -0
  260. package/resources/responses/ws.d.mts.map +1 -1
  261. package/resources/responses/ws.d.ts +10 -0
  262. package/resources/responses/ws.d.ts.map +1 -1
  263. package/resources/responses/ws.js +23 -22
  264. package/resources/responses/ws.js.map +1 -1
  265. package/resources/responses/ws.mjs +24 -23
  266. package/resources/responses/ws.mjs.map +1 -1
  267. package/src/client.ts +55 -19
  268. package/src/core/streaming.ts +9 -0
  269. package/src/helpers/beta/agents/standard-schema.ts +13 -0
  270. package/src/helpers/beta/agents/zod.ts +10 -0
  271. package/src/internal/realtime-credentials.ts +70 -4
  272. package/src/internal/responses-ws-credentials.ts +160 -0
  273. package/src/internal/ws-adapter-node.ts +66 -0
  274. package/src/internal/ws.ts +139 -11
  275. package/src/lib/agents/agent-session-stream.ts +36 -24
  276. package/src/lib/beta/agents/agent-session-create-stream.ts +36 -0
  277. package/src/lib/beta/agents/agent-turn-result-collector.ts +122 -0
  278. package/src/lib/beta/agents/agent-turn-result-error.ts +33 -0
  279. package/src/lib/beta/agents/agent-turn-result.ts +22 -0
  280. package/src/lib/beta/agents/function-tool.ts +60 -0
  281. package/src/lib/beta/agents/output-format-types.ts +12 -0
  282. package/src/lib/beta/agents/output-format.ts +20 -0
  283. package/src/lib/beta/agents/output-parse-error.ts +16 -0
  284. package/src/lib/beta/agents/parse-result.ts +133 -0
  285. package/src/lib/beta/agents/parsed-agent-turn-result.ts +12 -0
  286. package/src/lib/beta/agents/result-collection.ts +115 -0
  287. package/src/lib/beta/agents/tool-output.ts +22 -0
  288. package/src/lib/responses/responses-websocket-session.ts +14 -3
  289. package/src/resources/beta/agents/agents.ts +11 -0
  290. package/src/resources/beta/agents/sessions/events.ts +6 -5
  291. package/src/resources/beta/agents/sessions/index.ts +1 -0
  292. package/src/resources/beta/agents/sessions/sessions.ts +48 -18
  293. package/src/resources/beta/agents/sessions/traces.ts +298 -0
  294. package/src/resources/beta/responses/ws-base.ts +40 -6
  295. package/src/resources/beta/responses/ws.ts +37 -27
  296. package/src/resources/chat/completions/completions.ts +1 -1
  297. package/src/resources/evals/runs/runs.ts +1 -1
  298. package/src/resources/live/forks/forks.ts +6 -1
  299. package/src/resources/live/live.ts +6 -1
  300. package/src/resources/responses/ws-base.ts +40 -6
  301. package/src/resources/responses/ws.ts +37 -27
  302. package/src/tsconfig.dist-src-node.d.ts +7 -0
  303. package/src/tsconfig.dist-src.d.ts +3 -1
  304. package/src/version.ts +1 -1
  305. package/version.d.mts +1 -1
  306. package/version.d.ts +1 -1
  307. package/version.js +1 -1
  308. package/version.mjs +1 -1
@@ -6,8 +6,7 @@ const tslib_1 = require("../../internal/tslib.js");
6
6
  const WS = tslib_1.__importStar(require("ws"));
7
7
  const ws_adapter_node_1 = require("../../internal/ws-adapter-node.js");
8
8
  const ws_base_1 = require("./ws-base.js");
9
- const error_1 = require("../../core/error.js");
10
- const ws_1 = require("../../internal/ws.js");
9
+ const responses_ws_credentials_1 = require("../../internal/responses-ws-credentials.js");
11
10
  class ResponsesWS extends ws_base_1.ResponsesWSBase {
12
11
  constructor(client, options) {
13
12
  if (!WS?.WebSocket) {
@@ -15,32 +14,34 @@ class ResponsesWS extends ws_base_1.ResponsesWSBase {
15
14
  }
16
15
  const { reconnect, maxQueueSize, ...wsOptions } = options ?? {};
17
16
  super(client, { reconnect, maxQueueSize });
17
+ this._credentials = new responses_ws_credentials_1.ResponsesWebSocketCredentials();
18
18
  this._wsOptions = wsOptions;
19
19
  this._connectInitial();
20
20
  }
21
+ _authHeaders(apiKey) {
22
+ const headers = super._authHeaders(apiKey === undefined ? this._credentials.preparedAPIKey : apiKey);
23
+ this._credentials.trackInitialHeaders(this._client, headers, () => !!this.socket);
24
+ return headers;
25
+ }
26
+ /**
27
+ * Whether credentials passed to the Node transport use the SDK key.
28
+ * The SDK recognizes its key, including copies and additions in credential headers.
29
+ * Override and return true if your socket hook signs or otherwise irreversibly transforms it.
30
+ * Explicit caller options and header removals still take precedence on reconnect.
31
+ */
32
+ _usesSDKAPIKey(authHeaders) {
33
+ return this._credentials.usesAPIKey(this._client, authHeaders);
34
+ }
21
35
  _createSocket(url, authHeaders) {
22
36
  const capturedAuthHeaders = { ...authHeaders };
23
- const headers = new Map(Object.entries(this._client._buildWebSocketHeaders(capturedAuthHeaders)));
24
- for (const [name, value] of Object.entries(this._wsOptions?.headers ?? {})) {
25
- if (value === null) {
26
- headers.delete(name.toLowerCase());
27
- }
28
- else if (value !== undefined) {
29
- headers.set(name.toLowerCase(), value);
30
- }
31
- }
32
- const socketOptions = {
33
- ...this._wsOptions,
34
- headers: Object.fromEntries(headers),
35
- followRedirects: false,
36
- };
37
- if (this._client._hasApiKeyProvider() &&
38
- !capturedAuthHeaders['Authorization'] &&
39
- !(0, ws_1.snapshotWebSocketCredentials)(socketOptions)) {
40
- throw new error_1.OpenAIError('Cannot open a Responses WebSocket with an unresolved function-based apiKey. Resolve it before constructing the WebSocket or provide explicit WebSocket credentials.');
37
+ const socketOptions = this._credentials.build(this._client, capturedAuthHeaders, this._wsOptions, !this.socket ? this._usesSDKAPIKey(capturedAuthHeaders) : undefined);
38
+ return new ws_adapter_node_1.NodeWebSocket(new WS.WebSocket(url, socketOptions));
39
+ }
40
+ async _prepareReconnectSocket() {
41
+ if (!this._client._hasApiKeyProvider()) {
42
+ return super._prepareReconnectSocket();
41
43
  }
42
- const ws = new WS.WebSocket(url, socketOptions);
43
- return new ws_adapter_node_1.NodeWebSocket(ws);
44
+ return this._credentials.prepare(this._client, (0, ws_adapter_node_1.snapshotNodeWebSocketOptions)(this._wsOptions), (...args) => this._authHeaders(...args), (url, headers) => this._createSocket(url, headers));
44
45
  }
45
46
  }
46
47
  exports.ResponsesWS = ResponsesWS;
@@ -1 +1 @@
1
- {"version":3,"file":"ws.js","sourceRoot":"","sources":["../../src/resources/responses/ws.ts"],"names":[],"mappings":";AAAA,qFAAqF;;;;AAErF,+CAAyB;AACzB,uEAA+D;AAC/D,0CAAyE;AAEzE,+CAA+C;AAC/C,6CAAiE;AAWjE,MAAa,WAAY,SAAQ,yBAA8B;IAG7D,YAAY,MAAc,EAAE,OAAqD;QAC/E,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,wGAAwG,CACzG,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAChE,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAES,aAAa,CAAC,GAAQ,EAAE,WAAmC;QACnE,MAAM,mBAAmB,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAClG,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;YAC3E,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACrC,CAAC;iBAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QACD,MAAM,aAAa,GAA6B;YAC9C,GAAG,IAAI,CAAC,UAAU;YAClB,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;YACpC,eAAe,EAAE,KAAK;SACvB,CAAC;QACF,IACE,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACjC,CAAC,mBAAmB,CAAC,eAAe,CAAC;YACrC,CAAC,IAAA,iCAA4B,EAAC,aAAa,CAAC,EAC5C,CAAC;YACD,MAAM,IAAI,mBAAW,CACnB,qKAAqK,CACtK,CAAC;QACJ,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAChD,OAAO,IAAI,+BAAa,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;CACF;AA3CD,kCA2CC"}
1
+ {"version":3,"file":"ws.js","sourceRoot":"","sources":["../../src/resources/responses/ws.ts"],"names":[],"mappings":";AAAA,qFAAqF;;;;AAErF,+CAAyB;AACzB,uEAA6F;AAC7F,0CAAyE;AAEzE,yFAAwF;AAWxF,MAAa,WAAY,SAAQ,yBAA8B;IAI7D,YAAY,MAAc,EAAE,OAAqD;QAC/E,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,wGAAwG,CACzG,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAChE,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;QATrC,iBAAY,GAAG,IAAI,wDAA6B,EAAE,CAAC;QAUzD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEkB,YAAY,CAAC,MAAsB;QACpD,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACrG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACO,cAAc,CAAC,WAAmC;QAC1D,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAES,aAAa,CAAC,GAAQ,EAAE,WAAmC;QACnE,MAAM,mBAAmB,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;QAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAC3C,IAAI,CAAC,OAAO,EACZ,mBAAmB,EACnB,IAAI,CAAC,UAAU,EACf,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS,CACpE,CAAC;QACF,OAAO,IAAI,+BAAa,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IACjE,CAAC;IAEkB,KAAK,CAAC,uBAAuB;QAC9C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC,uBAAuB,EAAE,CAAC;QACzC,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAC9B,IAAI,CAAC,OAAO,EACZ,IAAA,8CAA4B,EAAC,IAAI,CAAC,UAAU,CAAC,EAC7C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,EACvC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CACnD,CAAC;IACJ,CAAC;CACF;AAtDD,kCAsDC"}
@@ -1,9 +1,8 @@
1
1
  // File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details.
2
2
  import * as WS from 'ws';
3
- import { NodeWebSocket } from "../../internal/ws-adapter-node.mjs";
3
+ import { NodeWebSocket, snapshotNodeWebSocketOptions } from "../../internal/ws-adapter-node.mjs";
4
4
  import { ResponsesWSBase } from "./ws-base.mjs";
5
- import { OpenAIError } from "../../core/error.mjs";
6
- import { snapshotWebSocketCredentials } from "../../internal/ws.mjs";
5
+ import { ResponsesWebSocketCredentials } from "../../internal/responses-ws-credentials.mjs";
7
6
  export class ResponsesWS extends ResponsesWSBase {
8
7
  constructor(client, options) {
9
8
  if (!WS?.WebSocket) {
@@ -11,32 +10,34 @@ export class ResponsesWS extends ResponsesWSBase {
11
10
  }
12
11
  const { reconnect, maxQueueSize, ...wsOptions } = options ?? {};
13
12
  super(client, { reconnect, maxQueueSize });
13
+ this._credentials = new ResponsesWebSocketCredentials();
14
14
  this._wsOptions = wsOptions;
15
15
  this._connectInitial();
16
16
  }
17
+ _authHeaders(apiKey) {
18
+ const headers = super._authHeaders(apiKey === undefined ? this._credentials.preparedAPIKey : apiKey);
19
+ this._credentials.trackInitialHeaders(this._client, headers, () => !!this.socket);
20
+ return headers;
21
+ }
22
+ /**
23
+ * Whether credentials passed to the Node transport use the SDK key.
24
+ * The SDK recognizes its key, including copies and additions in credential headers.
25
+ * Override and return true if your socket hook signs or otherwise irreversibly transforms it.
26
+ * Explicit caller options and header removals still take precedence on reconnect.
27
+ */
28
+ _usesSDKAPIKey(authHeaders) {
29
+ return this._credentials.usesAPIKey(this._client, authHeaders);
30
+ }
17
31
  _createSocket(url, authHeaders) {
18
32
  const capturedAuthHeaders = { ...authHeaders };
19
- const headers = new Map(Object.entries(this._client._buildWebSocketHeaders(capturedAuthHeaders)));
20
- for (const [name, value] of Object.entries(this._wsOptions?.headers ?? {})) {
21
- if (value === null) {
22
- headers.delete(name.toLowerCase());
23
- }
24
- else if (value !== undefined) {
25
- headers.set(name.toLowerCase(), value);
26
- }
27
- }
28
- const socketOptions = {
29
- ...this._wsOptions,
30
- headers: Object.fromEntries(headers),
31
- followRedirects: false,
32
- };
33
- if (this._client._hasApiKeyProvider() &&
34
- !capturedAuthHeaders['Authorization'] &&
35
- !snapshotWebSocketCredentials(socketOptions)) {
36
- throw new OpenAIError('Cannot open a Responses WebSocket with an unresolved function-based apiKey. Resolve it before constructing the WebSocket or provide explicit WebSocket credentials.');
33
+ const socketOptions = this._credentials.build(this._client, capturedAuthHeaders, this._wsOptions, !this.socket ? this._usesSDKAPIKey(capturedAuthHeaders) : undefined);
34
+ return new NodeWebSocket(new WS.WebSocket(url, socketOptions));
35
+ }
36
+ async _prepareReconnectSocket() {
37
+ if (!this._client._hasApiKeyProvider()) {
38
+ return super._prepareReconnectSocket();
37
39
  }
38
- const ws = new WS.WebSocket(url, socketOptions);
39
- return new NodeWebSocket(ws);
40
+ return this._credentials.prepare(this._client, snapshotNodeWebSocketOptions(this._wsOptions), (...args) => this._authHeaders(...args), (url, headers) => this._createSocket(url, headers));
40
41
  }
41
42
  }
42
43
  //# sourceMappingURL=ws.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws.mjs","sourceRoot":"","sources":["../../src/resources/responses/ws.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,2CAAuC;AAC/D,OAAO,EAAE,eAAe,EAA+B,sBAAkB;AAEzE,OAAO,EAAE,WAAW,EAAE,6BAAyB;AAC/C,OAAO,EAAE,4BAA4B,EAAE,8BAA0B;AAWjE,MAAM,OAAO,WAAY,SAAQ,eAA8B;IAG7D,YAAY,MAAc,EAAE,OAAqD;QAC/E,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,wGAAwG,CACzG,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAChE,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAES,aAAa,CAAC,GAAQ,EAAE,WAAmC;QACnE,MAAM,mBAAmB,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAClG,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;YAC3E,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACrC,CAAC;iBAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QACD,MAAM,aAAa,GAA6B;YAC9C,GAAG,IAAI,CAAC,UAAU;YAClB,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;YACpC,eAAe,EAAE,KAAK;SACvB,CAAC;QACF,IACE,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACjC,CAAC,mBAAmB,CAAC,eAAe,CAAC;YACrC,CAAC,4BAA4B,CAAC,aAAa,CAAC,EAC5C,CAAC;YACD,MAAM,IAAI,WAAW,CACnB,qKAAqK,CACtK,CAAC;QACJ,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAChD,OAAO,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;CACF"}
1
+ {"version":3,"file":"ws.mjs","sourceRoot":"","sources":["../../src/resources/responses/ws.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,4BAA4B,EAAE,2CAAuC;AAC7F,OAAO,EAAE,eAAe,EAA+B,sBAAkB;AAEzE,OAAO,EAAE,6BAA6B,EAAE,oDAAgD;AAWxF,MAAM,OAAO,WAAY,SAAQ,eAA8B;IAI7D,YAAY,MAAc,EAAE,OAAqD;QAC/E,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,wGAAwG,CACzG,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAChE,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;QATrC,iBAAY,GAAG,IAAI,6BAA6B,EAAE,CAAC;QAUzD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEkB,YAAY,CAAC,MAAsB;QACpD,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACrG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACO,cAAc,CAAC,WAAmC;QAC1D,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAES,aAAa,CAAC,GAAQ,EAAE,WAAmC;QACnE,MAAM,mBAAmB,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;QAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAC3C,IAAI,CAAC,OAAO,EACZ,mBAAmB,EACnB,IAAI,CAAC,UAAU,EACf,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS,CACpE,CAAC;QACF,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IACjE,CAAC;IAEkB,KAAK,CAAC,uBAAuB;QAC9C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC,uBAAuB,EAAE,CAAC;QACzC,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAC9B,IAAI,CAAC,OAAO,EACZ,4BAA4B,CAAC,IAAI,CAAC,UAAU,CAAC,EAC7C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,EACvC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CACnD,CAAC;IACJ,CAAC;CACF"}
package/src/client.ts CHANGED
@@ -48,7 +48,11 @@ import {
48
48
  import * as Uploads from './core/uploads';
49
49
  import * as API from './resources/index';
50
50
  import { APIPromise } from './core/api-promise';
51
- import { resolveRealtimeAPIKey } from './internal/realtime-credentials';
51
+ import {
52
+ getDeferredRealtimeAPIKeyCache,
53
+ resolveRealtimeAPIKey,
54
+ validateCapturedAPIKey,
55
+ } from './internal/realtime-credentials';
52
56
  import {
53
57
  Batch,
54
58
  BatchCreateParams,
@@ -258,6 +262,7 @@ import {
258
262
  import { type Fetch } from './internal/builtin-types';
259
263
  import { isRunningInBrowser } from './internal/detect-platform';
260
264
  import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
265
+ import { mergeWebSocketAuthHeaders, webSocketHeaderRemovals } from './internal/ws';
261
266
  import { configureProvider, type Provider, type ProviderRuntime } from './internal/provider';
262
267
  import { FinalRequestOptions, RequestOptions } from './internal/request-options';
263
268
  import { readEnv } from './internal/utils/env';
@@ -490,6 +495,8 @@ export class OpenAI {
490
495
  protected idempotencyHeader?: string;
491
496
  protected _options: ClientOptions;
492
497
  private _provider: ProviderRuntime | undefined;
498
+ private _apiKeyInvocation = 0;
499
+ private _lastCachedAPIKeyInvocation = 0;
493
500
  private _workloadIdentityAuth?: WorkloadIdentityAuth | X509WorkloadIdentityAuth;
494
501
 
495
502
  /**
@@ -741,18 +748,33 @@ export class OpenAI {
741
748
  }
742
749
 
743
750
  /** @internal Client request headers for each new WebSocket handshake. */
744
- _buildWebSocketHeaders(authHeaders: Record<string, string>): Record<string, string> {
745
- return Object.fromEntries(
746
- buildHeaders([
747
- {
748
- 'User-Agent': this.getUserAgent(),
749
- 'OpenAI-Organization': this.organization,
750
- 'OpenAI-Project': this.project,
751
- },
751
+ _buildWebSocketHeaders(
752
+ authHeaders: Record<string, string>,
753
+ removedHeaders?: Set<string>,
754
+ ): Record<string, string> {
755
+ const context = webSocketHeaderRemovals.get(this);
756
+ if (context?.baseHeaders) {
757
+ return mergeWebSocketAuthHeaders(
758
+ { headers: context.baseHeaders },
752
759
  authHeaders,
753
- this._options.defaultHeaders,
754
- ]).values,
755
- );
760
+ context.removedHeaders ?? new Set(),
761
+ ).headers;
762
+ }
763
+ const headers = buildHeaders([
764
+ {
765
+ 'User-Agent': this.getUserAgent(),
766
+ 'OpenAI-Organization': this.organization,
767
+ 'OpenAI-Project': this.project,
768
+ },
769
+ authHeaders,
770
+ this._options.defaultHeaders,
771
+ ]);
772
+ headers.nulls.forEach((name) => (removedHeaders ?? context?.removedHeaders)?.add(name));
773
+ const result = Object.fromEntries(headers.values);
774
+ if (context) {
775
+ context.baseHeaders = { ...result };
776
+ }
777
+ return result;
756
778
  }
757
779
 
758
780
  protected validateHeaders(
@@ -877,11 +899,8 @@ export class OpenAI {
877
899
  }
878
900
 
879
901
  /**
880
- * Resolves a function-based API key and retains the resolved value on this client.
881
- * Returns whether a provider was invoked. Internal callers can capture this
882
- * invocation's key before another request updates the shared `apiKey` property.
883
- * Overrides should forward `capture` or invoke it with their own resolved key
884
- * to preserve invocation-local credentials in concurrent requests and Realtime factories.
902
+ * Resolves and retains a provider key, returning whether a provider was invoked.
903
+ * Overrides should forward `capture` (or call it with their resolved key) for local credentials.
885
904
  * @internal
886
905
  */
887
906
  async _callApiKey(capture?: (apiKey: string | null) => void): Promise<boolean> {
@@ -896,6 +915,8 @@ export class OpenAI {
896
915
  return false;
897
916
  }
898
917
 
918
+ const deferredCache = getDeferredRealtimeAPIKeyCache(this);
919
+ const invocation = ++this._apiKeyInvocation;
899
920
  let token: unknown;
900
921
  try {
901
922
  token = await apiKey();
@@ -913,8 +934,23 @@ export class OpenAI {
913
934
  `Expected 'apiKey' function argument to return a string but it returned ${token}`,
914
935
  );
915
936
  }
916
- this.apiKey = token;
917
- capture?.(this.apiKey);
937
+ const resolvedToken = token;
938
+ const commit = () => {
939
+ if (capture) validateCapturedAPIKey(this, resolvedToken);
940
+ if (invocation < this._lastCachedAPIKeyInvocation) {
941
+ return resolvedToken;
942
+ }
943
+ this.apiKey = resolvedToken;
944
+ const cached = capture ? this.apiKey : resolvedToken;
945
+ this._lastCachedAPIKeyInvocation = invocation;
946
+ return cached;
947
+ };
948
+ if (deferredCache) {
949
+ deferredCache.providerKey = resolvedToken;
950
+ deferredCache.commit = commit;
951
+ }
952
+ const cached = deferredCache ? validateCapturedAPIKey(this, resolvedToken) : commit();
953
+ capture?.(cached);
918
954
  return true;
919
955
  }
920
956
 
@@ -301,6 +301,15 @@ export class Stream<Item> implements AsyncIterable<Item> {
301
301
  return this.iterator();
302
302
  }
303
303
 
304
+ /** Beta-only iterator decoration for Agents helpers, preserving custom stream identity.
305
+ * @internal
306
+ */
307
+ __betaTransformIterator(
308
+ transform: (iterator: () => AsyncIterator<Item>) => () => AsyncIterator<Item>,
309
+ ): void {
310
+ this.iterator = transform(this.iterator.bind(this));
311
+ }
312
+
304
313
  /**
305
314
  * Splits the stream into two streams which can be
306
315
  * independently read from at different speeds.
@@ -0,0 +1,13 @@
1
+ import { standardTextFormat } from '../../standard-schema';
2
+ import type { JSONSchema } from '../../../lib/jsonschema';
3
+ import { agentOutputFormat } from '../../../lib/beta/agents/output-format';
4
+
5
+ /** Beta: bind a synchronous Standard Schema validator to Agents output. */
6
+ export function standardAgentTextFormat<S extends Parameters<typeof standardTextFormat>[0]>(
7
+ schema: S,
8
+ jsonSchema?: JSONSchema,
9
+ ) {
10
+ const format = standardTextFormat(schema, 'agent_output', { schema: jsonSchema });
11
+ // SAFETY: The native Responses helper owns Standard Schema conversion and validation.
12
+ return agentOutputFormat(format.schema as JSONSchema, format.$parseRaw);
13
+ }
@@ -0,0 +1,10 @@
1
+ import { zodTextFormat } from '../../zod';
2
+ import type { JSONSchema } from '../../../lib/jsonschema';
3
+ import { agentOutputFormat } from '../../../lib/beta/agents/output-format';
4
+
5
+ /** Beta: bind a Zod v3/v4/Mini schema to an Agents text format and completed result. */
6
+ export function zodAgentTextFormat<S extends Parameters<typeof zodTextFormat>[0]>(schema: S) {
7
+ const format = zodTextFormat(schema, 'agent_output');
8
+ // SAFETY: The native Responses helper owns Zod schema conversion and validation.
9
+ return agentOutputFormat(format.schema as JSONSchema, format.$parseRaw);
10
+ }
@@ -1,4 +1,44 @@
1
1
  import type { OpenAI } from '../client';
2
+ import { assertValidBedrockBearerCredential, brand_privateBedrockClient } from './bedrock';
3
+
4
+ type CaptureAPIKey = (apiKey: string | null) => void;
5
+ export interface DeferredAPIKeyCache {
6
+ client: Pick<OpenAI, 'apiKey'>;
7
+ providerKey?: string;
8
+ commit: () => string | null;
9
+ }
10
+ interface RealtimeAPIKeyCacheContext {
11
+ run: <T>(cache: DeferredAPIKeyCache | undefined, operation: () => T) => T;
12
+ getStore: () => DeferredAPIKeyCache | undefined;
13
+ }
14
+ // Only the key crosses module formats: the context belongs to each participating client.
15
+ const realtimeCacheContext = Symbol.for('openai.realtimeAPIKeyCacheContext');
16
+ type CredentialClient = Pick<OpenAI, 'apiKey'> & {
17
+ [realtimeCacheContext]?: RealtimeAPIKeyCacheContext;
18
+ };
19
+ let cacheContext: RealtimeAPIKeyCacheContext | undefined;
20
+
21
+ /** Installs the Node transport's invocation context without loading Node in the base client. @internal */
22
+ export function setRealtimeAPIKeyCacheContext(context: RealtimeAPIKeyCacheContext): void {
23
+ cacheContext = context;
24
+ }
25
+
26
+ /** Reserves a deferred commit when the base hook is entered for this invocation. @internal */
27
+ export function getDeferredRealtimeAPIKeyCache(client: CredentialClient): DeferredAPIKeyCache | undefined {
28
+ const deferred = client[realtimeCacheContext]?.getStore();
29
+ return deferred?.client === client ? deferred : undefined;
30
+ }
31
+
32
+ /** Applies the Bedrock getter's validation when a captured credential does not enter the cache. @internal */
33
+ export function validateCapturedAPIKey(
34
+ client: Pick<OpenAI, 'apiKey'>,
35
+ credential: string | null,
36
+ ): string | null {
37
+ if (credential !== null && brand_privateBedrockClient in client) {
38
+ assertValidBedrockBearerCredential(credential);
39
+ }
40
+ return credential;
41
+ }
2
42
 
3
43
  /** Selects a captured credential without treating an explicit null as absent. @internal */
4
44
  export function getRealtimeAPIKey(
@@ -15,13 +55,39 @@ export function getRealtimeAPIKey(
15
55
  * synchronizing concurrent credential updates.
16
56
  * @internal
17
57
  */
18
- export async function resolveRealtimeAPIKey(client: Pick<OpenAI, 'apiKey' | '_callApiKey'>): Promise<{
58
+ export async function resolveRealtimeAPIKey(
59
+ client: CredentialClient & Pick<OpenAI, '_callApiKey'>,
60
+ deferCache = false,
61
+ ): Promise<{
19
62
  apiKey: string | null;
20
63
  isProvider: boolean;
64
+ commit: () => string | null;
21
65
  }> {
22
66
  let apiKey: string | null | undefined;
23
- const isProvider = await client._callApiKey((resolved) => {
67
+ const current: DeferredAPIKeyCache = {
68
+ client,
69
+ commit: () => (apiKey === undefined ? client.apiKey : apiKey),
70
+ };
71
+ const capture: CaptureAPIKey = (resolved) => {
24
72
  apiKey = resolved;
25
- });
26
- return { apiKey: apiKey === undefined ? client.apiKey : apiKey, isProvider };
73
+ };
74
+ const invoke = () => client._callApiKey(capture);
75
+ const context = client[realtimeCacheContext] ?? cacheContext;
76
+ if (deferCache && context && !client[realtimeCacheContext]) {
77
+ Object.defineProperty(client, realtimeCacheContext, { value: context });
78
+ }
79
+ // An HTTP or ordinary Realtime request nested inside a WebSocket hook owns its own cache writes.
80
+ const isProvider = await (context ? context.run(deferCache ? current : undefined, invoke) : invoke());
81
+ return {
82
+ apiKey: apiKey === undefined ? client.apiKey : apiKey,
83
+ isProvider,
84
+ commit: () => {
85
+ const hookKey =
86
+ current.providerKey !== undefined && apiKey !== undefined && apiKey !== current.providerKey
87
+ ? validateCapturedAPIKey(client, apiKey)
88
+ : undefined;
89
+ const cached = current.commit();
90
+ return hookKey === undefined ? validateCapturedAPIKey(client, cached) : hookKey;
91
+ },
92
+ };
27
93
  }
@@ -0,0 +1,160 @@
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 buildResponsesWebSocketOptions<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 prepareResponsesWebSocketReconnect<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 Responses credential state shared by the stable and beta Node transports. */
68
+ export class ResponsesWebSocketCredentials {
69
+ private initialAuthUsedAPIKey = false;
70
+ private initialAPIKey: string | undefined;
71
+ private prepared:
72
+ | {
73
+ options: ReturnType<typeof buildWebSocketOptions>;
74
+ removedHeaders: Set<string>;
75
+ apiKey?: string | null | undefined;
76
+ }
77
+ | undefined;
78
+
79
+ get preparedAPIKey(): string | null | undefined {
80
+ return this.prepared?.apiKey;
81
+ }
82
+
83
+ trackInitialHeaders(client: OpenAI, headers: Record<string, string>, hasSocket: () => boolean): void {
84
+ if (!hasSocket() && client._hasApiKeyProvider()) {
85
+ this.initialAPIKey = headers['Authorization']?.slice('Bearer '.length);
86
+ }
87
+ }
88
+
89
+ usesAPIKey(client: OpenAI, headers: Record<string, string>): boolean {
90
+ // Hooks can read the SDK key without delegating. Only use an ordinary cached property here:
91
+ // invoking custom/Bedrock getters could validate credentials a caller-owned socket never sends.
92
+ const apiKey =
93
+ this.initialAPIKey ??
94
+ (client._hasApiKeyProvider() ? Object.getOwnPropertyDescriptor(client, 'apiKey')?.value : undefined);
95
+ if (!apiKey) {
96
+ return false;
97
+ }
98
+ // Metadata containing a copy of a credential does not make it the socket's authentication.
99
+ return snapshotWebSocketCredentials(
100
+ {
101
+ headers: Object.fromEntries(
102
+ Object.entries(headers).map(([name, value]) => [name, value?.includes(apiKey) ? value : '']),
103
+ ),
104
+ },
105
+ WEBSOCKET_METADATA_HEADERS,
106
+ );
107
+ }
108
+
109
+ build<Options extends CredentialedWebSocketOptions>(
110
+ client: OpenAI,
111
+ authHeaders: Record<string, string>,
112
+ options: Options | null | undefined,
113
+ initialAuthUsedAPIKey?: boolean,
114
+ ) {
115
+ if (initialAuthUsedAPIKey !== undefined) {
116
+ this.initialAuthUsedAPIKey = initialAuthUsedAPIKey;
117
+ this.initialAPIKey = undefined;
118
+ }
119
+ const socketOptions = buildResponsesWebSocketOptions(client, authHeaders, options, this.prepared);
120
+ if (
121
+ client._hasApiKeyProvider() &&
122
+ !authHeaders['Authorization'] &&
123
+ !snapshotWebSocketCredentials(socketOptions, WEBSOCKET_METADATA_HEADERS)
124
+ ) {
125
+ throw new OpenAIError(
126
+ 'Cannot open a Responses WebSocket with an unresolved function-based apiKey. Resolve it before constructing the WebSocket or provide explicit WebSocket credentials.',
127
+ );
128
+ }
129
+ return socketOptions;
130
+ }
131
+
132
+ async prepare<Socket, Options extends CredentialedWebSocketOptions>(
133
+ client: OpenAI,
134
+ socketOptions: Options | null | undefined,
135
+ authHeaders: (apiKey?: string | null) => Record<string, string>,
136
+ createSocket: (url: URL, headers: Record<string, string>) => Socket,
137
+ ): Promise<(url: URL) => Socket> {
138
+ const { options, removedHeaders, authentication } = prepareResponsesWebSocketReconnect(
139
+ client,
140
+ socketOptions,
141
+ this.initialAuthUsedAPIKey,
142
+ );
143
+ const createPreparedSocket = (url: URL, headers: Record<string, string>, apiKey?: string | null) => {
144
+ const previous = this.prepared;
145
+ this.prepared = { options, removedHeaders, apiKey };
146
+ try {
147
+ // Resolve headers inside the scope so legacy zero-argument overrides see this attempt's key.
148
+ return createSocket(url, apiKey === undefined ? headers : authHeaders(apiKey));
149
+ } finally {
150
+ this.prepared = previous;
151
+ }
152
+ };
153
+ if (authentication !== 'refresh') {
154
+ const headers = authentication === 'provided' ? {} : authHeaders();
155
+ return (url) => createPreparedSocket(url, headers);
156
+ }
157
+ const { commit } = await resolveRealtimeAPIKey(client, true);
158
+ return (url) => createPreparedSocket(url, {}, commit());
159
+ }
160
+ }
@@ -1,10 +1,76 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
1
2
  import type * as WS from 'ws';
2
3
  import type { WebSocketLike } from './ws-adapter';
3
4
  import { protectWebSocketOptionsFromCredentialRedirects } from './ws';
5
+ import { setRealtimeAPIKeyCacheContext } from './realtime-credentials';
6
+ import type { DeferredAPIKeyCache } from './realtime-credentials';
7
+
8
+ setRealtimeAPIKeyCacheContext(new AsyncLocalStorage<DeferredAPIKeyCache | undefined>());
4
9
 
5
10
  /** A generic event listener callback. */
6
11
  type Listener = (...args: any[]) => void;
7
12
 
13
+ function copyTLSMaterial(value: string | Buffer): string | Buffer {
14
+ return ArrayBuffer.isView(value)
15
+ ? Buffer.from(new Uint8Array(value.buffer, value.byteOffset, value.byteLength))
16
+ : value;
17
+ }
18
+
19
+ /** Snapshot caller headers and TLS identity before an async reconnect credential refresh. */
20
+ export function snapshotNodeWebSocketOptions(
21
+ options: WS.ClientOptions | null | undefined,
22
+ ): Omit<WS.ClientOptions, 'headers'> & { headers: Record<string, string | string[]> } {
23
+ const captured = {
24
+ ...options,
25
+ headers: Object.fromEntries(
26
+ Object.entries(options?.headers ?? {}).map(([name, value]) => [
27
+ name,
28
+ Array.isArray(value) ? [...value] : value,
29
+ ]),
30
+ ),
31
+ };
32
+ const { ca, cert, crl, key, pfx } = captured;
33
+ if (ca !== undefined) {
34
+ captured.ca = Array.isArray(ca) ? ca.map(copyTLSMaterial) : copyTLSMaterial(ca);
35
+ }
36
+ if (cert !== undefined) {
37
+ captured.cert = Array.isArray(cert) ? cert.map(copyTLSMaterial) : copyTLSMaterial(cert);
38
+ }
39
+ if (crl !== undefined) {
40
+ captured.crl = Array.isArray(crl) ? crl.map(copyTLSMaterial) : copyTLSMaterial(crl);
41
+ }
42
+ if (key !== undefined) {
43
+ captured.key = Array.isArray(key)
44
+ ? key.map((value) =>
45
+ typeof value === 'string' || ArrayBuffer.isView(value)
46
+ ? copyTLSMaterial(value)
47
+ : { ...value, pem: copyTLSMaterial(value.pem) },
48
+ )
49
+ : copyTLSMaterial(key);
50
+ }
51
+ if (pfx !== undefined) {
52
+ captured.pfx = Array.isArray(pfx)
53
+ ? pfx.map((value) =>
54
+ typeof value === 'string' || ArrayBuffer.isView(value)
55
+ ? copyTLSMaterial(value)
56
+ : { ...value, buf: copyTLSMaterial(value.buf) },
57
+ )
58
+ : copyTLSMaterial(pfx);
59
+ }
60
+ if ('session' in captured && Buffer.isBuffer(captured.session)) {
61
+ captured.session = Buffer.from(captured.session);
62
+ }
63
+ if ('ALPNProtocols' in captured) {
64
+ if (Array.isArray(captured.ALPNProtocols)) {
65
+ captured.ALPNProtocols = [...captured.ALPNProtocols];
66
+ } else if (ArrayBuffer.isView(captured.ALPNProtocols)) {
67
+ const { buffer, byteOffset, byteLength } = captured.ALPNProtocols;
68
+ captured.ALPNProtocols = Buffer.from(new Uint8Array(buffer, byteOffset, byteLength));
69
+ }
70
+ }
71
+ return captured;
72
+ }
73
+
8
74
  /**
9
75
  * Adapts a Node.js `ws` socket to the SDK's platform-neutral WebSocket API.
10
76
  *