openai 7.5.0 → 7.7.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 (597) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/README.md +46 -2
  3. package/auth/index.d.mts +1 -1
  4. package/auth/index.d.mts.map +1 -1
  5. package/auth/index.d.ts +1 -1
  6. package/auth/index.d.ts.map +1 -1
  7. package/auth/index.js.map +1 -1
  8. package/auth/index.mjs.map +1 -1
  9. package/auth/subject-token-providers.d.mts.map +1 -1
  10. package/auth/subject-token-providers.d.ts.map +1 -1
  11. package/auth/subject-token-providers.js +176 -4
  12. package/auth/subject-token-providers.js.map +1 -1
  13. package/auth/subject-token-providers.mjs +176 -4
  14. package/auth/subject-token-providers.mjs.map +1 -1
  15. package/auth/types.d.mts +17 -0
  16. package/auth/types.d.mts.map +1 -1
  17. package/auth/types.d.ts +17 -0
  18. package/auth/types.d.ts.map +1 -1
  19. package/auth/workload-identity-auth.d.mts.map +1 -1
  20. package/auth/workload-identity-auth.d.ts.map +1 -1
  21. package/auth/workload-identity-auth.js +80 -7
  22. package/auth/workload-identity-auth.js.map +1 -1
  23. package/auth/workload-identity-auth.mjs +80 -7
  24. package/auth/workload-identity-auth.mjs.map +1 -1
  25. package/auth/x509-transport.d.mts +5 -0
  26. package/auth/x509-transport.d.mts.map +1 -0
  27. package/auth/x509-transport.d.ts +5 -0
  28. package/auth/x509-transport.d.ts.map +1 -0
  29. package/auth/x509-transport.js +39 -0
  30. package/auth/x509-transport.js.map +1 -0
  31. package/auth/x509-transport.mjs +36 -0
  32. package/auth/x509-transport.mjs.map +1 -0
  33. package/azure.d.mts +11 -2
  34. package/azure.d.mts.map +1 -1
  35. package/azure.d.ts +11 -2
  36. package/azure.d.ts.map +1 -1
  37. package/azure.js +7 -1
  38. package/azure.js.map +1 -1
  39. package/azure.mjs +7 -1
  40. package/azure.mjs.map +1 -1
  41. package/bedrock.d.mts +6 -2
  42. package/bedrock.d.mts.map +1 -1
  43. package/bedrock.d.ts +6 -2
  44. package/bedrock.d.ts.map +1 -1
  45. package/bedrock.js +34 -4
  46. package/bedrock.js.map +1 -1
  47. package/bedrock.mjs +35 -5
  48. package/bedrock.mjs.map +1 -1
  49. package/beta/realtime/internal-base.d.mts +2 -0
  50. package/beta/realtime/internal-base.d.mts.map +1 -1
  51. package/beta/realtime/internal-base.d.ts +2 -0
  52. package/beta/realtime/internal-base.d.ts.map +1 -1
  53. package/beta/realtime/internal-base.js +15 -0
  54. package/beta/realtime/internal-base.js.map +1 -1
  55. package/beta/realtime/internal-base.mjs +14 -0
  56. package/beta/realtime/internal-base.mjs.map +1 -1
  57. package/beta/realtime/websocket.d.mts +11 -5
  58. package/beta/realtime/websocket.d.mts.map +1 -1
  59. package/beta/realtime/websocket.d.ts +11 -5
  60. package/beta/realtime/websocket.d.ts.map +1 -1
  61. package/beta/realtime/websocket.js +106 -31
  62. package/beta/realtime/websocket.js.map +1 -1
  63. package/beta/realtime/websocket.mjs +107 -32
  64. package/beta/realtime/websocket.mjs.map +1 -1
  65. package/beta/realtime/ws.d.mts +0 -2
  66. package/beta/realtime/ws.d.mts.map +1 -1
  67. package/beta/realtime/ws.d.ts +0 -2
  68. package/beta/realtime/ws.d.ts.map +1 -1
  69. package/beta/realtime/ws.js +24 -5
  70. package/beta/realtime/ws.js.map +1 -1
  71. package/beta/realtime/ws.mjs +25 -6
  72. package/beta/realtime/ws.mjs.map +1 -1
  73. package/client.d.mts +17 -2
  74. package/client.d.mts.map +1 -1
  75. package/client.d.ts +17 -2
  76. package/client.d.ts.map +1 -1
  77. package/client.js +422 -70
  78. package/client.js.map +1 -1
  79. package/client.mjs +423 -71
  80. package/client.mjs.map +1 -1
  81. package/core/EventEmitter.d.mts.map +1 -1
  82. package/core/EventEmitter.d.ts.map +1 -1
  83. package/core/EventEmitter.js +67 -9
  84. package/core/EventEmitter.js.map +1 -1
  85. package/core/EventEmitter.mjs +68 -10
  86. package/core/EventEmitter.mjs.map +1 -1
  87. package/core/streaming.d.mts +1 -0
  88. package/core/streaming.d.mts.map +1 -1
  89. package/core/streaming.d.ts +1 -0
  90. package/core/streaming.d.ts.map +1 -1
  91. package/core/streaming.js +216 -26
  92. package/core/streaming.js.map +1 -1
  93. package/core/streaming.mjs +216 -26
  94. package/core/streaming.mjs.map +1 -1
  95. package/helpers/audio.d.mts +5 -5
  96. package/helpers/audio.d.mts.map +1 -1
  97. package/helpers/audio.d.ts +5 -5
  98. package/helpers/audio.d.ts.map +1 -1
  99. package/helpers/audio.js +93 -22
  100. package/helpers/audio.js.map +1 -1
  101. package/helpers/audio.mjs +93 -22
  102. package/helpers/audio.mjs.map +1 -1
  103. package/helpers/standard-schema.d.mts.map +1 -1
  104. package/helpers/standard-schema.d.ts.map +1 -1
  105. package/helpers/standard-schema.js +34 -14
  106. package/helpers/standard-schema.js.map +1 -1
  107. package/helpers/standard-schema.mjs +35 -15
  108. package/helpers/standard-schema.mjs.map +1 -1
  109. package/helpers/zod-v3-strict-schema.d.mts +7 -0
  110. package/helpers/zod-v3-strict-schema.d.mts.map +1 -0
  111. package/helpers/zod-v3-strict-schema.d.ts +7 -0
  112. package/helpers/zod-v3-strict-schema.d.ts.map +1 -0
  113. package/helpers/zod-v3-strict-schema.js +403 -0
  114. package/helpers/zod-v3-strict-schema.js.map +1 -0
  115. package/helpers/zod-v3-strict-schema.mjs +399 -0
  116. package/helpers/zod-v3-strict-schema.mjs.map +1 -0
  117. package/helpers/zod.d.mts.map +1 -1
  118. package/helpers/zod.d.ts.map +1 -1
  119. package/helpers/zod.js +11 -3
  120. package/helpers/zod.js.map +1 -1
  121. package/helpers/zod.mjs +12 -4
  122. package/helpers/zod.mjs.map +1 -1
  123. package/index.d.mts +1 -1
  124. package/index.d.mts.map +1 -1
  125. package/index.d.ts +1 -1
  126. package/index.d.ts.map +1 -1
  127. package/index.js.map +1 -1
  128. package/index.mjs.map +1 -1
  129. package/internal/assistant-stream-delta.d.mts.map +1 -1
  130. package/internal/assistant-stream-delta.d.ts.map +1 -1
  131. package/internal/assistant-stream-delta.js +28 -8
  132. package/internal/assistant-stream-delta.js.map +1 -1
  133. package/internal/assistant-stream-delta.mjs +28 -8
  134. package/internal/assistant-stream-delta.mjs.map +1 -1
  135. package/internal/auth/x509-token-exchange.d.mts +16 -0
  136. package/internal/auth/x509-token-exchange.d.mts.map +1 -0
  137. package/internal/auth/x509-token-exchange.d.ts +16 -0
  138. package/internal/auth/x509-token-exchange.d.ts.map +1 -0
  139. package/internal/auth/x509-token-exchange.js +246 -0
  140. package/internal/auth/x509-token-exchange.js.map +1 -0
  141. package/internal/auth/x509-token-exchange.mjs +243 -0
  142. package/internal/auth/x509-token-exchange.mjs.map +1 -0
  143. package/internal/auth/x509-transport-capability.d.mts +37 -0
  144. package/internal/auth/x509-transport-capability.d.mts.map +1 -0
  145. package/internal/auth/x509-transport-capability.d.ts +37 -0
  146. package/internal/auth/x509-transport-capability.d.ts.map +1 -0
  147. package/internal/auth/x509-transport-capability.js +169 -0
  148. package/internal/auth/x509-transport-capability.js.map +1 -0
  149. package/internal/auth/x509-transport-capability.mjs +164 -0
  150. package/internal/auth/x509-transport-capability.mjs.map +1 -0
  151. package/internal/auth/x509-transport-registry.d.mts +63 -0
  152. package/internal/auth/x509-transport-registry.d.mts.map +1 -0
  153. package/internal/auth/x509-transport-registry.d.ts +63 -0
  154. package/internal/auth/x509-transport-registry.d.ts.map +1 -0
  155. package/internal/auth/x509-transport-registry.js +53 -0
  156. package/internal/auth/x509-transport-registry.js.map +1 -0
  157. package/internal/auth/x509-transport-registry.mjs +48 -0
  158. package/internal/auth/x509-transport-registry.mjs.map +1 -0
  159. package/internal/auth/x509-transport-state-browser.d.mts +21 -0
  160. package/internal/auth/x509-transport-state-browser.d.mts.map +1 -0
  161. package/internal/auth/x509-transport-state-browser.d.ts +21 -0
  162. package/internal/auth/x509-transport-state-browser.d.ts.map +1 -0
  163. package/internal/auth/x509-transport-state-browser.js +30 -0
  164. package/internal/auth/x509-transport-state-browser.js.map +1 -0
  165. package/internal/auth/x509-transport-state-browser.mjs +27 -0
  166. package/internal/auth/x509-transport-state-browser.mjs.map +1 -0
  167. package/internal/auth/x509-transport-state.cjs +30 -0
  168. package/internal/auth/x509-transport-state.cjs.map +1 -0
  169. package/internal/auth/x509-transport-state.d.cts +21 -0
  170. package/internal/auth/x509-transport-state.d.cts.map +1 -0
  171. package/internal/auth/x509-workload-identity-auth.d.mts +128 -0
  172. package/internal/auth/x509-workload-identity-auth.d.mts.map +1 -0
  173. package/internal/auth/x509-workload-identity-auth.d.ts +128 -0
  174. package/internal/auth/x509-workload-identity-auth.d.ts.map +1 -0
  175. package/internal/auth/x509-workload-identity-auth.js +767 -0
  176. package/internal/auth/x509-workload-identity-auth.js.map +1 -0
  177. package/internal/auth/x509-workload-identity-auth.mjs +757 -0
  178. package/internal/auth/x509-workload-identity-auth.mjs.map +1 -0
  179. package/internal/bedrock.d.mts +2 -0
  180. package/internal/bedrock.d.mts.map +1 -1
  181. package/internal/bedrock.d.ts +2 -0
  182. package/internal/bedrock.d.ts.map +1 -1
  183. package/internal/bedrock.js +169 -5
  184. package/internal/bedrock.js.map +1 -1
  185. package/internal/bedrock.mjs +168 -5
  186. package/internal/bedrock.mjs.map +1 -1
  187. package/internal/data-residency.d.mts +12 -0
  188. package/internal/data-residency.d.mts.map +1 -0
  189. package/internal/data-residency.d.ts +12 -0
  190. package/internal/data-residency.d.ts.map +1 -0
  191. package/internal/data-residency.js +34 -0
  192. package/internal/data-residency.js.map +1 -0
  193. package/internal/data-residency.mjs +30 -0
  194. package/internal/data-residency.mjs.map +1 -0
  195. package/internal/multipart-encoding.d.mts +8 -0
  196. package/internal/multipart-encoding.d.mts.map +1 -0
  197. package/internal/multipart-encoding.d.ts +8 -0
  198. package/internal/multipart-encoding.d.ts.map +1 -0
  199. package/internal/multipart-encoding.js +51 -0
  200. package/internal/multipart-encoding.js.map +1 -0
  201. package/internal/multipart-encoding.mjs +48 -0
  202. package/internal/multipart-encoding.mjs.map +1 -0
  203. package/internal/qs/utils.d.mts.map +1 -1
  204. package/internal/qs/utils.d.ts.map +1 -1
  205. package/internal/qs/utils.js +307 -10
  206. package/internal/qs/utils.js.map +1 -1
  207. package/internal/qs/utils.mjs +307 -10
  208. package/internal/qs/utils.mjs.map +1 -1
  209. package/internal/request-options.d.mts +7 -0
  210. package/internal/request-options.d.mts.map +1 -1
  211. package/internal/request-options.d.ts +7 -0
  212. package/internal/request-options.d.ts.map +1 -1
  213. package/internal/request-options.js +43 -1
  214. package/internal/request-options.js.map +1 -1
  215. package/internal/request-options.mjs +42 -1
  216. package/internal/request-options.mjs.map +1 -1
  217. package/internal/responses/canonical-output-text.js +3 -3
  218. package/internal/responses/canonical-output-text.js.map +1 -1
  219. package/internal/responses/canonical-output-text.mjs +3 -3
  220. package/internal/responses/canonical-output-text.mjs.map +1 -1
  221. package/internal/responses/response-accumulator.d.mts +1 -1
  222. package/internal/responses/response-accumulator.d.mts.map +1 -1
  223. package/internal/responses/response-accumulator.d.ts +1 -1
  224. package/internal/responses/response-accumulator.d.ts.map +1 -1
  225. package/internal/responses/response-accumulator.js +331 -25
  226. package/internal/responses/response-accumulator.js.map +1 -1
  227. package/internal/responses/response-accumulator.mjs +331 -25
  228. package/internal/responses/response-accumulator.mjs.map +1 -1
  229. package/internal/tslib.js +6 -0
  230. package/internal/tslib.mjs +6 -1
  231. package/internal/uploads.d.mts +10 -6
  232. package/internal/uploads.d.mts.map +1 -1
  233. package/internal/uploads.d.ts +10 -6
  234. package/internal/uploads.d.ts.map +1 -1
  235. package/internal/uploads.js +65 -24
  236. package/internal/uploads.js.map +1 -1
  237. package/internal/uploads.mjs +65 -24
  238. package/internal/uploads.mjs.map +1 -1
  239. package/internal/utils/env.d.mts.map +1 -1
  240. package/internal/utils/env.d.ts.map +1 -1
  241. package/internal/utils/env.js +9 -4
  242. package/internal/utils/env.js.map +1 -1
  243. package/internal/utils/env.mjs +9 -4
  244. package/internal/utils/env.mjs.map +1 -1
  245. package/internal/ws.d.mts.map +1 -1
  246. package/internal/ws.d.ts.map +1 -1
  247. package/internal/ws.js +23 -1
  248. package/internal/ws.js.map +1 -1
  249. package/internal/ws.mjs +23 -1
  250. package/internal/ws.mjs.map +1 -1
  251. package/lib/AbstractChatCompletionRunner.d.mts.map +1 -1
  252. package/lib/AbstractChatCompletionRunner.d.ts.map +1 -1
  253. package/lib/AbstractChatCompletionRunner.js +32 -7
  254. package/lib/AbstractChatCompletionRunner.js.map +1 -1
  255. package/lib/AbstractChatCompletionRunner.mjs +34 -9
  256. package/lib/AbstractChatCompletionRunner.mjs.map +1 -1
  257. package/lib/AssistantStream.d.mts.map +1 -1
  258. package/lib/AssistantStream.d.ts.map +1 -1
  259. package/lib/AssistantStream.js +211 -23
  260. package/lib/AssistantStream.js.map +1 -1
  261. package/lib/AssistantStream.mjs +211 -23
  262. package/lib/AssistantStream.mjs.map +1 -1
  263. package/lib/ChatCompletionStream.d.mts +1 -1
  264. package/lib/ChatCompletionStream.d.mts.map +1 -1
  265. package/lib/ChatCompletionStream.d.ts +1 -1
  266. package/lib/ChatCompletionStream.d.ts.map +1 -1
  267. package/lib/ChatCompletionStream.js +1118 -67
  268. package/lib/ChatCompletionStream.js.map +1 -1
  269. package/lib/ChatCompletionStream.mjs +1119 -68
  270. package/lib/ChatCompletionStream.mjs.map +1 -1
  271. package/lib/EventEmitter.d.mts.map +1 -1
  272. package/lib/EventEmitter.d.ts.map +1 -1
  273. package/lib/EventEmitter.js +67 -9
  274. package/lib/EventEmitter.js.map +1 -1
  275. package/lib/EventEmitter.mjs +68 -10
  276. package/lib/EventEmitter.mjs.map +1 -1
  277. package/lib/EventStream.d.mts +4 -0
  278. package/lib/EventStream.d.mts.map +1 -1
  279. package/lib/EventStream.d.ts +4 -0
  280. package/lib/EventStream.d.ts.map +1 -1
  281. package/lib/EventStream.js +1096 -11
  282. package/lib/EventStream.js.map +1 -1
  283. package/lib/EventStream.mjs +1097 -12
  284. package/lib/EventStream.mjs.map +1 -1
  285. package/lib/ResponsesParser.d.mts.map +1 -1
  286. package/lib/ResponsesParser.d.ts.map +1 -1
  287. package/lib/ResponsesParser.js +1 -1
  288. package/lib/ResponsesParser.js.map +1 -1
  289. package/lib/ResponsesParser.mjs +1 -1
  290. package/lib/ResponsesParser.mjs.map +1 -1
  291. package/lib/Util.d.mts +2 -0
  292. package/lib/Util.d.mts.map +1 -1
  293. package/lib/Util.d.ts +2 -0
  294. package/lib/Util.d.ts.map +1 -1
  295. package/lib/Util.js +7 -4
  296. package/lib/Util.js.map +1 -1
  297. package/lib/Util.mjs +7 -4
  298. package/lib/Util.mjs.map +1 -1
  299. package/lib/assistant-run-polling.d.mts +12 -0
  300. package/lib/assistant-run-polling.d.mts.map +1 -0
  301. package/lib/assistant-run-polling.d.ts +12 -0
  302. package/lib/assistant-run-polling.d.ts.map +1 -0
  303. package/lib/assistant-run-polling.js +17 -0
  304. package/lib/assistant-run-polling.js.map +1 -0
  305. package/lib/assistant-run-polling.mjs +14 -0
  306. package/lib/assistant-run-polling.mjs.map +1 -0
  307. package/lib/embeddings.d.mts +18 -0
  308. package/lib/embeddings.d.mts.map +1 -0
  309. package/lib/embeddings.d.ts +18 -0
  310. package/lib/embeddings.d.ts.map +1 -0
  311. package/lib/embeddings.js +50 -0
  312. package/lib/embeddings.js.map +1 -0
  313. package/lib/embeddings.mjs +47 -0
  314. package/lib/embeddings.mjs.map +1 -0
  315. package/lib/file-processing.d.mts +10 -0
  316. package/lib/file-processing.d.mts.map +1 -0
  317. package/lib/file-processing.d.ts +10 -0
  318. package/lib/file-processing.d.ts.map +1 -0
  319. package/lib/file-processing.js +30 -0
  320. package/lib/file-processing.js.map +1 -0
  321. package/lib/file-processing.mjs +27 -0
  322. package/lib/file-processing.mjs.map +1 -0
  323. package/lib/parser.d.mts.map +1 -1
  324. package/lib/parser.d.ts.map +1 -1
  325. package/lib/parser.js +16 -4
  326. package/lib/parser.js.map +1 -1
  327. package/lib/parser.mjs +16 -4
  328. package/lib/parser.mjs.map +1 -1
  329. package/lib/polling.d.mts +20 -0
  330. package/lib/polling.d.mts.map +1 -0
  331. package/lib/polling.d.ts +20 -0
  332. package/lib/polling.d.ts.map +1 -0
  333. package/lib/polling.js +130 -0
  334. package/lib/polling.js.map +1 -0
  335. package/lib/polling.mjs +127 -0
  336. package/lib/polling.mjs.map +1 -0
  337. package/lib/responses/ResponseStream.d.mts.map +1 -1
  338. package/lib/responses/ResponseStream.d.ts.map +1 -1
  339. package/lib/responses/ResponseStream.js +21 -11
  340. package/lib/responses/ResponseStream.js.map +1 -1
  341. package/lib/responses/ResponseStream.mjs +21 -11
  342. package/lib/responses/ResponseStream.mjs.map +1 -1
  343. package/lib/vector-store-polling.d.mts +22 -0
  344. package/lib/vector-store-polling.d.mts.map +1 -0
  345. package/lib/vector-store-polling.d.ts +22 -0
  346. package/lib/vector-store-polling.d.ts.map +1 -0
  347. package/lib/vector-store-polling.js +24 -0
  348. package/lib/vector-store-polling.js.map +1 -0
  349. package/lib/vector-store-polling.mjs +20 -0
  350. package/lib/vector-store-polling.mjs.map +1 -0
  351. package/lib/vector-store-upload.d.mts +17 -0
  352. package/lib/vector-store-upload.d.mts.map +1 -0
  353. package/lib/vector-store-upload.d.ts +17 -0
  354. package/lib/vector-store-upload.d.ts.map +1 -0
  355. package/lib/vector-store-upload.js +37 -0
  356. package/lib/vector-store-upload.js.map +1 -0
  357. package/lib/vector-store-upload.mjs +34 -0
  358. package/lib/vector-store-upload.mjs.map +1 -0
  359. package/lib/webhook-signature.d.mts +15 -0
  360. package/lib/webhook-signature.d.mts.map +1 -0
  361. package/lib/webhook-signature.d.ts +15 -0
  362. package/lib/webhook-signature.d.ts.map +1 -0
  363. package/lib/webhook-signature.js +125 -0
  364. package/lib/webhook-signature.js.map +1 -0
  365. package/lib/webhook-signature.mjs +121 -0
  366. package/lib/webhook-signature.mjs.map +1 -0
  367. package/package.json +14 -1
  368. package/realtime/internal-base.d.mts +2 -0
  369. package/realtime/internal-base.d.mts.map +1 -1
  370. package/realtime/internal-base.d.ts +2 -0
  371. package/realtime/internal-base.d.ts.map +1 -1
  372. package/realtime/internal-base.js +15 -0
  373. package/realtime/internal-base.js.map +1 -1
  374. package/realtime/internal-base.mjs +14 -0
  375. package/realtime/internal-base.mjs.map +1 -1
  376. package/realtime/websocket.d.mts +3 -2
  377. package/realtime/websocket.d.mts.map +1 -1
  378. package/realtime/websocket.d.ts +3 -2
  379. package/realtime/websocket.d.ts.map +1 -1
  380. package/realtime/websocket.js +90 -26
  381. package/realtime/websocket.js.map +1 -1
  382. package/realtime/websocket.mjs +91 -27
  383. package/realtime/websocket.mjs.map +1 -1
  384. package/realtime/ws.d.mts.map +1 -1
  385. package/realtime/ws.d.ts.map +1 -1
  386. package/realtime/ws.js +9 -1
  387. package/realtime/ws.js.map +1 -1
  388. package/realtime/ws.mjs +10 -2
  389. package/realtime/ws.mjs.map +1 -1
  390. package/resources/admin/organization/index.d.mts +2 -2
  391. package/resources/admin/organization/index.d.mts.map +1 -1
  392. package/resources/admin/organization/index.d.ts +2 -2
  393. package/resources/admin/organization/index.d.ts.map +1 -1
  394. package/resources/admin/organization/index.js.map +1 -1
  395. package/resources/admin/organization/index.mjs.map +1 -1
  396. package/resources/admin/organization/organization.d.mts +4 -4
  397. package/resources/admin/organization/organization.d.mts.map +1 -1
  398. package/resources/admin/organization/organization.d.ts +4 -4
  399. package/resources/admin/organization/organization.d.ts.map +1 -1
  400. package/resources/admin/organization/organization.js.map +1 -1
  401. package/resources/admin/organization/organization.mjs.map +1 -1
  402. package/resources/admin/organization/projects/index.d.mts +1 -1
  403. package/resources/admin/organization/projects/index.d.mts.map +1 -1
  404. package/resources/admin/organization/projects/index.d.ts +1 -1
  405. package/resources/admin/organization/projects/index.d.ts.map +1 -1
  406. package/resources/admin/organization/projects/index.js.map +1 -1
  407. package/resources/admin/organization/projects/index.mjs.map +1 -1
  408. package/resources/admin/organization/projects/projects.d.mts +22 -5
  409. package/resources/admin/organization/projects/projects.d.mts.map +1 -1
  410. package/resources/admin/organization/projects/projects.d.ts +22 -5
  411. package/resources/admin/organization/projects/projects.d.ts.map +1 -1
  412. package/resources/admin/organization/projects/projects.js.map +1 -1
  413. package/resources/admin/organization/projects/projects.mjs.map +1 -1
  414. package/resources/admin/organization/usage.d.mts +62 -1
  415. package/resources/admin/organization/usage.d.mts.map +1 -1
  416. package/resources/admin/organization/usage.d.ts +62 -1
  417. package/resources/admin/organization/usage.d.ts.map +1 -1
  418. package/resources/admin/organization/usage.js.map +1 -1
  419. package/resources/admin/organization/usage.mjs.map +1 -1
  420. package/resources/beta/responses/internal-base.d.mts.map +1 -1
  421. package/resources/beta/responses/internal-base.d.ts.map +1 -1
  422. package/resources/beta/responses/internal-base.js +2 -0
  423. package/resources/beta/responses/internal-base.js.map +1 -1
  424. package/resources/beta/responses/internal-base.mjs +2 -0
  425. package/resources/beta/responses/internal-base.mjs.map +1 -1
  426. package/resources/beta/responses/responses.d.mts +17 -20
  427. package/resources/beta/responses/responses.d.mts.map +1 -1
  428. package/resources/beta/responses/responses.d.ts +17 -20
  429. package/resources/beta/responses/responses.d.ts.map +1 -1
  430. package/resources/beta/responses/responses.js.map +1 -1
  431. package/resources/beta/responses/responses.mjs.map +1 -1
  432. package/resources/beta/threads/runs/index.d.mts +1 -1
  433. package/resources/beta/threads/runs/index.d.mts.map +1 -1
  434. package/resources/beta/threads/runs/index.d.ts +1 -1
  435. package/resources/beta/threads/runs/index.d.ts.map +1 -1
  436. package/resources/beta/threads/runs/runs.d.mts.map +1 -1
  437. package/resources/beta/threads/runs/runs.d.ts.map +1 -1
  438. package/resources/beta/threads/runs/runs.js +2 -43
  439. package/resources/beta/threads/runs/runs.js.map +1 -1
  440. package/resources/beta/threads/runs/runs.mjs +2 -43
  441. package/resources/beta/threads/runs/runs.mjs.map +1 -1
  442. package/resources/chat/completions/completions.d.mts +6 -0
  443. package/resources/chat/completions/completions.d.mts.map +1 -1
  444. package/resources/chat/completions/completions.d.ts +6 -0
  445. package/resources/chat/completions/completions.d.ts.map +1 -1
  446. package/resources/chat/completions/completions.js.map +1 -1
  447. package/resources/chat/completions/completions.mjs.map +1 -1
  448. package/resources/embeddings.d.mts.map +1 -1
  449. package/resources/embeddings.d.ts.map +1 -1
  450. package/resources/embeddings.js +2 -36
  451. package/resources/embeddings.js.map +1 -1
  452. package/resources/embeddings.mjs +2 -36
  453. package/resources/embeddings.mjs.map +1 -1
  454. package/resources/files.d.mts.map +1 -1
  455. package/resources/files.d.ts.map +1 -1
  456. package/resources/files.js +2 -15
  457. package/resources/files.js.map +1 -1
  458. package/resources/files.mjs +2 -15
  459. package/resources/files.mjs.map +1 -1
  460. package/resources/images.d.mts +12 -22
  461. package/resources/images.d.mts.map +1 -1
  462. package/resources/images.d.ts +12 -22
  463. package/resources/images.d.ts.map +1 -1
  464. package/resources/realtime/calls.d.mts +23 -1
  465. package/resources/realtime/calls.d.mts.map +1 -1
  466. package/resources/realtime/calls.d.ts +23 -1
  467. package/resources/realtime/calls.d.ts.map +1 -1
  468. package/resources/realtime/calls.js +24 -0
  469. package/resources/realtime/calls.js.map +1 -1
  470. package/resources/realtime/calls.mjs +24 -0
  471. package/resources/realtime/calls.mjs.map +1 -1
  472. package/resources/realtime/index.d.mts +1 -1
  473. package/resources/realtime/index.d.mts.map +1 -1
  474. package/resources/realtime/index.d.ts +1 -1
  475. package/resources/realtime/index.d.ts.map +1 -1
  476. package/resources/realtime/index.js.map +1 -1
  477. package/resources/realtime/index.mjs +1 -1
  478. package/resources/realtime/index.mjs.map +1 -1
  479. package/resources/realtime/realtime.d.mts +5 -4
  480. package/resources/realtime/realtime.d.mts.map +1 -1
  481. package/resources/realtime/realtime.d.ts +5 -4
  482. package/resources/realtime/realtime.d.ts.map +1 -1
  483. package/resources/realtime/realtime.js.map +1 -1
  484. package/resources/realtime/realtime.mjs.map +1 -1
  485. package/resources/responses/internal-base.d.mts.map +1 -1
  486. package/resources/responses/internal-base.d.ts.map +1 -1
  487. package/resources/responses/internal-base.js +2 -0
  488. package/resources/responses/internal-base.js.map +1 -1
  489. package/resources/responses/internal-base.mjs +2 -0
  490. package/resources/responses/internal-base.mjs.map +1 -1
  491. package/resources/responses/responses.d.mts +17 -20
  492. package/resources/responses/responses.d.mts.map +1 -1
  493. package/resources/responses/responses.d.ts +17 -20
  494. package/resources/responses/responses.d.ts.map +1 -1
  495. package/resources/responses/responses.js.map +1 -1
  496. package/resources/responses/responses.mjs.map +1 -1
  497. package/resources/vector-stores/file-batches.d.mts.map +1 -1
  498. package/resources/vector-stores/file-batches.d.ts.map +1 -1
  499. package/resources/vector-stores/file-batches.js +4 -61
  500. package/resources/vector-stores/file-batches.js.map +1 -1
  501. package/resources/vector-stores/file-batches.mjs +4 -61
  502. package/resources/vector-stores/file-batches.mjs.map +1 -1
  503. package/resources/vector-stores/files.d.mts +1 -1
  504. package/resources/vector-stores/files.d.mts.map +1 -1
  505. package/resources/vector-stores/files.d.ts +1 -1
  506. package/resources/vector-stores/files.d.ts.map +1 -1
  507. package/resources/vector-stores/files.js +2 -35
  508. package/resources/vector-stores/files.js.map +1 -1
  509. package/resources/vector-stores/files.mjs +2 -35
  510. package/resources/vector-stores/files.mjs.map +1 -1
  511. package/resources/webhooks/webhooks.d.mts.map +1 -1
  512. package/resources/webhooks/webhooks.d.ts.map +1 -1
  513. package/resources/webhooks/webhooks.js +5 -43
  514. package/resources/webhooks/webhooks.js.map +1 -1
  515. package/resources/webhooks/webhooks.mjs +5 -43
  516. package/resources/webhooks/webhooks.mjs.map +1 -1
  517. package/src/auth/index.ts +6 -1
  518. package/src/auth/subject-token-providers.ts +196 -4
  519. package/src/auth/types.ts +24 -0
  520. package/src/auth/workload-identity-auth.ts +104 -7
  521. package/src/auth/x509-transport.ts +49 -0
  522. package/src/azure.ts +22 -1
  523. package/src/bedrock.ts +49 -5
  524. package/src/beta/realtime/internal-base.ts +15 -0
  525. package/src/beta/realtime/websocket.ts +148 -40
  526. package/src/beta/realtime/ws.ts +31 -13
  527. package/src/client.ts +536 -92
  528. package/src/core/EventEmitter.ts +91 -7
  529. package/src/core/streaming.ts +226 -30
  530. package/src/helpers/audio.ts +93 -22
  531. package/src/helpers/standard-schema.ts +50 -16
  532. package/src/helpers/zod-v3-strict-schema.ts +514 -0
  533. package/src/helpers/zod.ts +17 -4
  534. package/src/index.ts +1 -1
  535. package/src/internal/assistant-stream-delta.ts +33 -10
  536. package/src/internal/auth/x509-token-exchange.ts +310 -0
  537. package/src/internal/auth/x509-transport-capability.ts +219 -0
  538. package/src/internal/auth/x509-transport-registry.ts +118 -0
  539. package/src/internal/auth/x509-transport-state-browser.ts +36 -0
  540. package/src/internal/auth/x509-transport-state.cts +36 -0
  541. package/src/internal/auth/x509-workload-identity-auth.ts +958 -0
  542. package/src/internal/bedrock.ts +182 -5
  543. package/src/internal/data-residency.ts +44 -0
  544. package/src/internal/multipart-encoding.ts +53 -0
  545. package/src/internal/qs/utils.ts +375 -13
  546. package/src/internal/request-options.ts +52 -1
  547. package/src/internal/responses/canonical-output-text.ts +3 -3
  548. package/src/internal/responses/response-accumulator.ts +411 -24
  549. package/src/internal/uploads.ts +81 -26
  550. package/src/internal/utils/env.ts +9 -5
  551. package/src/internal/ws.ts +24 -3
  552. package/src/lib/AbstractChatCompletionRunner.ts +33 -6
  553. package/src/lib/AssistantStream.ts +262 -22
  554. package/src/lib/ChatCompletionStream.ts +1467 -103
  555. package/src/lib/EventEmitter.ts +91 -7
  556. package/src/lib/EventStream.ts +1483 -10
  557. package/src/lib/ResponsesParser.ts +4 -1
  558. package/src/lib/Util.ts +7 -5
  559. package/src/lib/assistant-run-polling.ts +27 -0
  560. package/src/lib/embeddings.ts +65 -0
  561. package/src/lib/file-processing.ts +36 -0
  562. package/src/lib/parser.ts +19 -4
  563. package/src/lib/polling.ts +144 -0
  564. package/src/lib/responses/ResponseStream.ts +22 -10
  565. package/src/lib/vector-store-polling.ts +46 -0
  566. package/src/lib/vector-store-upload.ts +53 -0
  567. package/src/lib/webhook-signature.ts +164 -0
  568. package/src/realtime/internal-base.ts +15 -0
  569. package/src/realtime/websocket.ts +130 -27
  570. package/src/realtime/ws.ts +15 -2
  571. package/src/resources/admin/organization/index.ts +2 -0
  572. package/src/resources/admin/organization/organization.ts +4 -0
  573. package/src/resources/admin/organization/projects/index.ts +1 -0
  574. package/src/resources/admin/organization/projects/projects.ts +37 -4
  575. package/src/resources/admin/organization/usage.ts +83 -0
  576. package/src/resources/beta/responses/internal-base.ts +2 -0
  577. package/src/resources/beta/responses/responses.ts +19 -22
  578. package/src/resources/beta/threads/runs/index.ts +1 -1
  579. package/src/resources/beta/threads/runs/runs.ts +2 -45
  580. package/src/resources/chat/completions/completions.ts +7 -0
  581. package/src/resources/embeddings.ts +2 -42
  582. package/src/resources/files.ts +2 -19
  583. package/src/resources/images.ts +12 -22
  584. package/src/resources/realtime/api.md +1 -0
  585. package/src/resources/realtime/calls.ts +46 -0
  586. package/src/resources/realtime/index.ts +7 -1
  587. package/src/resources/realtime/realtime.ts +5 -3
  588. package/src/resources/responses/internal-base.ts +2 -0
  589. package/src/resources/responses/responses.ts +19 -22
  590. package/src/resources/vector-stores/file-batches.ts +8 -77
  591. package/src/resources/vector-stores/files.ts +3 -43
  592. package/src/resources/webhooks/webhooks.ts +5 -61
  593. package/src/version.ts +1 -1
  594. package/version.d.mts +1 -1
  595. package/version.d.ts +1 -1
  596. package/version.js +1 -1
  597. package/version.mjs +1 -1
@@ -3,7 +3,12 @@ import type * as z3 from 'zod/v3';
3
3
  import * as z4 from 'zod/v4';
4
4
  import type * as z4Mini from 'zod/v4-mini';
5
5
  import type { AutoParseableResponseFormat, AutoParseableTextFormat, AutoParseableTool } from '../lib/parser';
6
- import { makeParseableResponseFormat, makeParseableTextFormat, makeParseableTool } from '../lib/parser';
6
+ import {
7
+ makeParseableResponseFormat,
8
+ makeParseableTextFormat,
9
+ makeParseableTool,
10
+ parseResponseFormatContent,
11
+ } from '../lib/parser';
7
12
  import { zodToJsonSchema as _zodToJsonSchema } from '../_vendor/zod-to-json-schema';
8
13
  import type { AutoParseableResponseTool } from '../lib/ResponsesParser';
9
14
  import { makeParseableResponseTool } from '../lib/ResponsesParser';
@@ -12,6 +17,7 @@ import type { RealtimeFunctionTool } from '../resources/realtime/realtime';
12
17
  import { forEachJSONSchemaChild, toStrictJsonSchema } from '../lib/transform';
13
18
  import type { JSONSchema } from '../lib/jsonschema';
14
19
  import { hasOwn } from '../internal/utils/values';
20
+ import { assertJSONSerializableSchema, assertSupportedZodV3Schema } from './zod-v3-strict-schema';
15
21
 
16
22
  type ZodV4Schema = z4.ZodType | z4Mini.ZodMiniType;
17
23
  type ZodSchema = z3.ZodType | ZodV4Schema;
@@ -128,6 +134,7 @@ function zodV3ToJsonSchema(
128
134
  schema: z3.ZodType,
129
135
  options: { name: string; schemaDefinitions?: ZodSchemaDefinitions | undefined },
130
136
  ): Record<string, unknown> {
137
+ assertSupportedZodV3Schema(schema, options.schemaDefinitions as Record<string, z3.ZodType> | undefined);
131
138
  const rootName = getZodV3RootName(options.name, options.schemaDefinitions);
132
139
  const jsonSchema = _zodToJsonSchema(schema, {
133
140
  openaiStrictMode: true,
@@ -140,7 +147,9 @@ function zodV3ToJsonSchema(
140
147
  : undefined),
141
148
  });
142
149
 
143
- return escapeSchemaDefinitionRefs(jsonSchema, options.schemaDefinitions);
150
+ const escapedSchema = escapeSchemaDefinitionRefs(jsonSchema, options.schemaDefinitions);
151
+ assertJSONSerializableSchema(escapedSchema);
152
+ return escapedSchema;
144
153
  }
145
154
 
146
155
  function zodV4ToJsonSchema(
@@ -202,11 +211,15 @@ function parseZodObject<ZodInput extends ZodTypeLike>(
202
211
  zodObject: ZodInput,
203
212
  content: string,
204
213
  ): InferZodType<ZodInput> {
205
- const parsed = JSON.parse(content);
214
+ const parsed = parseResponseFormatContent({ type: 'json_schema', $parseRaw: undefined }, content);
206
215
  const parser = (zodObject as { parse?: (data: unknown) => unknown }).parse;
207
216
 
208
217
  if (typeof parser === 'function') {
209
- return parser.call(zodObject, parsed) as InferZodType<ZodInput>;
218
+ const result = parser.call(zodObject, parsed) as InferZodType<ZodInput>;
219
+ if (!isZodV4(zodObject as unknown as ZodSchema)) {
220
+ assertJSONSerializableSchema(result);
221
+ }
222
+ return result;
210
223
  }
211
224
 
212
225
  return z4.parse(zodObject as unknown as ZodV4Schema, parsed) as InferZodType<ZodInput>;
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@ export { OpenAI as default } from './client';
2
2
 
3
3
  export { type Uploadable, toFile, toStreamingFile } from './core/uploads';
4
4
  export { APIPromise } from './core/api-promise';
5
- export { OpenAI, type ClientOptions } from './client';
5
+ export { OpenAI, type ClientOptions, type DataResidency } from './client';
6
6
  export { PagePromise } from './core/pagination';
7
7
  export {
8
8
  OpenAIError,
@@ -6,6 +6,28 @@ const MAX_EXTERNALLY_MUTABLE_ASSISTANT_STREAM_ARRAY_LENGTH = 65_536;
6
6
 
7
7
  type AssistantStreamRecord = Record<string, unknown>;
8
8
 
9
+ function getAssistantStreamDiagnosticProperty(property: string): string {
10
+ switch (property) {
11
+ case 'value':
12
+ case 'arguments':
13
+ case 'input':
14
+ case 'text':
15
+ case 'content':
16
+ case 'annotations':
17
+ case 'metadata':
18
+ case 'name':
19
+ case 'role':
20
+ case 'status':
21
+ case 'tool_calls':
22
+ case 'step_details': {
23
+ return property;
24
+ }
25
+ default: {
26
+ return 'unknown';
27
+ }
28
+ }
29
+ }
30
+
9
31
  interface AssistantStreamArrayState {
10
32
  length: number;
11
33
  ownEntryCount: number;
@@ -87,12 +109,13 @@ function getAssistantStreamDeltaIndex(
87
109
  const { index } = deltaEntry;
88
110
 
89
111
  if (kind === 'array' && (index === null || index === undefined)) {
90
- console.error(deltaEntry);
91
112
  throw new Error('Expected array delta entry to have an `index` property');
92
113
  }
93
114
 
94
115
  if (kind === 'array' && typeof index !== 'number') {
95
- throw new TypeError(`Expected array delta entry \`index\` property to be a number but got ${index}`);
116
+ throw new TypeError(
117
+ 'Expected array delta entry `index` property to be a number but got an invalid value',
118
+ );
96
119
  }
97
120
 
98
121
  if (
@@ -101,7 +124,8 @@ function getAssistantStreamDeltaIndex(
101
124
  (index as number) >= baselineLength + MAX_ASSISTANT_STREAM_ARRAY_GROWTH ||
102
125
  (index as number) >= MAX_EXTERNALLY_MUTABLE_ASSISTANT_STREAM_ARRAY_LENGTH
103
126
  ) {
104
- throw new OpenAIError(`Assistant stream delta contains an invalid ${kind} index: ${index}`);
127
+ const safeIndex = typeof index === 'number' ? index : 'unknown';
128
+ throw new OpenAIError(`Assistant stream delta contains an invalid ${kind} index: ${safeIndex}`);
105
129
  }
106
130
 
107
131
  return index as number;
@@ -139,7 +163,7 @@ function assertValidAssistantStreamArrayDelta(
139
163
 
140
164
  for (const deltaEntry of delta) {
141
165
  if (!isObj(deltaEntry)) {
142
- throw new Error(`Expected array delta entry to be an object but got: ${deltaEntry}`);
166
+ throw new Error('Expected array delta entry to be an object but got an invalid value');
143
167
  }
144
168
 
145
169
  const validatedIndex = getAssistantStreamDeltaIndex(deltaEntry, kind, projectedArray.baselineLength);
@@ -259,11 +283,12 @@ export function defineAssistantStreamArrayEntry(accumulator: unknown[], index: n
259
283
  function getRequiredAssistantStreamArrayIndex(deltaEntry: AssistantStreamRecord): number {
260
284
  const { index } = deltaEntry;
261
285
  if (index === null || index === undefined) {
262
- console.error(deltaEntry);
263
286
  throw new Error('Expected array delta entry to have an `index` property');
264
287
  }
265
288
  if (typeof index !== 'number') {
266
- throw new TypeError(`Expected array delta entry \`index\` property to be a number but got ${index}`);
289
+ throw new TypeError(
290
+ 'Expected array delta entry `index` property to be a number but got an invalid value',
291
+ );
267
292
  }
268
293
  return index;
269
294
  }
@@ -286,7 +311,7 @@ function applyAssistantStreamArrayDelta(
286
311
 
287
312
  for (const deltaEntry of delta) {
288
313
  if (!isObj(deltaEntry)) {
289
- throw new Error(`Expected array delta entry to be an object but got: ${deltaEntry}`);
314
+ throw new Error('Expected array delta entry to be an object but got an invalid value');
290
315
  }
291
316
 
292
317
  const index = getRequiredAssistantStreamArrayIndex(deltaEntry);
@@ -349,9 +374,7 @@ function applyAssistantStreamDelta(
349
374
  applyAssistantStreamArrayDelta(accumulatedValue, deltaValue, applyAssistantStreamDelta);
350
375
  continue;
351
376
  } else {
352
- throw new TypeError(
353
- `Unhandled record type: ${key}, deltaValue: ${deltaValue}, accValue: ${accumulatedValue}`,
354
- );
377
+ throw new TypeError(`Unhandled record type: ${getAssistantStreamDiagnosticProperty(key)}`);
355
378
  }
356
379
  accumulator[key] = accumulatedValue;
357
380
  }
@@ -0,0 +1,310 @@
1
+ import {
2
+ APIConnectionError,
3
+ APIConnectionTimeoutError,
4
+ APIError,
5
+ OAuthError,
6
+ OpenAIError,
7
+ } from '../../core/error';
8
+ import { hasOwn } from '../utils/values';
9
+ import { sendX509Request } from './x509-transport-capability';
10
+ import { isRetryableX509TransportFailure } from './x509-transport-registry';
11
+ import {
12
+ isTransientX509ConnectionError,
13
+ markRetryableX509IssuerError,
14
+ markTransientX509ConnectionError,
15
+ rememberX509OAuthError,
16
+ } from '#x509-transport-state';
17
+ import type { X509ExchangedToken, X509Transport } from './x509-transport-registry';
18
+
19
+ export type { X509ExchangedToken } from './x509-transport-registry';
20
+
21
+ const TOKEN_EXCHANGE_URL = new URL('https://mtls.auth.openai.com/oauth/token');
22
+ const TOKEN_EXCHANGE_GRANT = 'urn:ietf:params:oauth:grant-type:token-exchange';
23
+ const X509_SUBJECT_TOKEN = 'urn:openai:params:oauth:token-type:x509';
24
+ const ACCESS_TOKEN_TYPE = 'urn:ietf:params:oauth:token-type:access_token';
25
+ const SAFE_ACCESS_TOKEN = /^[A-Za-z0-9._~+/-]+=*$/u;
26
+ const SAFE_OAUTH_ERRORS = new Set(['invalid_grant', 'invalid_subject_token', 'token_exchange_server_error']);
27
+ const SAFE_RESPONSE_HEADERS = ['retry-after', 'retry-after-ms', 'x-should-retry', 'x-request-id'];
28
+ const MAX_TOKEN_EXCHANGE_DURATION_MS = 5000;
29
+
30
+ function transientConnectionError(message: string, failure: unknown): APIConnectionError {
31
+ const error = new APIConnectionError({ message });
32
+ if (isRetryableX509TransportFailure(failure)) {
33
+ markTransientX509ConnectionError(error);
34
+ }
35
+ return error;
36
+ }
37
+
38
+ /** Parameters for one certificate-authenticated OAuth exchange. */
39
+ export interface X509TokenExchangeOptions {
40
+ /** Frozen, caller-owned certificate transport shared with the eventual API request. */
41
+ transport: X509Transport;
42
+
43
+ /** Identity provider enrolled for the workload certificate. */
44
+ identityProviderId: string;
45
+
46
+ /** OpenAI service account selected for the verified certificate identity. */
47
+ serviceAccountId: string;
48
+
49
+ /** Optional caller cancellation propagated through request and response consumption. */
50
+ signal?: AbortSignal | undefined;
51
+ }
52
+
53
+ async function cancelReader(
54
+ reader: ReadableStreamDefaultReader<Uint8Array>,
55
+ reason?: unknown,
56
+ ): Promise<void> {
57
+ try {
58
+ await reader.cancel(reason);
59
+ } catch {
60
+ // Response retirement is best-effort and must never replace the sanitized exchange result.
61
+ }
62
+ }
63
+
64
+ function cancelResponseBody(response: Response): void {
65
+ if (!response.body) {
66
+ return;
67
+ }
68
+
69
+ const reader = response.body.getReader();
70
+ try {
71
+ void cancelReader(reader);
72
+ } finally {
73
+ reader.releaseLock();
74
+ }
75
+ }
76
+
77
+ async function readResponseBody(response: Response, signal?: AbortSignal): Promise<unknown> {
78
+ if (!response.body) {
79
+ throw new OpenAIError('X.509 workload identity token exchange returned invalid JSON.');
80
+ }
81
+
82
+ const reader = response.body.getReader();
83
+ const chunks: Uint8Array[] = [];
84
+ let totalBytes = 0;
85
+ const cancel = () => {
86
+ void cancelReader(reader, signal?.reason);
87
+ };
88
+ signal?.addEventListener('abort', cancel, { once: true });
89
+
90
+ try {
91
+ while (true) {
92
+ signal?.throwIfAborted();
93
+ // oxlint-disable-next-line no-await-in-loop -- Token-response chunks must be consumed in wire order.
94
+ const chunk = await reader.read();
95
+ signal?.throwIfAborted();
96
+ if (chunk.done) {
97
+ break;
98
+ }
99
+ chunks.push(chunk.value);
100
+ totalBytes += chunk.value.byteLength;
101
+ }
102
+ } catch (error) {
103
+ cancel();
104
+ if (signal?.aborted) {
105
+ signal.throwIfAborted();
106
+ }
107
+ throw transientConnectionError('X.509 workload identity token response could not be read.', error);
108
+ } finally {
109
+ signal?.removeEventListener('abort', cancel);
110
+ reader.releaseLock();
111
+ }
112
+
113
+ const bytes = new Uint8Array(totalBytes);
114
+ let offset = 0;
115
+ for (const chunk of chunks) {
116
+ bytes.set(chunk, offset);
117
+ offset += chunk.byteLength;
118
+ }
119
+
120
+ try {
121
+ return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
122
+ } catch {
123
+ throw new OpenAIError('X.509 workload identity token exchange returned invalid JSON.');
124
+ }
125
+ }
126
+
127
+ function validateTokenResponse(value: unknown): X509ExchangedToken {
128
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
129
+ throw new OpenAIError('X.509 workload identity token exchange returned an invalid token response.');
130
+ }
131
+
132
+ const response = value as Record<string, unknown>;
133
+ if (
134
+ !hasOwn(response, 'access_token') ||
135
+ typeof response['access_token'] !== 'string' ||
136
+ !SAFE_ACCESS_TOKEN.test(response['access_token'])
137
+ ) {
138
+ throw new OpenAIError('X.509 workload identity token exchange returned an invalid access token.');
139
+ }
140
+ if (!hasOwn(response, 'token_type') || !hasOwn(response, 'issued_token_type')) {
141
+ throw new OpenAIError('X.509 workload identity token exchange returned an invalid token type.');
142
+ }
143
+ const tokenType = response['token_type'];
144
+ if (
145
+ typeof tokenType !== 'string' ||
146
+ tokenType.toLowerCase() !== 'bearer' ||
147
+ response['issued_token_type'] !== ACCESS_TOKEN_TYPE
148
+ ) {
149
+ throw new OpenAIError('X.509 workload identity token exchange returned an invalid token type.');
150
+ }
151
+
152
+ if (!hasOwn(response, 'expires_in')) {
153
+ throw new OpenAIError('X.509 workload identity token exchange returned an invalid token lifetime.');
154
+ }
155
+ const expiresIn = response['expires_in'];
156
+ if (typeof expiresIn !== 'number' || !Number.isFinite(expiresIn) || expiresIn <= 0 || expiresIn > 3600) {
157
+ throw new OpenAIError('X.509 workload identity token exchange returned an invalid token lifetime.');
158
+ }
159
+
160
+ return { accessToken: response['access_token'], expiresIn };
161
+ }
162
+
163
+ function safeResponseHeaders(response: Response, includeRetryHints = false): Headers {
164
+ const headers = new Headers();
165
+ for (const name of SAFE_RESPONSE_HEADERS) {
166
+ if (name !== 'x-request-id' && !includeRetryHints) {
167
+ continue;
168
+ }
169
+ const value = response.headers.get(name);
170
+ if (value !== null) {
171
+ headers.set(name, value);
172
+ }
173
+ }
174
+ return headers;
175
+ }
176
+
177
+ function readOAuthErrorCode(value: unknown): string | undefined {
178
+ if (typeof value === 'string') {
179
+ return value;
180
+ }
181
+ if (typeof value === 'object' && value !== null && hasOwn(value, 'code')) {
182
+ const code: unknown = Object.getOwnPropertyDescriptor(value, 'code')?.value;
183
+ return typeof code === 'string' ? code : undefined;
184
+ }
185
+ return undefined;
186
+ }
187
+
188
+ async function oauthError(
189
+ response: Response,
190
+ signal?: AbortSignal,
191
+ callerSignal?: AbortSignal,
192
+ ): Promise<OAuthError> {
193
+ let errorCode: { error: string } | undefined;
194
+
195
+ try {
196
+ const parsed = await readResponseBody(response, signal);
197
+ if (typeof parsed === 'object' && parsed !== null && hasOwn(parsed, 'error')) {
198
+ const code = readOAuthErrorCode(Object.getOwnPropertyDescriptor(parsed, 'error')?.value);
199
+ if (code !== undefined && SAFE_OAUTH_ERRORS.has(code)) {
200
+ errorCode = { error: code };
201
+ }
202
+ }
203
+ } catch {
204
+ callerSignal?.throwIfAborted();
205
+ if (
206
+ signal?.aborted &&
207
+ !(signal.reason instanceof APIConnectionTimeoutError && isTransientX509ConnectionError(signal.reason))
208
+ ) {
209
+ signal.throwIfAborted();
210
+ }
211
+ }
212
+
213
+ const { status } = response;
214
+ if (status !== 400 && status !== 401 && status !== 403) {
215
+ throw new OpenAIError('X.509 workload identity received an invalid OAuth error status.');
216
+ }
217
+ const headers = safeResponseHeaders(response);
218
+ const error = new OAuthError(status, errorCode, headers);
219
+ rememberX509OAuthError(error, { status, error: errorCode, headers });
220
+ return error;
221
+ }
222
+
223
+ /** Exchanges one enrolled client certificate for a validated OpenAI workload access token. */
224
+ export async function exchangeX509Token(options: X509TokenExchangeOptions): Promise<X509ExchangedToken> {
225
+ const { signal: callerSignal } = options;
226
+ callerSignal?.throwIfAborted();
227
+ const { identityProviderId, serviceAccountId, transport } = options;
228
+ if (
229
+ typeof identityProviderId !== 'string' ||
230
+ identityProviderId.trim().length === 0 ||
231
+ typeof serviceAccountId !== 'string' ||
232
+ serviceAccountId.trim().length === 0
233
+ ) {
234
+ throw new OpenAIError(
235
+ 'X.509 workload identity requires nonempty provider and service-account identifiers.',
236
+ );
237
+ }
238
+
239
+ const timeoutController = new AbortController();
240
+ const signal = callerSignal
241
+ ? AbortSignal.any([callerSignal, timeoutController.signal])
242
+ : timeoutController.signal;
243
+ const timeout = setTimeout(() => {
244
+ const error = new APIConnectionTimeoutError({
245
+ message: 'X.509 workload identity token exchange timed out.',
246
+ });
247
+ markTransientX509ConnectionError(error);
248
+ timeoutController.abort(error);
249
+ }, MAX_TOKEN_EXCHANGE_DURATION_MS);
250
+ timeout.unref();
251
+
252
+ try {
253
+ const body = JSON.stringify({
254
+ grant_type: TOKEN_EXCHANGE_GRANT,
255
+ subject_token_type: X509_SUBJECT_TOKEN,
256
+ identity_provider_id: identityProviderId,
257
+ service_account_id: serviceAccountId,
258
+ });
259
+
260
+ let response: Response;
261
+ try {
262
+ response = await sendX509Request(transport, TOKEN_EXCHANGE_URL, {
263
+ method: 'POST',
264
+ headers: { 'Content-Type': 'application/json' },
265
+ body,
266
+ redirect: 'manual',
267
+ signal,
268
+ });
269
+ } catch (error) {
270
+ signal.throwIfAborted();
271
+ throw transientConnectionError('X.509 workload identity token exchange connection failed.', error);
272
+ }
273
+ signal.throwIfAborted();
274
+
275
+ if (response.ok) {
276
+ try {
277
+ return validateTokenResponse(await readResponseBody(response, signal));
278
+ } catch (error) {
279
+ signal.throwIfAborted();
280
+ if (error instanceof APIConnectionError) {
281
+ throw error;
282
+ }
283
+ if (error instanceof OpenAIError) {
284
+ throw APIError.generate(response.status, undefined, error.message, safeResponseHeaders(response));
285
+ }
286
+ throw error;
287
+ }
288
+ }
289
+ if (response.status === 400 || response.status === 401 || response.status === 403) {
290
+ throw await oauthError(response, signal, callerSignal);
291
+ }
292
+
293
+ cancelResponseBody(response);
294
+ const retryableStatus =
295
+ response.status === 408 || response.status === 409 || response.status === 429 || response.status >= 500;
296
+ const headers = safeResponseHeaders(response, retryableStatus);
297
+ const error = APIError.generate(
298
+ response.status,
299
+ undefined,
300
+ 'X.509 workload identity token exchange failed.',
301
+ headers,
302
+ );
303
+ if (retryableStatus && headers.get('x-should-retry') !== 'false') {
304
+ markRetryableX509IssuerError(error);
305
+ }
306
+ throw error;
307
+ } finally {
308
+ clearTimeout(timeout);
309
+ }
310
+ }
@@ -0,0 +1,219 @@
1
+ import { types } from 'node:util';
2
+ import { Agent, ProxyAgent, Request, fetch } from 'undici';
3
+ import { OpenAIError } from '../../core/error';
4
+ import { x509TransportBrand } from './x509-transport-registry';
5
+ import type { RegisteredX509Transport, X509Transport } from './x509-transport-registry';
6
+ import { findRegisteredX509Transport, rememberRegisteredX509Transport } from '#x509-transport-state';
7
+
8
+ export type { X509Transport } from './x509-transport-registry';
9
+
10
+ /** Explicitly supported, application-owned Undici proxy configurations. */
11
+ export type X509ProxyMode = 'direct' | 'http-connect' | 'https-connect';
12
+
13
+ /** Application attestation for one caller-owned static-certificate Undici transport. */
14
+ export interface X509TransportOptions {
15
+ /** X.509 transport currently supports genuine Node.js runtimes only. */
16
+ runtime: 'node';
17
+
18
+ /** Caller-owned Undici Agent or ProxyAgent; the SDK never closes or inspects it. */
19
+ dispatcher: Agent | ProxyAgent;
20
+
21
+ /** Attests that the dispatcher uses one static workload-certificate identity. */
22
+ certificateIdentity: 'static';
23
+
24
+ /** Attests that proxy TLS and CONNECT credentials are independently configured. */
25
+ proxy: X509ProxyMode;
26
+ }
27
+
28
+ const allowedOptionNames = new Set(['runtime', 'dispatcher', 'certificateIdentity', 'proxy']);
29
+ const transportBrand: typeof x509TransportBrand = x509TransportBrand;
30
+
31
+ class NodeX509Transport implements X509Transport {
32
+ declare readonly [transportBrand]: true;
33
+
34
+ readonly #dispatcher: Agent | ProxyAgent;
35
+
36
+ constructor(dispatcher: Agent | ProxyAgent) {
37
+ this.#dispatcher = dispatcher;
38
+ Object.freeze(this);
39
+ }
40
+
41
+ static dispatcher(value: object): Agent | ProxyAgent | undefined {
42
+ return #dispatcher in value ? value.#dispatcher : undefined;
43
+ }
44
+ }
45
+
46
+ /** Registers only a genuine frozen capability whose JavaScript private dispatcher cannot be forged. */
47
+ export function registerX509Transport(transport: X509Transport, registered: RegisteredX509Transport): void {
48
+ if (
49
+ !transport ||
50
+ typeof transport !== 'object' ||
51
+ types.isProxy(transport) ||
52
+ !Object.isFrozen(transport) ||
53
+ !NodeX509Transport.dispatcher(transport)
54
+ ) {
55
+ throw new OpenAIError('Only a genuine frozen X.509 transport capability can be registered.');
56
+ }
57
+ if (findRegisteredX509Transport(transport)) {
58
+ throw new OpenAIError('An approved X.509 transport capability cannot be registered more than once.');
59
+ }
60
+ rememberRegisteredX509Transport(transport, Object.freeze(registered));
61
+ }
62
+
63
+ function dataOption(options: X509TransportOptions, name: keyof X509TransportOptions): unknown {
64
+ const descriptor = Object.getOwnPropertyDescriptor(options, name);
65
+ if (!descriptor || !('value' in descriptor)) {
66
+ throw new Error(`X.509 transport option \`${name}\` must be an own plain data property.`);
67
+ }
68
+ return descriptor.value;
69
+ }
70
+
71
+ function assertNodeRuntime(): void {
72
+ if (
73
+ typeof process === 'undefined' ||
74
+ process.release.name !== 'node' ||
75
+ 'bun' in process.versions ||
76
+ 'Bun' in globalThis ||
77
+ 'Deno' in globalThis
78
+ ) {
79
+ throw new Error('X.509 transport requires a genuine Node.js runtime.');
80
+ }
81
+ }
82
+
83
+ function attestedDispatcher(options: X509TransportOptions): Agent | ProxyAgent {
84
+ const dispatcher = dataOption(options, 'dispatcher');
85
+ if (!dispatcher || typeof dispatcher !== 'object') {
86
+ throw new Error('X.509 transport requires a caller-owned Undici Agent or ProxyAgent.');
87
+ }
88
+ if (types.isProxy(dispatcher)) {
89
+ throw new Error('X.509 transport does not accept a dispatcher proxy.');
90
+ }
91
+
92
+ const isDirect = dispatcher instanceof Agent;
93
+ const isConnect = dispatcher instanceof ProxyAgent;
94
+ if (!isDirect && !isConnect) {
95
+ throw new Error('X.509 transport requires a caller-owned Undici Agent or ProxyAgent.');
96
+ }
97
+
98
+ const proxy = dataOption(options, 'proxy');
99
+ if (proxy !== 'direct' && proxy !== 'http-connect' && proxy !== 'https-connect') {
100
+ throw new Error('X.509 transport requires an explicitly supported proxy mode.');
101
+ }
102
+ if ((proxy === 'direct') !== isDirect) {
103
+ throw new Error('An X.509 CONNECT proxy requires an Undici ProxyAgent.');
104
+ }
105
+
106
+ return dispatcher;
107
+ }
108
+
109
+ function assertRequestDispatcherSupport(dispatcher: Agent | ProxyAgent): void {
110
+ let observesRequestDispatcher = false;
111
+
112
+ // about:blank never reaches the network; the getter checks the actual fetch contract.
113
+ void Promise.allSettled([
114
+ fetch('about:blank', {
115
+ get dispatcher() {
116
+ observesRequestDispatcher = true;
117
+ return dispatcher;
118
+ },
119
+ }),
120
+ ]);
121
+
122
+ if (!observesRequestDispatcher) {
123
+ throw new Error('X.509 transport requires Undici 5.2.0 or later with per-request dispatcher support.');
124
+ }
125
+ }
126
+
127
+ function assertConnectProxySupport(): void {
128
+ const targetOrigin = 'https://127.0.0.1:65535';
129
+ let routedOrigin: string | undefined;
130
+ const probe = new ProxyAgent({
131
+ uri: 'http://127.0.0.1:1',
132
+ factory(origin) {
133
+ routedOrigin = String(origin);
134
+ throw new Error('X.509 CONNECT capability probe');
135
+ },
136
+ });
137
+
138
+ // The throwing factory reveals the actual routing decision before any socket opens.
139
+ const request = fetch(targetOrigin, { dispatcher: probe });
140
+ void Promise.allSettled([request, probe.close()]);
141
+
142
+ if (routedOrigin !== targetOrigin) {
143
+ throw new Error('X.509 CONNECT proxy requires Undici 5.5.1 or later with target TLS tunneling.');
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Creates a frozen, opaque capability for one caller-owned Undici transport.
149
+ *
150
+ * `certificateIdentity: 'static'` is an application attestation: the SDK does
151
+ * not inspect certificates, private dispatcher internals, callbacks, or TLS
152
+ * options and cannot cryptographically prove certificate selection. Configure
153
+ * one static identity without custom dispatcher factories. For HTTPS CONNECT,
154
+ * independently configure `proxyTls` and `requestTls` so workload credentials
155
+ * never reach the proxy. Rotation requires creating a fresh dispatcher and
156
+ * capability; the application remains responsible for draining the old one.
157
+ *
158
+ * This Node-only preview entrypoint requires the optional `undici` peer at
159
+ * version 5.2.0 or later. CONNECT proxy modes require version 5.5.1 or
160
+ * later; ordinary SDK clients retain broader compatibility.
161
+ */
162
+ export function createX509Transport(options: X509TransportOptions): X509Transport {
163
+ assertNodeRuntime();
164
+
165
+ if (!options || typeof options !== 'object' || types.isProxy(options)) {
166
+ throw new Error('X.509 transport configuration must be a non-proxy object.');
167
+ }
168
+
169
+ for (const name of Reflect.ownKeys(options)) {
170
+ if (typeof name !== 'string' || !allowedOptionNames.has(name)) {
171
+ throw new Error(`Unsupported X.509 transport option: \`${String(name)}\`.`);
172
+ }
173
+ }
174
+
175
+ if (dataOption(options, 'runtime') !== 'node') {
176
+ throw new Error('X.509 transport requires an explicitly attested Node.js runtime.');
177
+ }
178
+
179
+ if (dataOption(options, 'certificateIdentity') !== 'static') {
180
+ throw new Error('X.509 transport requires an explicitly attested static client certificate.');
181
+ }
182
+
183
+ const dispatcher = attestedDispatcher(options);
184
+ assertRequestDispatcherSupport(dispatcher);
185
+ if (dispatcher instanceof ProxyAgent) {
186
+ assertConnectProxySupport();
187
+ }
188
+ return new NodeX509Transport(dispatcher);
189
+ }
190
+
191
+ /** Dispatches through the opaque attested transport without accepting replacement dispatchers. */
192
+ export async function sendX509Request(
193
+ transport: X509Transport,
194
+ target: URL,
195
+ options: RequestInit,
196
+ ): Promise<Response> {
197
+ if (!transport || typeof transport !== 'object' || types.isProxy(transport)) {
198
+ throw new Error('Invalid X.509 transport capability.');
199
+ }
200
+
201
+ const dispatcher = NodeX509Transport.dispatcher(transport);
202
+ if (!dispatcher) {
203
+ throw new Error('Invalid X.509 transport capability.');
204
+ }
205
+
206
+ const normalizedTarget = new URL(target.href);
207
+ if (normalizedTarget.protocol !== 'https:') {
208
+ throw new Error('X.509 transport requires an HTTPS destination.');
209
+ }
210
+
211
+ if (Object.getOwnPropertyDescriptor(options, 'dispatcher')) {
212
+ throw new Error('X.509 transport does not allow a per-request dispatcher override.');
213
+ }
214
+
215
+ const requestOptions: Omit<RequestInit, 'dispatcher'> = options;
216
+ const request = new Request(normalizedTarget, requestOptions);
217
+ const response = await fetch(request, { dispatcher, redirect: 'manual' });
218
+ return response;
219
+ }