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.
- package/CHANGELOG.md +117 -0
- package/README.md +46 -2
- package/auth/index.d.mts +1 -1
- package/auth/index.d.mts.map +1 -1
- package/auth/index.d.ts +1 -1
- package/auth/index.d.ts.map +1 -1
- package/auth/index.js.map +1 -1
- package/auth/index.mjs.map +1 -1
- package/auth/subject-token-providers.d.mts.map +1 -1
- package/auth/subject-token-providers.d.ts.map +1 -1
- package/auth/subject-token-providers.js +176 -4
- package/auth/subject-token-providers.js.map +1 -1
- package/auth/subject-token-providers.mjs +176 -4
- package/auth/subject-token-providers.mjs.map +1 -1
- package/auth/types.d.mts +17 -0
- package/auth/types.d.mts.map +1 -1
- package/auth/types.d.ts +17 -0
- package/auth/types.d.ts.map +1 -1
- package/auth/workload-identity-auth.d.mts.map +1 -1
- package/auth/workload-identity-auth.d.ts.map +1 -1
- package/auth/workload-identity-auth.js +80 -7
- package/auth/workload-identity-auth.js.map +1 -1
- package/auth/workload-identity-auth.mjs +80 -7
- package/auth/workload-identity-auth.mjs.map +1 -1
- package/auth/x509-transport.d.mts +5 -0
- package/auth/x509-transport.d.mts.map +1 -0
- package/auth/x509-transport.d.ts +5 -0
- package/auth/x509-transport.d.ts.map +1 -0
- package/auth/x509-transport.js +39 -0
- package/auth/x509-transport.js.map +1 -0
- package/auth/x509-transport.mjs +36 -0
- package/auth/x509-transport.mjs.map +1 -0
- package/azure.d.mts +11 -2
- package/azure.d.mts.map +1 -1
- package/azure.d.ts +11 -2
- package/azure.d.ts.map +1 -1
- package/azure.js +7 -1
- package/azure.js.map +1 -1
- package/azure.mjs +7 -1
- package/azure.mjs.map +1 -1
- package/bedrock.d.mts +6 -2
- package/bedrock.d.mts.map +1 -1
- package/bedrock.d.ts +6 -2
- package/bedrock.d.ts.map +1 -1
- package/bedrock.js +34 -4
- package/bedrock.js.map +1 -1
- package/bedrock.mjs +35 -5
- package/bedrock.mjs.map +1 -1
- package/beta/realtime/internal-base.d.mts +2 -0
- package/beta/realtime/internal-base.d.mts.map +1 -1
- package/beta/realtime/internal-base.d.ts +2 -0
- package/beta/realtime/internal-base.d.ts.map +1 -1
- package/beta/realtime/internal-base.js +15 -0
- package/beta/realtime/internal-base.js.map +1 -1
- package/beta/realtime/internal-base.mjs +14 -0
- package/beta/realtime/internal-base.mjs.map +1 -1
- package/beta/realtime/websocket.d.mts +11 -5
- package/beta/realtime/websocket.d.mts.map +1 -1
- package/beta/realtime/websocket.d.ts +11 -5
- package/beta/realtime/websocket.d.ts.map +1 -1
- package/beta/realtime/websocket.js +106 -31
- package/beta/realtime/websocket.js.map +1 -1
- package/beta/realtime/websocket.mjs +107 -32
- package/beta/realtime/websocket.mjs.map +1 -1
- package/beta/realtime/ws.d.mts +0 -2
- package/beta/realtime/ws.d.mts.map +1 -1
- package/beta/realtime/ws.d.ts +0 -2
- package/beta/realtime/ws.d.ts.map +1 -1
- package/beta/realtime/ws.js +24 -5
- package/beta/realtime/ws.js.map +1 -1
- package/beta/realtime/ws.mjs +25 -6
- package/beta/realtime/ws.mjs.map +1 -1
- package/client.d.mts +17 -2
- package/client.d.mts.map +1 -1
- package/client.d.ts +17 -2
- package/client.d.ts.map +1 -1
- package/client.js +422 -70
- package/client.js.map +1 -1
- package/client.mjs +423 -71
- package/client.mjs.map +1 -1
- package/core/EventEmitter.d.mts.map +1 -1
- package/core/EventEmitter.d.ts.map +1 -1
- package/core/EventEmitter.js +67 -9
- package/core/EventEmitter.js.map +1 -1
- package/core/EventEmitter.mjs +68 -10
- package/core/EventEmitter.mjs.map +1 -1
- package/core/streaming.d.mts +1 -0
- package/core/streaming.d.mts.map +1 -1
- package/core/streaming.d.ts +1 -0
- package/core/streaming.d.ts.map +1 -1
- package/core/streaming.js +216 -26
- package/core/streaming.js.map +1 -1
- package/core/streaming.mjs +216 -26
- package/core/streaming.mjs.map +1 -1
- package/helpers/audio.d.mts +5 -5
- package/helpers/audio.d.mts.map +1 -1
- package/helpers/audio.d.ts +5 -5
- package/helpers/audio.d.ts.map +1 -1
- package/helpers/audio.js +93 -22
- package/helpers/audio.js.map +1 -1
- package/helpers/audio.mjs +93 -22
- package/helpers/audio.mjs.map +1 -1
- package/helpers/standard-schema.d.mts.map +1 -1
- package/helpers/standard-schema.d.ts.map +1 -1
- package/helpers/standard-schema.js +34 -14
- package/helpers/standard-schema.js.map +1 -1
- package/helpers/standard-schema.mjs +35 -15
- package/helpers/standard-schema.mjs.map +1 -1
- package/helpers/zod-v3-strict-schema.d.mts +7 -0
- package/helpers/zod-v3-strict-schema.d.mts.map +1 -0
- package/helpers/zod-v3-strict-schema.d.ts +7 -0
- package/helpers/zod-v3-strict-schema.d.ts.map +1 -0
- package/helpers/zod-v3-strict-schema.js +403 -0
- package/helpers/zod-v3-strict-schema.js.map +1 -0
- package/helpers/zod-v3-strict-schema.mjs +399 -0
- package/helpers/zod-v3-strict-schema.mjs.map +1 -0
- package/helpers/zod.d.mts.map +1 -1
- package/helpers/zod.d.ts.map +1 -1
- package/helpers/zod.js +11 -3
- package/helpers/zod.js.map +1 -1
- package/helpers/zod.mjs +12 -4
- package/helpers/zod.mjs.map +1 -1
- package/index.d.mts +1 -1
- package/index.d.mts.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js.map +1 -1
- package/index.mjs.map +1 -1
- package/internal/assistant-stream-delta.d.mts.map +1 -1
- package/internal/assistant-stream-delta.d.ts.map +1 -1
- package/internal/assistant-stream-delta.js +28 -8
- package/internal/assistant-stream-delta.js.map +1 -1
- package/internal/assistant-stream-delta.mjs +28 -8
- package/internal/assistant-stream-delta.mjs.map +1 -1
- package/internal/auth/x509-token-exchange.d.mts +16 -0
- package/internal/auth/x509-token-exchange.d.mts.map +1 -0
- package/internal/auth/x509-token-exchange.d.ts +16 -0
- package/internal/auth/x509-token-exchange.d.ts.map +1 -0
- package/internal/auth/x509-token-exchange.js +246 -0
- package/internal/auth/x509-token-exchange.js.map +1 -0
- package/internal/auth/x509-token-exchange.mjs +243 -0
- package/internal/auth/x509-token-exchange.mjs.map +1 -0
- package/internal/auth/x509-transport-capability.d.mts +37 -0
- package/internal/auth/x509-transport-capability.d.mts.map +1 -0
- package/internal/auth/x509-transport-capability.d.ts +37 -0
- package/internal/auth/x509-transport-capability.d.ts.map +1 -0
- package/internal/auth/x509-transport-capability.js +169 -0
- package/internal/auth/x509-transport-capability.js.map +1 -0
- package/internal/auth/x509-transport-capability.mjs +164 -0
- package/internal/auth/x509-transport-capability.mjs.map +1 -0
- package/internal/auth/x509-transport-registry.d.mts +63 -0
- package/internal/auth/x509-transport-registry.d.mts.map +1 -0
- package/internal/auth/x509-transport-registry.d.ts +63 -0
- package/internal/auth/x509-transport-registry.d.ts.map +1 -0
- package/internal/auth/x509-transport-registry.js +53 -0
- package/internal/auth/x509-transport-registry.js.map +1 -0
- package/internal/auth/x509-transport-registry.mjs +48 -0
- package/internal/auth/x509-transport-registry.mjs.map +1 -0
- package/internal/auth/x509-transport-state-browser.d.mts +21 -0
- package/internal/auth/x509-transport-state-browser.d.mts.map +1 -0
- package/internal/auth/x509-transport-state-browser.d.ts +21 -0
- package/internal/auth/x509-transport-state-browser.d.ts.map +1 -0
- package/internal/auth/x509-transport-state-browser.js +30 -0
- package/internal/auth/x509-transport-state-browser.js.map +1 -0
- package/internal/auth/x509-transport-state-browser.mjs +27 -0
- package/internal/auth/x509-transport-state-browser.mjs.map +1 -0
- package/internal/auth/x509-transport-state.cjs +30 -0
- package/internal/auth/x509-transport-state.cjs.map +1 -0
- package/internal/auth/x509-transport-state.d.cts +21 -0
- package/internal/auth/x509-transport-state.d.cts.map +1 -0
- package/internal/auth/x509-workload-identity-auth.d.mts +128 -0
- package/internal/auth/x509-workload-identity-auth.d.mts.map +1 -0
- package/internal/auth/x509-workload-identity-auth.d.ts +128 -0
- package/internal/auth/x509-workload-identity-auth.d.ts.map +1 -0
- package/internal/auth/x509-workload-identity-auth.js +767 -0
- package/internal/auth/x509-workload-identity-auth.js.map +1 -0
- package/internal/auth/x509-workload-identity-auth.mjs +757 -0
- package/internal/auth/x509-workload-identity-auth.mjs.map +1 -0
- package/internal/bedrock.d.mts +2 -0
- package/internal/bedrock.d.mts.map +1 -1
- package/internal/bedrock.d.ts +2 -0
- package/internal/bedrock.d.ts.map +1 -1
- package/internal/bedrock.js +169 -5
- package/internal/bedrock.js.map +1 -1
- package/internal/bedrock.mjs +168 -5
- package/internal/bedrock.mjs.map +1 -1
- package/internal/data-residency.d.mts +12 -0
- package/internal/data-residency.d.mts.map +1 -0
- package/internal/data-residency.d.ts +12 -0
- package/internal/data-residency.d.ts.map +1 -0
- package/internal/data-residency.js +34 -0
- package/internal/data-residency.js.map +1 -0
- package/internal/data-residency.mjs +30 -0
- package/internal/data-residency.mjs.map +1 -0
- package/internal/multipart-encoding.d.mts +8 -0
- package/internal/multipart-encoding.d.mts.map +1 -0
- package/internal/multipart-encoding.d.ts +8 -0
- package/internal/multipart-encoding.d.ts.map +1 -0
- package/internal/multipart-encoding.js +51 -0
- package/internal/multipart-encoding.js.map +1 -0
- package/internal/multipart-encoding.mjs +48 -0
- package/internal/multipart-encoding.mjs.map +1 -0
- package/internal/qs/utils.d.mts.map +1 -1
- package/internal/qs/utils.d.ts.map +1 -1
- package/internal/qs/utils.js +307 -10
- package/internal/qs/utils.js.map +1 -1
- package/internal/qs/utils.mjs +307 -10
- package/internal/qs/utils.mjs.map +1 -1
- package/internal/request-options.d.mts +7 -0
- package/internal/request-options.d.mts.map +1 -1
- package/internal/request-options.d.ts +7 -0
- package/internal/request-options.d.ts.map +1 -1
- package/internal/request-options.js +43 -1
- package/internal/request-options.js.map +1 -1
- package/internal/request-options.mjs +42 -1
- package/internal/request-options.mjs.map +1 -1
- package/internal/responses/canonical-output-text.js +3 -3
- package/internal/responses/canonical-output-text.js.map +1 -1
- package/internal/responses/canonical-output-text.mjs +3 -3
- package/internal/responses/canonical-output-text.mjs.map +1 -1
- package/internal/responses/response-accumulator.d.mts +1 -1
- package/internal/responses/response-accumulator.d.mts.map +1 -1
- package/internal/responses/response-accumulator.d.ts +1 -1
- package/internal/responses/response-accumulator.d.ts.map +1 -1
- package/internal/responses/response-accumulator.js +331 -25
- package/internal/responses/response-accumulator.js.map +1 -1
- package/internal/responses/response-accumulator.mjs +331 -25
- package/internal/responses/response-accumulator.mjs.map +1 -1
- package/internal/tslib.js +6 -0
- package/internal/tslib.mjs +6 -1
- package/internal/uploads.d.mts +10 -6
- package/internal/uploads.d.mts.map +1 -1
- package/internal/uploads.d.ts +10 -6
- package/internal/uploads.d.ts.map +1 -1
- package/internal/uploads.js +65 -24
- package/internal/uploads.js.map +1 -1
- package/internal/uploads.mjs +65 -24
- package/internal/uploads.mjs.map +1 -1
- package/internal/utils/env.d.mts.map +1 -1
- package/internal/utils/env.d.ts.map +1 -1
- package/internal/utils/env.js +9 -4
- package/internal/utils/env.js.map +1 -1
- package/internal/utils/env.mjs +9 -4
- package/internal/utils/env.mjs.map +1 -1
- package/internal/ws.d.mts.map +1 -1
- package/internal/ws.d.ts.map +1 -1
- package/internal/ws.js +23 -1
- package/internal/ws.js.map +1 -1
- package/internal/ws.mjs +23 -1
- package/internal/ws.mjs.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.mts.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.ts.map +1 -1
- package/lib/AbstractChatCompletionRunner.js +32 -7
- package/lib/AbstractChatCompletionRunner.js.map +1 -1
- package/lib/AbstractChatCompletionRunner.mjs +34 -9
- package/lib/AbstractChatCompletionRunner.mjs.map +1 -1
- package/lib/AssistantStream.d.mts.map +1 -1
- package/lib/AssistantStream.d.ts.map +1 -1
- package/lib/AssistantStream.js +211 -23
- package/lib/AssistantStream.js.map +1 -1
- package/lib/AssistantStream.mjs +211 -23
- package/lib/AssistantStream.mjs.map +1 -1
- package/lib/ChatCompletionStream.d.mts +1 -1
- package/lib/ChatCompletionStream.d.mts.map +1 -1
- package/lib/ChatCompletionStream.d.ts +1 -1
- package/lib/ChatCompletionStream.d.ts.map +1 -1
- package/lib/ChatCompletionStream.js +1118 -67
- package/lib/ChatCompletionStream.js.map +1 -1
- package/lib/ChatCompletionStream.mjs +1119 -68
- package/lib/ChatCompletionStream.mjs.map +1 -1
- package/lib/EventEmitter.d.mts.map +1 -1
- package/lib/EventEmitter.d.ts.map +1 -1
- package/lib/EventEmitter.js +67 -9
- package/lib/EventEmitter.js.map +1 -1
- package/lib/EventEmitter.mjs +68 -10
- package/lib/EventEmitter.mjs.map +1 -1
- package/lib/EventStream.d.mts +4 -0
- package/lib/EventStream.d.mts.map +1 -1
- package/lib/EventStream.d.ts +4 -0
- package/lib/EventStream.d.ts.map +1 -1
- package/lib/EventStream.js +1096 -11
- package/lib/EventStream.js.map +1 -1
- package/lib/EventStream.mjs +1097 -12
- package/lib/EventStream.mjs.map +1 -1
- package/lib/ResponsesParser.d.mts.map +1 -1
- package/lib/ResponsesParser.d.ts.map +1 -1
- package/lib/ResponsesParser.js +1 -1
- package/lib/ResponsesParser.js.map +1 -1
- package/lib/ResponsesParser.mjs +1 -1
- package/lib/ResponsesParser.mjs.map +1 -1
- package/lib/Util.d.mts +2 -0
- package/lib/Util.d.mts.map +1 -1
- package/lib/Util.d.ts +2 -0
- package/lib/Util.d.ts.map +1 -1
- package/lib/Util.js +7 -4
- package/lib/Util.js.map +1 -1
- package/lib/Util.mjs +7 -4
- package/lib/Util.mjs.map +1 -1
- package/lib/assistant-run-polling.d.mts +12 -0
- package/lib/assistant-run-polling.d.mts.map +1 -0
- package/lib/assistant-run-polling.d.ts +12 -0
- package/lib/assistant-run-polling.d.ts.map +1 -0
- package/lib/assistant-run-polling.js +17 -0
- package/lib/assistant-run-polling.js.map +1 -0
- package/lib/assistant-run-polling.mjs +14 -0
- package/lib/assistant-run-polling.mjs.map +1 -0
- package/lib/embeddings.d.mts +18 -0
- package/lib/embeddings.d.mts.map +1 -0
- package/lib/embeddings.d.ts +18 -0
- package/lib/embeddings.d.ts.map +1 -0
- package/lib/embeddings.js +50 -0
- package/lib/embeddings.js.map +1 -0
- package/lib/embeddings.mjs +47 -0
- package/lib/embeddings.mjs.map +1 -0
- package/lib/file-processing.d.mts +10 -0
- package/lib/file-processing.d.mts.map +1 -0
- package/lib/file-processing.d.ts +10 -0
- package/lib/file-processing.d.ts.map +1 -0
- package/lib/file-processing.js +30 -0
- package/lib/file-processing.js.map +1 -0
- package/lib/file-processing.mjs +27 -0
- package/lib/file-processing.mjs.map +1 -0
- package/lib/parser.d.mts.map +1 -1
- package/lib/parser.d.ts.map +1 -1
- package/lib/parser.js +16 -4
- package/lib/parser.js.map +1 -1
- package/lib/parser.mjs +16 -4
- package/lib/parser.mjs.map +1 -1
- package/lib/polling.d.mts +20 -0
- package/lib/polling.d.mts.map +1 -0
- package/lib/polling.d.ts +20 -0
- package/lib/polling.d.ts.map +1 -0
- package/lib/polling.js +130 -0
- package/lib/polling.js.map +1 -0
- package/lib/polling.mjs +127 -0
- package/lib/polling.mjs.map +1 -0
- package/lib/responses/ResponseStream.d.mts.map +1 -1
- package/lib/responses/ResponseStream.d.ts.map +1 -1
- package/lib/responses/ResponseStream.js +21 -11
- package/lib/responses/ResponseStream.js.map +1 -1
- package/lib/responses/ResponseStream.mjs +21 -11
- package/lib/responses/ResponseStream.mjs.map +1 -1
- package/lib/vector-store-polling.d.mts +22 -0
- package/lib/vector-store-polling.d.mts.map +1 -0
- package/lib/vector-store-polling.d.ts +22 -0
- package/lib/vector-store-polling.d.ts.map +1 -0
- package/lib/vector-store-polling.js +24 -0
- package/lib/vector-store-polling.js.map +1 -0
- package/lib/vector-store-polling.mjs +20 -0
- package/lib/vector-store-polling.mjs.map +1 -0
- package/lib/vector-store-upload.d.mts +17 -0
- package/lib/vector-store-upload.d.mts.map +1 -0
- package/lib/vector-store-upload.d.ts +17 -0
- package/lib/vector-store-upload.d.ts.map +1 -0
- package/lib/vector-store-upload.js +37 -0
- package/lib/vector-store-upload.js.map +1 -0
- package/lib/vector-store-upload.mjs +34 -0
- package/lib/vector-store-upload.mjs.map +1 -0
- package/lib/webhook-signature.d.mts +15 -0
- package/lib/webhook-signature.d.mts.map +1 -0
- package/lib/webhook-signature.d.ts +15 -0
- package/lib/webhook-signature.d.ts.map +1 -0
- package/lib/webhook-signature.js +125 -0
- package/lib/webhook-signature.js.map +1 -0
- package/lib/webhook-signature.mjs +121 -0
- package/lib/webhook-signature.mjs.map +1 -0
- package/package.json +14 -1
- package/realtime/internal-base.d.mts +2 -0
- package/realtime/internal-base.d.mts.map +1 -1
- package/realtime/internal-base.d.ts +2 -0
- package/realtime/internal-base.d.ts.map +1 -1
- package/realtime/internal-base.js +15 -0
- package/realtime/internal-base.js.map +1 -1
- package/realtime/internal-base.mjs +14 -0
- package/realtime/internal-base.mjs.map +1 -1
- package/realtime/websocket.d.mts +3 -2
- package/realtime/websocket.d.mts.map +1 -1
- package/realtime/websocket.d.ts +3 -2
- package/realtime/websocket.d.ts.map +1 -1
- package/realtime/websocket.js +90 -26
- package/realtime/websocket.js.map +1 -1
- package/realtime/websocket.mjs +91 -27
- package/realtime/websocket.mjs.map +1 -1
- package/realtime/ws.d.mts.map +1 -1
- package/realtime/ws.d.ts.map +1 -1
- package/realtime/ws.js +9 -1
- package/realtime/ws.js.map +1 -1
- package/realtime/ws.mjs +10 -2
- package/realtime/ws.mjs.map +1 -1
- package/resources/admin/organization/index.d.mts +2 -2
- package/resources/admin/organization/index.d.mts.map +1 -1
- package/resources/admin/organization/index.d.ts +2 -2
- package/resources/admin/organization/index.d.ts.map +1 -1
- package/resources/admin/organization/index.js.map +1 -1
- package/resources/admin/organization/index.mjs.map +1 -1
- package/resources/admin/organization/organization.d.mts +4 -4
- package/resources/admin/organization/organization.d.mts.map +1 -1
- package/resources/admin/organization/organization.d.ts +4 -4
- package/resources/admin/organization/organization.d.ts.map +1 -1
- package/resources/admin/organization/organization.js.map +1 -1
- package/resources/admin/organization/organization.mjs.map +1 -1
- package/resources/admin/organization/projects/index.d.mts +1 -1
- package/resources/admin/organization/projects/index.d.mts.map +1 -1
- package/resources/admin/organization/projects/index.d.ts +1 -1
- package/resources/admin/organization/projects/index.d.ts.map +1 -1
- package/resources/admin/organization/projects/index.js.map +1 -1
- package/resources/admin/organization/projects/index.mjs.map +1 -1
- package/resources/admin/organization/projects/projects.d.mts +22 -5
- package/resources/admin/organization/projects/projects.d.mts.map +1 -1
- package/resources/admin/organization/projects/projects.d.ts +22 -5
- package/resources/admin/organization/projects/projects.d.ts.map +1 -1
- package/resources/admin/organization/projects/projects.js.map +1 -1
- package/resources/admin/organization/projects/projects.mjs.map +1 -1
- package/resources/admin/organization/usage.d.mts +62 -1
- package/resources/admin/organization/usage.d.mts.map +1 -1
- package/resources/admin/organization/usage.d.ts +62 -1
- package/resources/admin/organization/usage.d.ts.map +1 -1
- package/resources/admin/organization/usage.js.map +1 -1
- package/resources/admin/organization/usage.mjs.map +1 -1
- package/resources/beta/responses/internal-base.d.mts.map +1 -1
- package/resources/beta/responses/internal-base.d.ts.map +1 -1
- package/resources/beta/responses/internal-base.js +2 -0
- package/resources/beta/responses/internal-base.js.map +1 -1
- package/resources/beta/responses/internal-base.mjs +2 -0
- package/resources/beta/responses/internal-base.mjs.map +1 -1
- package/resources/beta/responses/responses.d.mts +17 -20
- package/resources/beta/responses/responses.d.mts.map +1 -1
- package/resources/beta/responses/responses.d.ts +17 -20
- package/resources/beta/responses/responses.d.ts.map +1 -1
- package/resources/beta/responses/responses.js.map +1 -1
- package/resources/beta/responses/responses.mjs.map +1 -1
- package/resources/beta/threads/runs/index.d.mts +1 -1
- package/resources/beta/threads/runs/index.d.mts.map +1 -1
- package/resources/beta/threads/runs/index.d.ts +1 -1
- package/resources/beta/threads/runs/index.d.ts.map +1 -1
- package/resources/beta/threads/runs/runs.d.mts.map +1 -1
- package/resources/beta/threads/runs/runs.d.ts.map +1 -1
- package/resources/beta/threads/runs/runs.js +2 -43
- package/resources/beta/threads/runs/runs.js.map +1 -1
- package/resources/beta/threads/runs/runs.mjs +2 -43
- package/resources/beta/threads/runs/runs.mjs.map +1 -1
- package/resources/chat/completions/completions.d.mts +6 -0
- package/resources/chat/completions/completions.d.mts.map +1 -1
- package/resources/chat/completions/completions.d.ts +6 -0
- package/resources/chat/completions/completions.d.ts.map +1 -1
- package/resources/chat/completions/completions.js.map +1 -1
- package/resources/chat/completions/completions.mjs.map +1 -1
- package/resources/embeddings.d.mts.map +1 -1
- package/resources/embeddings.d.ts.map +1 -1
- package/resources/embeddings.js +2 -36
- package/resources/embeddings.js.map +1 -1
- package/resources/embeddings.mjs +2 -36
- package/resources/embeddings.mjs.map +1 -1
- package/resources/files.d.mts.map +1 -1
- package/resources/files.d.ts.map +1 -1
- package/resources/files.js +2 -15
- package/resources/files.js.map +1 -1
- package/resources/files.mjs +2 -15
- package/resources/files.mjs.map +1 -1
- package/resources/images.d.mts +12 -22
- package/resources/images.d.mts.map +1 -1
- package/resources/images.d.ts +12 -22
- package/resources/images.d.ts.map +1 -1
- package/resources/realtime/calls.d.mts +23 -1
- package/resources/realtime/calls.d.mts.map +1 -1
- package/resources/realtime/calls.d.ts +23 -1
- package/resources/realtime/calls.d.ts.map +1 -1
- package/resources/realtime/calls.js +24 -0
- package/resources/realtime/calls.js.map +1 -1
- package/resources/realtime/calls.mjs +24 -0
- package/resources/realtime/calls.mjs.map +1 -1
- package/resources/realtime/index.d.mts +1 -1
- package/resources/realtime/index.d.mts.map +1 -1
- package/resources/realtime/index.d.ts +1 -1
- package/resources/realtime/index.d.ts.map +1 -1
- package/resources/realtime/index.js.map +1 -1
- package/resources/realtime/index.mjs +1 -1
- package/resources/realtime/index.mjs.map +1 -1
- package/resources/realtime/realtime.d.mts +5 -4
- package/resources/realtime/realtime.d.mts.map +1 -1
- package/resources/realtime/realtime.d.ts +5 -4
- package/resources/realtime/realtime.d.ts.map +1 -1
- package/resources/realtime/realtime.js.map +1 -1
- package/resources/realtime/realtime.mjs.map +1 -1
- package/resources/responses/internal-base.d.mts.map +1 -1
- package/resources/responses/internal-base.d.ts.map +1 -1
- package/resources/responses/internal-base.js +2 -0
- package/resources/responses/internal-base.js.map +1 -1
- package/resources/responses/internal-base.mjs +2 -0
- package/resources/responses/internal-base.mjs.map +1 -1
- package/resources/responses/responses.d.mts +17 -20
- package/resources/responses/responses.d.mts.map +1 -1
- package/resources/responses/responses.d.ts +17 -20
- package/resources/responses/responses.d.ts.map +1 -1
- package/resources/responses/responses.js.map +1 -1
- package/resources/responses/responses.mjs.map +1 -1
- package/resources/vector-stores/file-batches.d.mts.map +1 -1
- package/resources/vector-stores/file-batches.d.ts.map +1 -1
- package/resources/vector-stores/file-batches.js +4 -61
- package/resources/vector-stores/file-batches.js.map +1 -1
- package/resources/vector-stores/file-batches.mjs +4 -61
- package/resources/vector-stores/file-batches.mjs.map +1 -1
- package/resources/vector-stores/files.d.mts +1 -1
- package/resources/vector-stores/files.d.mts.map +1 -1
- package/resources/vector-stores/files.d.ts +1 -1
- package/resources/vector-stores/files.d.ts.map +1 -1
- package/resources/vector-stores/files.js +2 -35
- package/resources/vector-stores/files.js.map +1 -1
- package/resources/vector-stores/files.mjs +2 -35
- package/resources/vector-stores/files.mjs.map +1 -1
- package/resources/webhooks/webhooks.d.mts.map +1 -1
- package/resources/webhooks/webhooks.d.ts.map +1 -1
- package/resources/webhooks/webhooks.js +5 -43
- package/resources/webhooks/webhooks.js.map +1 -1
- package/resources/webhooks/webhooks.mjs +5 -43
- package/resources/webhooks/webhooks.mjs.map +1 -1
- package/src/auth/index.ts +6 -1
- package/src/auth/subject-token-providers.ts +196 -4
- package/src/auth/types.ts +24 -0
- package/src/auth/workload-identity-auth.ts +104 -7
- package/src/auth/x509-transport.ts +49 -0
- package/src/azure.ts +22 -1
- package/src/bedrock.ts +49 -5
- package/src/beta/realtime/internal-base.ts +15 -0
- package/src/beta/realtime/websocket.ts +148 -40
- package/src/beta/realtime/ws.ts +31 -13
- package/src/client.ts +536 -92
- package/src/core/EventEmitter.ts +91 -7
- package/src/core/streaming.ts +226 -30
- package/src/helpers/audio.ts +93 -22
- package/src/helpers/standard-schema.ts +50 -16
- package/src/helpers/zod-v3-strict-schema.ts +514 -0
- package/src/helpers/zod.ts +17 -4
- package/src/index.ts +1 -1
- package/src/internal/assistant-stream-delta.ts +33 -10
- package/src/internal/auth/x509-token-exchange.ts +310 -0
- package/src/internal/auth/x509-transport-capability.ts +219 -0
- package/src/internal/auth/x509-transport-registry.ts +118 -0
- package/src/internal/auth/x509-transport-state-browser.ts +36 -0
- package/src/internal/auth/x509-transport-state.cts +36 -0
- package/src/internal/auth/x509-workload-identity-auth.ts +958 -0
- package/src/internal/bedrock.ts +182 -5
- package/src/internal/data-residency.ts +44 -0
- package/src/internal/multipart-encoding.ts +53 -0
- package/src/internal/qs/utils.ts +375 -13
- package/src/internal/request-options.ts +52 -1
- package/src/internal/responses/canonical-output-text.ts +3 -3
- package/src/internal/responses/response-accumulator.ts +411 -24
- package/src/internal/uploads.ts +81 -26
- package/src/internal/utils/env.ts +9 -5
- package/src/internal/ws.ts +24 -3
- package/src/lib/AbstractChatCompletionRunner.ts +33 -6
- package/src/lib/AssistantStream.ts +262 -22
- package/src/lib/ChatCompletionStream.ts +1467 -103
- package/src/lib/EventEmitter.ts +91 -7
- package/src/lib/EventStream.ts +1483 -10
- package/src/lib/ResponsesParser.ts +4 -1
- package/src/lib/Util.ts +7 -5
- package/src/lib/assistant-run-polling.ts +27 -0
- package/src/lib/embeddings.ts +65 -0
- package/src/lib/file-processing.ts +36 -0
- package/src/lib/parser.ts +19 -4
- package/src/lib/polling.ts +144 -0
- package/src/lib/responses/ResponseStream.ts +22 -10
- package/src/lib/vector-store-polling.ts +46 -0
- package/src/lib/vector-store-upload.ts +53 -0
- package/src/lib/webhook-signature.ts +164 -0
- package/src/realtime/internal-base.ts +15 -0
- package/src/realtime/websocket.ts +130 -27
- package/src/realtime/ws.ts +15 -2
- package/src/resources/admin/organization/index.ts +2 -0
- package/src/resources/admin/organization/organization.ts +4 -0
- package/src/resources/admin/organization/projects/index.ts +1 -0
- package/src/resources/admin/organization/projects/projects.ts +37 -4
- package/src/resources/admin/organization/usage.ts +83 -0
- package/src/resources/beta/responses/internal-base.ts +2 -0
- package/src/resources/beta/responses/responses.ts +19 -22
- package/src/resources/beta/threads/runs/index.ts +1 -1
- package/src/resources/beta/threads/runs/runs.ts +2 -45
- package/src/resources/chat/completions/completions.ts +7 -0
- package/src/resources/embeddings.ts +2 -42
- package/src/resources/files.ts +2 -19
- package/src/resources/images.ts +12 -22
- package/src/resources/realtime/api.md +1 -0
- package/src/resources/realtime/calls.ts +46 -0
- package/src/resources/realtime/index.ts +7 -1
- package/src/resources/realtime/realtime.ts +5 -3
- package/src/resources/responses/internal-base.ts +2 -0
- package/src/resources/responses/responses.ts +19 -22
- package/src/resources/vector-stores/file-batches.ts +8 -77
- package/src/resources/vector-stores/files.ts +3 -43
- package/src/resources/webhooks/webhooks.ts +5 -61
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/src/client.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types';
|
|
4
4
|
import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types';
|
|
5
5
|
import { uuid4 } from './internal/utils/uuid';
|
|
6
|
-
import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values';
|
|
6
|
+
import { validatePositiveInteger, isAbsoluteURL, safeJSON, hasOwn } from './internal/utils/values';
|
|
7
7
|
import { sleep } from './internal/utils/sleep';
|
|
8
8
|
export type { Logger, LogLevel } from './internal/utils/log';
|
|
9
9
|
import { castToError, isAbortError } from './internal/errors';
|
|
@@ -13,10 +13,22 @@ import * as Shims from './internal/shims';
|
|
|
13
13
|
import * as Opts from './internal/request-options';
|
|
14
14
|
import { stringifyQuery } from './internal/utils/query';
|
|
15
15
|
import { VERSION } from './version';
|
|
16
|
+
import { resolveDataResidency, type DataResidency } from './internal/data-residency';
|
|
17
|
+
export type { DataResidency } from './internal/data-residency';
|
|
16
18
|
import * as Errors from './core/error';
|
|
17
19
|
import * as Pagination from './core/pagination';
|
|
18
|
-
import type { WorkloadIdentity } from './auth/types';
|
|
20
|
+
import type { WorkloadIdentity, X509WorkloadIdentity } from './auth/types';
|
|
19
21
|
import { WorkloadIdentityAuth } from './auth/workload-identity-auth';
|
|
22
|
+
import {
|
|
23
|
+
X509_API_BASE_URL,
|
|
24
|
+
X509WorkloadIdentityAuth,
|
|
25
|
+
assertX509APIOrigin,
|
|
26
|
+
assertX509RequestOptions,
|
|
27
|
+
isX509WorkloadIdentity,
|
|
28
|
+
snapshotX509RequestOptions,
|
|
29
|
+
} from './internal/auth/x509-workload-identity-auth';
|
|
30
|
+
import type { X509Transport } from './internal/auth/x509-transport-registry';
|
|
31
|
+
import { isTransientX509ConnectionError, markApprovedX509Client } from '#x509-transport-state';
|
|
20
32
|
import { OAuthError, SubjectTokenProviderError } from './core/error';
|
|
21
33
|
import {
|
|
22
34
|
type ConversationCursorPageParams,
|
|
@@ -269,6 +281,8 @@ function isRunningInBrowserOrBrowserWorker(): boolean {
|
|
|
269
281
|
}
|
|
270
282
|
|
|
271
283
|
const WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER = 'workload-identity-auth';
|
|
284
|
+
const inheritedDataResidencySelection = Symbol('inheritedDataResidencySelection');
|
|
285
|
+
type InternalClientOptions = ClientOptions & { [inheritedDataResidencySelection]?: boolean };
|
|
272
286
|
|
|
273
287
|
export type ApiKeySetter = () => Promise<string>;
|
|
274
288
|
|
|
@@ -314,6 +328,14 @@ export interface ClientOptions {
|
|
|
314
328
|
*/
|
|
315
329
|
baseURL?: string | null | undefined;
|
|
316
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Select an OpenAI regional endpoint. This overrides an inherited or environment
|
|
333
|
+
* base URL and is mutually exclusive with an explicit `baseURL` or `provider`.
|
|
334
|
+
* Availability depends on your project and model; no fallback is performed.
|
|
335
|
+
* `null` and `undefined` leave ordinary base URL resolution unchanged.
|
|
336
|
+
*/
|
|
337
|
+
dataResidency?: DataResidency | null | undefined;
|
|
338
|
+
|
|
317
339
|
/**
|
|
318
340
|
* The maximum amount of time (in milliseconds) that the client should wait for a response
|
|
319
341
|
* from the server before timing out a single request.
|
|
@@ -403,7 +425,10 @@ export interface ClientOptions {
|
|
|
403
425
|
* Workload identity configuration for OAuth2 token exchange authentication.
|
|
404
426
|
* Mutually exclusive with `apiKey`.
|
|
405
427
|
*/
|
|
406
|
-
workloadIdentity?: WorkloadIdentity | undefined;
|
|
428
|
+
workloadIdentity?: WorkloadIdentity | X509WorkloadIdentity | undefined;
|
|
429
|
+
|
|
430
|
+
/** Approved, frozen Node.js certificate transport required only for X.509 workload identity. */
|
|
431
|
+
x509Transport?: X509Transport | undefined;
|
|
407
432
|
|
|
408
433
|
/**
|
|
409
434
|
* Configure this client to use a third-party API provider.
|
|
@@ -431,11 +456,25 @@ export class OpenAI {
|
|
|
431
456
|
|
|
432
457
|
private fetch: Fetch;
|
|
433
458
|
#encoder: Opts.RequestEncoder;
|
|
434
|
-
#
|
|
459
|
+
#x509Authentication: X509WorkloadIdentityAuth | undefined;
|
|
460
|
+
#x509Fetch: Fetch | undefined;
|
|
461
|
+
// Preserve an explicit global selection without storing a second routing URL.
|
|
462
|
+
#explicitDataResidency = false;
|
|
463
|
+
#responseAttempts = new WeakMap<
|
|
464
|
+
AbortController,
|
|
465
|
+
{
|
|
466
|
+
timeout: number;
|
|
467
|
+
retriesRemaining: number;
|
|
468
|
+
hasStreamingBody: boolean;
|
|
469
|
+
authentication?: X509WorkloadIdentityAuth;
|
|
470
|
+
helperMethod?: unknown;
|
|
471
|
+
continueRequest?: <T>(operation: () => Promise<T>) => Promise<T>;
|
|
472
|
+
}
|
|
473
|
+
>();
|
|
435
474
|
protected idempotencyHeader?: string;
|
|
436
475
|
protected _options: ClientOptions;
|
|
437
476
|
private _provider: ProviderRuntime | undefined;
|
|
438
|
-
private _workloadIdentityAuth?: WorkloadIdentityAuth;
|
|
477
|
+
private _workloadIdentityAuth?: WorkloadIdentityAuth | X509WorkloadIdentityAuth;
|
|
439
478
|
|
|
440
479
|
/**
|
|
441
480
|
* API Client for interfacing with the OpenAI API.
|
|
@@ -456,30 +495,38 @@ export class OpenAI {
|
|
|
456
495
|
* @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers.
|
|
457
496
|
*/
|
|
458
497
|
constructor(clientOptions: ClientOptions = {}) {
|
|
498
|
+
const residencyBaseURL = resolveDataResidency(clientOptions);
|
|
459
499
|
const provider = clientOptions.provider;
|
|
460
|
-
if (provider) {
|
|
461
|
-
const conflictingOptions = (['apiKey', 'adminAPIKey', 'workloadIdentity', 'baseURL'] as const).filter(
|
|
462
|
-
(key) => clientOptions[key] != null,
|
|
463
|
-
);
|
|
464
|
-
if (conflictingOptions.length) {
|
|
465
|
-
throw new Errors.OpenAIError(
|
|
466
|
-
`The \`provider\` option cannot be used with ${conflictingOptions
|
|
467
|
-
.map((key) => `\`${key}\``)
|
|
468
|
-
.join(', ')}. Configure authentication and the base URL through the provider instead.`,
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
500
|
const {
|
|
474
501
|
baseURL = provider ? null : readEnv('OPENAI_BASE_URL'),
|
|
502
|
+
dataResidency: _dataResidency,
|
|
503
|
+
[inheritedDataResidencySelection]: inheritedResidencySelection = false,
|
|
475
504
|
apiKey = provider ? null : (readEnv('OPENAI_API_KEY') ?? null),
|
|
476
505
|
adminAPIKey = provider ? null : (readEnv('OPENAI_ADMIN_KEY') ?? null),
|
|
477
506
|
organization = provider ? null : (readEnv('OPENAI_ORG_ID') ?? null),
|
|
478
507
|
project = provider ? null : (readEnv('OPENAI_PROJECT_ID') ?? null),
|
|
479
508
|
webhookSecret = readEnv('OPENAI_WEBHOOK_SECRET') ?? null,
|
|
480
509
|
workloadIdentity,
|
|
510
|
+
x509Transport,
|
|
481
511
|
...opts
|
|
482
|
-
} = clientOptions;
|
|
512
|
+
} = clientOptions as InternalClientOptions;
|
|
513
|
+
if (provider) {
|
|
514
|
+
const conflictingOptions = (
|
|
515
|
+
['apiKey', 'adminAPIKey', 'workloadIdentity', 'x509Transport', 'baseURL', 'dataResidency'] as const
|
|
516
|
+
).filter((key) => (key === 'workloadIdentity' ? workloadIdentity : clientOptions[key]) != null);
|
|
517
|
+
if (conflictingOptions.length) {
|
|
518
|
+
throw new Errors.OpenAIError(
|
|
519
|
+
`The \`provider\` option cannot be used with ${conflictingOptions
|
|
520
|
+
.map((key) => `\`${key}\``)
|
|
521
|
+
.join(', ')}. Configure authentication and the base URL through the provider instead.`,
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
const identity = isX509WorkloadIdentity(workloadIdentity)
|
|
526
|
+
? { x509: workloadIdentity, legacy: undefined }
|
|
527
|
+
: { x509: undefined, legacy: workloadIdentity };
|
|
528
|
+
const x509Identity = identity.x509;
|
|
529
|
+
const usesX509Identity = x509Identity !== undefined;
|
|
483
530
|
const providerRuntime = provider ? configureProvider(provider) : undefined;
|
|
484
531
|
const options: ClientOptions = {
|
|
485
532
|
apiKey,
|
|
@@ -488,11 +535,40 @@ export class OpenAI {
|
|
|
488
535
|
project,
|
|
489
536
|
webhookSecret,
|
|
490
537
|
workloadIdentity,
|
|
538
|
+
x509Transport,
|
|
491
539
|
provider,
|
|
492
540
|
...opts,
|
|
493
|
-
baseURL:
|
|
541
|
+
baseURL:
|
|
542
|
+
providerRuntime?.baseURL ??
|
|
543
|
+
residencyBaseURL ??
|
|
544
|
+
(baseURL || (usesX509Identity ? X509_API_BASE_URL : `https://api.openai.com/v1`)),
|
|
494
545
|
};
|
|
495
546
|
|
|
547
|
+
if (x509Transport && !usesX509Identity) {
|
|
548
|
+
throw new Errors.OpenAIError('An X.509 transport requires an X.509 workload identity.');
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (usesX509Identity) {
|
|
552
|
+
if (residencyBaseURL !== undefined || inheritedResidencySelection) {
|
|
553
|
+
throw new Errors.OpenAIError('X.509 workload identity does not support data residency selection.');
|
|
554
|
+
}
|
|
555
|
+
if (clientOptions.fetch !== undefined) {
|
|
556
|
+
throw new Errors.OpenAIError(
|
|
557
|
+
'X.509 workload identity does not support a custom fetch implementation.',
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
assertX509APIOrigin(options.baseURL!);
|
|
561
|
+
assertX509RequestOptions(options.fetchOptions);
|
|
562
|
+
if (
|
|
563
|
+
this.fetchWithAuth !== OpenAI.prototype.fetchWithAuth ||
|
|
564
|
+
this.fetchWithTimeout !== OpenAI.prototype.fetchWithTimeout
|
|
565
|
+
) {
|
|
566
|
+
throw new Errors.OpenAIError(
|
|
567
|
+
'X.509 workload identity does not support overridden fetch dispatch hooks.',
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
496
572
|
if (apiKey && workloadIdentity) {
|
|
497
573
|
throw new Errors.OpenAIError('The `apiKey` and `workloadIdentity` options are mutually exclusive');
|
|
498
574
|
}
|
|
@@ -510,6 +586,7 @@ export class OpenAI {
|
|
|
510
586
|
}
|
|
511
587
|
|
|
512
588
|
this.baseURL = options.baseURL!;
|
|
589
|
+
this.#explicitDataResidency = residencyBaseURL !== undefined || inheritedResidencySelection;
|
|
513
590
|
this.timeout = options.timeout ?? OpenAI.DEFAULT_TIMEOUT; /* 10 minutes */
|
|
514
591
|
this.logger = options.logger ?? console;
|
|
515
592
|
const defaultLogLevel = 'warn';
|
|
@@ -539,8 +616,15 @@ export class OpenAI {
|
|
|
539
616
|
this._options = options;
|
|
540
617
|
this._provider = providerRuntime;
|
|
541
618
|
|
|
542
|
-
if (
|
|
543
|
-
|
|
619
|
+
if (x509Identity) {
|
|
620
|
+
const authentication = new X509WorkloadIdentityAuth(x509Identity, x509Transport, organization, project);
|
|
621
|
+
this._workloadIdentityAuth = authentication;
|
|
622
|
+
this.#x509Authentication = authentication;
|
|
623
|
+
this.#x509Fetch = authentication.fetch();
|
|
624
|
+
this.fetch = this.#x509Fetch;
|
|
625
|
+
markApprovedX509Client(this);
|
|
626
|
+
} else if (identity.legacy) {
|
|
627
|
+
this._workloadIdentityAuth = new WorkloadIdentityAuth(identity.legacy, this.fetch);
|
|
544
628
|
}
|
|
545
629
|
|
|
546
630
|
this.apiKey = typeof apiKey === 'string' ? apiKey : null;
|
|
@@ -554,8 +638,10 @@ export class OpenAI {
|
|
|
554
638
|
* Create a new client instance re-using the same options given to the current client with optional overriding.
|
|
555
639
|
*/
|
|
556
640
|
withOptions(options: Partial<ClientOptions>): this {
|
|
641
|
+
const residencyBaseURL = resolveDataResidency(options);
|
|
557
642
|
const inheritedProvider = this._options.provider;
|
|
558
643
|
const provider = options.provider ?? inheritedProvider;
|
|
644
|
+
const x509Authentication = this.#x509Authentication;
|
|
559
645
|
const inheritedOptions: ClientOptions = {
|
|
560
646
|
...this._options,
|
|
561
647
|
baseURL: this.baseURL,
|
|
@@ -563,19 +649,38 @@ export class OpenAI {
|
|
|
563
649
|
timeout: this.timeout,
|
|
564
650
|
logger: this.logger,
|
|
565
651
|
logLevel: this.logLevel,
|
|
566
|
-
fetch: this.fetch,
|
|
652
|
+
fetch: this.#x509Authentication ? undefined : this.fetch,
|
|
567
653
|
fetchOptions: this.fetchOptions,
|
|
568
654
|
apiKey: this._options.apiKey,
|
|
569
655
|
adminAPIKey: this.adminAPIKey,
|
|
570
|
-
workloadIdentity: this._options.workloadIdentity,
|
|
656
|
+
workloadIdentity: x509Authentication?.identitySnapshot() ?? this._options.workloadIdentity,
|
|
657
|
+
x509Transport: this._options.x509Transport,
|
|
571
658
|
organization: this.organization,
|
|
572
659
|
project: this.project,
|
|
573
660
|
webhookSecret: this.webhookSecret,
|
|
574
661
|
};
|
|
662
|
+
const currentlyX509 = x509Authentication !== undefined;
|
|
663
|
+
const nextIdentity = hasOwn(options, 'workloadIdentity')
|
|
664
|
+
? options.workloadIdentity
|
|
665
|
+
: inheritedOptions.workloadIdentity;
|
|
666
|
+
const nextX509 = isX509WorkloadIdentity(nextIdentity);
|
|
667
|
+
if (currentlyX509 !== nextX509) {
|
|
668
|
+
delete inheritedOptions.fetch;
|
|
669
|
+
delete inheritedOptions.baseURL;
|
|
670
|
+
if (nextX509) {
|
|
671
|
+
inheritedOptions.apiKey = null;
|
|
672
|
+
} else {
|
|
673
|
+
delete inheritedOptions.x509Transport;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
if (residencyBaseURL !== undefined) {
|
|
677
|
+
delete inheritedOptions.baseURL;
|
|
678
|
+
}
|
|
575
679
|
if (provider) {
|
|
576
680
|
delete inheritedOptions.apiKey;
|
|
577
681
|
delete inheritedOptions.adminAPIKey;
|
|
578
682
|
delete inheritedOptions.workloadIdentity;
|
|
683
|
+
delete inheritedOptions.x509Transport;
|
|
579
684
|
delete inheritedOptions.baseURL;
|
|
580
685
|
if (provider !== inheritedProvider) {
|
|
581
686
|
delete inheritedOptions.organization;
|
|
@@ -584,11 +689,27 @@ export class OpenAI {
|
|
|
584
689
|
}
|
|
585
690
|
}
|
|
586
691
|
|
|
587
|
-
const
|
|
692
|
+
const clientOptions: InternalClientOptions = {
|
|
588
693
|
...inheritedOptions,
|
|
589
694
|
...options,
|
|
590
695
|
provider,
|
|
591
|
-
|
|
696
|
+
[inheritedDataResidencySelection]:
|
|
697
|
+
this.#explicitDataResidency &&
|
|
698
|
+
residencyBaseURL === undefined &&
|
|
699
|
+
!hasOwn(options, 'baseURL') &&
|
|
700
|
+
!provider,
|
|
701
|
+
};
|
|
702
|
+
const client = new (this.constructor as any as new (props: ClientOptions) => typeof this)(clientOptions);
|
|
703
|
+
if (
|
|
704
|
+
this.#x509Authentication &&
|
|
705
|
+
client.#x509Authentication &&
|
|
706
|
+
this.baseURL === client.baseURL &&
|
|
707
|
+
this.#x509Authentication.matches(client.#x509Authentication)
|
|
708
|
+
) {
|
|
709
|
+
client._workloadIdentityAuth = this.#x509Authentication;
|
|
710
|
+
client.#x509Authentication = this.#x509Authentication;
|
|
711
|
+
client.#x509Fetch = this.#x509Fetch;
|
|
712
|
+
}
|
|
592
713
|
return client;
|
|
593
714
|
}
|
|
594
715
|
|
|
@@ -596,7 +717,11 @@ export class OpenAI {
|
|
|
596
717
|
* Check whether the base URL is set to its default.
|
|
597
718
|
*/
|
|
598
719
|
#baseURLOverridden(): boolean {
|
|
599
|
-
return
|
|
720
|
+
return (
|
|
721
|
+
this.#explicitDataResidency ||
|
|
722
|
+
this._provider !== undefined ||
|
|
723
|
+
this.baseURL !== 'https://api.openai.com/v1'
|
|
724
|
+
);
|
|
600
725
|
}
|
|
601
726
|
|
|
602
727
|
protected defaultQuery(): Record<string, string | undefined> | undefined {
|
|
@@ -633,6 +758,14 @@ export class OpenAI {
|
|
|
633
758
|
adminAPIKeyAuth: true,
|
|
634
759
|
},
|
|
635
760
|
): Promise<NullableHeaders | undefined> {
|
|
761
|
+
const authentication = this.#x509Authentication ?? this._workloadIdentityAuth;
|
|
762
|
+
if (
|
|
763
|
+
authentication instanceof X509WorkloadIdentityAuth &&
|
|
764
|
+
schemes.adminAPIKeyAuth &&
|
|
765
|
+
this.adminAPIKey !== null
|
|
766
|
+
) {
|
|
767
|
+
return await this.adminAPIKeyAuth(opts);
|
|
768
|
+
}
|
|
636
769
|
return buildHeaders([
|
|
637
770
|
schemes.bearerAuth ? await this.bearerAuth(opts) : null,
|
|
638
771
|
schemes.adminAPIKeyAuth ? await this.adminAPIKeyAuth(opts) : null,
|
|
@@ -640,8 +773,40 @@ export class OpenAI {
|
|
|
640
773
|
}
|
|
641
774
|
|
|
642
775
|
protected async bearerAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
|
|
643
|
-
|
|
644
|
-
|
|
776
|
+
const authentication = this.#x509Authentication ?? this._workloadIdentityAuth;
|
|
777
|
+
if (authentication) {
|
|
778
|
+
if (authentication instanceof X509WorkloadIdentityAuth) {
|
|
779
|
+
if (
|
|
780
|
+
authentication === this._workloadIdentityAuth &&
|
|
781
|
+
(this.fetchWithAuth !== OpenAI.prototype.fetchWithAuth ||
|
|
782
|
+
this.fetchWithTimeout !== OpenAI.prototype.fetchWithTimeout)
|
|
783
|
+
) {
|
|
784
|
+
throw new Errors.OpenAIError(
|
|
785
|
+
'X.509 workload identity does not support overridden fetch dispatch hooks.',
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
const snapshots = authentication.headerSnapshots();
|
|
789
|
+
if (
|
|
790
|
+
!X509WorkloadIdentityAuth.shouldAuthenticate(
|
|
791
|
+
opts,
|
|
792
|
+
snapshots.defaultHeaders,
|
|
793
|
+
snapshots.requestHeaders,
|
|
794
|
+
)
|
|
795
|
+
) {
|
|
796
|
+
return undefined;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
const token =
|
|
800
|
+
authentication instanceof X509WorkloadIdentityAuth
|
|
801
|
+
? await authentication.getToken(opts, {
|
|
802
|
+
apiURL: authentication.requestAPIURL(),
|
|
803
|
+
...authentication.headerSnapshots(),
|
|
804
|
+
...authentication.requestSnapshot(),
|
|
805
|
+
signal: authentication.effectiveSignal(),
|
|
806
|
+
...authentication.tenantSnapshot(),
|
|
807
|
+
})
|
|
808
|
+
: await authentication.getToken();
|
|
809
|
+
return buildHeaders([{ Authorization: `Bearer ${token}` }]);
|
|
645
810
|
}
|
|
646
811
|
if (this.apiKey == null) {
|
|
647
812
|
return undefined;
|
|
@@ -788,7 +953,14 @@ export class OpenAI {
|
|
|
788
953
|
options: PromiseOrValue<FinalRequestOptions>,
|
|
789
954
|
remainingRetries: number | null = null,
|
|
790
955
|
): APIPromise<Rsp> {
|
|
791
|
-
|
|
956
|
+
const authentication = this.#x509Authentication ?? this._workloadIdentityAuth;
|
|
957
|
+
const request =
|
|
958
|
+
authentication instanceof X509WorkloadIdentityAuth
|
|
959
|
+
? Promise.resolve(options).then((resolved) =>
|
|
960
|
+
authentication.runRequest(() => this.makeRequest(resolved, remainingRetries, undefined), this),
|
|
961
|
+
)
|
|
962
|
+
: this.makeRequest(options, remainingRetries, undefined);
|
|
963
|
+
return this.responsePromise<Rsp>(request);
|
|
792
964
|
}
|
|
793
965
|
|
|
794
966
|
private responsePromise<Rsp>(
|
|
@@ -796,7 +968,10 @@ export class OpenAI {
|
|
|
796
968
|
parse: (client: OpenAI, props: APIResponseProps) => Promise<any> = (client, props) =>
|
|
797
969
|
this.parseResponseWithTimeout<Rsp>(client, props),
|
|
798
970
|
): APIPromise<Rsp> {
|
|
799
|
-
const promise = new APIPromise<Rsp>(this, request,
|
|
971
|
+
const promise = new APIPromise<Rsp>(this, request, (client, props) => {
|
|
972
|
+
const resume = this.#responseAttempts.get(props.controller)?.continueRequest;
|
|
973
|
+
return resume ? resume(() => parse(client, props)) : parse(client, props);
|
|
974
|
+
});
|
|
800
975
|
|
|
801
976
|
// A body timeout can retry after the original raw response has arrived. Wait for
|
|
802
977
|
// parsing before selecting the response so withResponse() reports the retry.
|
|
@@ -826,16 +1001,31 @@ export class OpenAI {
|
|
|
826
1001
|
while (true) {
|
|
827
1002
|
const attempt = this.#responseAttempts.get(props.controller);
|
|
828
1003
|
const timeout = attempt?.timeout ?? props.options.timeout ?? this.timeout;
|
|
829
|
-
const
|
|
830
|
-
const callerSignal = props.options.signal;
|
|
1004
|
+
const x509Authentication = attempt?.authentication;
|
|
1005
|
+
const callerSignal = x509Authentication ? props.controller.signal : props.options.signal;
|
|
1006
|
+
const abortError = () =>
|
|
1007
|
+
x509Authentication && callerSignal
|
|
1008
|
+
? this._makeUserAbortError(callerSignal)
|
|
1009
|
+
: new Errors.APIUserAbortError();
|
|
1010
|
+
let remaining: number;
|
|
1011
|
+
try {
|
|
1012
|
+
remaining =
|
|
1013
|
+
x509Authentication?.remainingTimeout(props.options, timeout) ??
|
|
1014
|
+
Math.max(0, props.startTime + timeout - Date.now());
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
const cancellation = callerSignal?.aborted ? abortError() : undefined;
|
|
1017
|
+
props.controller.abort();
|
|
1018
|
+
void Shims.CancelReadableStream(props.response.body).catch(() => undefined);
|
|
1019
|
+
throw cancellation ?? error;
|
|
1020
|
+
}
|
|
831
1021
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
832
1022
|
let abortListener: (() => void) | undefined;
|
|
833
1023
|
let timedOut = false;
|
|
834
1024
|
|
|
835
1025
|
try {
|
|
836
1026
|
// Tool runners preserve a completed buffered turn before cancellation stops the next request.
|
|
837
|
-
if (callerSignal?.aborted &&
|
|
838
|
-
throw
|
|
1027
|
+
if (callerSignal?.aborted && attempt?.helperMethod !== 'runTools') {
|
|
1028
|
+
throw abortError();
|
|
839
1029
|
}
|
|
840
1030
|
|
|
841
1031
|
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
@@ -846,23 +1036,34 @@ export class OpenAI {
|
|
|
846
1036
|
}, remaining);
|
|
847
1037
|
|
|
848
1038
|
if (callerSignal) {
|
|
849
|
-
abortListener = () =>
|
|
1039
|
+
abortListener = () => {
|
|
1040
|
+
if (!timedOut) reject(abortError());
|
|
1041
|
+
};
|
|
850
1042
|
callerSignal.addEventListener('abort', abortListener, { once: true });
|
|
851
1043
|
}
|
|
852
1044
|
});
|
|
853
1045
|
|
|
854
1046
|
return await Promise.race([defaultParseResponse<Rsp>(client, props), timeoutPromise]);
|
|
855
1047
|
} catch (error) {
|
|
856
|
-
if (callerSignal?.aborted) {
|
|
857
|
-
throw
|
|
1048
|
+
if (callerSignal?.aborted && !timedOut) {
|
|
1049
|
+
throw abortError();
|
|
858
1050
|
}
|
|
859
1051
|
if (!timedOut) {
|
|
1052
|
+
if (x509Authentication && error instanceof SyntaxError) {
|
|
1053
|
+
throw new SyntaxError('X.509 workload identity API response contains invalid JSON.');
|
|
1054
|
+
}
|
|
1055
|
+
if (x509Authentication && !(error instanceof Errors.OpenAIError)) {
|
|
1056
|
+
throw new Errors.APIConnectionError({
|
|
1057
|
+
message: 'X.509 workload identity API response body could not be read.',
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
860
1060
|
throw error;
|
|
861
1061
|
}
|
|
862
1062
|
|
|
863
1063
|
const retriesRemaining = attempt?.retriesRemaining ?? 0;
|
|
864
1064
|
if (
|
|
865
1065
|
!retriesRemaining ||
|
|
1066
|
+
attempt?.hasStreamingBody ||
|
|
866
1067
|
props.options.__metadata?.['hasStreamingBody'] ||
|
|
867
1068
|
((globalThis as any).ReadableStream &&
|
|
868
1069
|
props.options.body instanceof (globalThis as any).ReadableStream) ||
|
|
@@ -893,6 +1094,52 @@ export class OpenAI {
|
|
|
893
1094
|
}
|
|
894
1095
|
}
|
|
895
1096
|
|
|
1097
|
+
/** Keeps terminal X.509 error-body consumption inside the original logical request deadline. */
|
|
1098
|
+
private async readX509ResponseError(
|
|
1099
|
+
response: Response,
|
|
1100
|
+
options: FinalRequestOptions,
|
|
1101
|
+
timeout: number,
|
|
1102
|
+
controller: AbortController,
|
|
1103
|
+
authentication: X509WorkloadIdentityAuth,
|
|
1104
|
+
): Promise<string> {
|
|
1105
|
+
const deadline = new AbortController();
|
|
1106
|
+
const callerSignal = controller.signal;
|
|
1107
|
+
let timedOut = false;
|
|
1108
|
+
const cancel = () => deadline.abort(callerSignal.reason);
|
|
1109
|
+
callerSignal.addEventListener('abort', cancel, { once: true });
|
|
1110
|
+
if (callerSignal.aborted) {
|
|
1111
|
+
cancel();
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
try {
|
|
1115
|
+
const remaining = authentication.remainingTimeout(options, timeout);
|
|
1116
|
+
const expiration = authentication.waitForRetry(remaining, deadline.signal).then(() => {
|
|
1117
|
+
throw new Errors.APIConnectionTimeoutError();
|
|
1118
|
+
});
|
|
1119
|
+
const body = await Promise.race([
|
|
1120
|
+
response.text().catch(() => 'X.509 workload identity API response body could not be read.'),
|
|
1121
|
+
expiration,
|
|
1122
|
+
]);
|
|
1123
|
+
if (callerSignal.aborted) {
|
|
1124
|
+
throw this._makeUserAbortError(callerSignal);
|
|
1125
|
+
}
|
|
1126
|
+
return body;
|
|
1127
|
+
} catch (error) {
|
|
1128
|
+
if (error instanceof Errors.APIConnectionTimeoutError) {
|
|
1129
|
+
timedOut = !callerSignal.aborted;
|
|
1130
|
+
controller.abort();
|
|
1131
|
+
void Shims.CancelReadableStream(response.body).catch(() => undefined);
|
|
1132
|
+
}
|
|
1133
|
+
if (callerSignal.aborted && !timedOut) {
|
|
1134
|
+
throw this._makeUserAbortError(callerSignal);
|
|
1135
|
+
}
|
|
1136
|
+
throw error;
|
|
1137
|
+
} finally {
|
|
1138
|
+
callerSignal.removeEventListener('abort', cancel);
|
|
1139
|
+
deadline.abort();
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
896
1143
|
private async makeRequest(
|
|
897
1144
|
optionsInput: PromiseOrValue<FinalRequestOptions>,
|
|
898
1145
|
retriesRemaining: number | null,
|
|
@@ -906,18 +1153,85 @@ export class OpenAI {
|
|
|
906
1153
|
|
|
907
1154
|
await this.prepareOptions(options);
|
|
908
1155
|
|
|
909
|
-
const
|
|
910
|
-
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
1156
|
+
const x509Authentication = this.#x509Authentication;
|
|
1157
|
+
x509Authentication?.beginRequestPlanning();
|
|
1158
|
+
let built: { req: FinalizedRequestInit; url: string; timeout: number };
|
|
1159
|
+
try {
|
|
1160
|
+
const candidate = await this.buildRequest(options, {
|
|
1161
|
+
retryCount: maxRetries - retriesRemaining,
|
|
1162
|
+
});
|
|
1163
|
+
built = { req: candidate.req, url: candidate.url, timeout: candidate.timeout };
|
|
1164
|
+
if (x509Authentication) {
|
|
1165
|
+
validatePositiveInteger('timeout', built.timeout);
|
|
1166
|
+
x509Authentication.authorizePlannedRequest(built.url, built.req, built.timeout);
|
|
1167
|
+
if (X509WorkloadIdentityAuth.isStreamingRequestBody(built.req.body)) {
|
|
1168
|
+
options.__metadata = { ...options.__metadata, hasStreamingBody: true };
|
|
1169
|
+
}
|
|
1170
|
+
await this.prepareRequest(built.req, { url: built.url, options });
|
|
1171
|
+
await this._provider?.prepareRequest?.(built.req, { url: built.url, options });
|
|
1172
|
+
x509Authentication.beginRequestPlanning();
|
|
1173
|
+
x509Authentication.authorizePlannedRequest(built.url, built.req, built.timeout, true);
|
|
1174
|
+
if (X509WorkloadIdentityAuth.isStreamingRequestBody(built.req.body)) {
|
|
1175
|
+
options.__metadata = { ...options.__metadata, hasStreamingBody: true };
|
|
1176
|
+
}
|
|
1177
|
+
const callerSignal = x509Authentication.requestSnapshot().signal;
|
|
1178
|
+
if (callerSignal?.aborted || built.req.signal?.aborted) {
|
|
1179
|
+
throw this._makeUserAbortError(callerSignal?.aborted ? callerSignal : built.req.signal!);
|
|
1180
|
+
}
|
|
1181
|
+
x509Authentication.setEffectiveSignal(
|
|
1182
|
+
built.req.signal || callerSignal
|
|
1183
|
+
? createRequestController(built.req.signal ?? callerSignal, callerSignal).signal
|
|
1184
|
+
: undefined,
|
|
1185
|
+
);
|
|
1186
|
+
x509Authentication.beginRequestNetwork();
|
|
1187
|
+
const security = options.__security ?? { bearerAuth: true };
|
|
1188
|
+
const authenticationHeaders = await this.authHeaders(options, security);
|
|
1189
|
+
const suppliedHeaders = x509Authentication.headerSnapshots();
|
|
1190
|
+
const supplied = buildHeaders([suppliedHeaders.defaultHeaders, suppliedHeaders.requestHeaders]);
|
|
1191
|
+
for (const [name, value] of authenticationHeaders?.values ?? []) {
|
|
1192
|
+
if (!supplied.nulls.has(name) && !built.req.headers.has(name)) {
|
|
1193
|
+
built.req.headers.set(name, value);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
this.validateHeaders(buildHeaders([supplied, built.req.headers]), security);
|
|
1197
|
+
}
|
|
1198
|
+
} catch (error) {
|
|
1199
|
+
x509Authentication?.retireRequestBody();
|
|
1200
|
+
if (
|
|
1201
|
+
x509Authentication &&
|
|
1202
|
+
retriesRemaining &&
|
|
1203
|
+
!options.__metadata?.['hasStreamingBody'] &&
|
|
1204
|
+
X509WorkloadIdentityAuth.isRetryableFailure(error)
|
|
1205
|
+
) {
|
|
1206
|
+
return await this.retryRequest(
|
|
1207
|
+
options,
|
|
1208
|
+
retriesRemaining,
|
|
1209
|
+
retryOfRequestLogID ?? 'x509-token-exchange',
|
|
1210
|
+
X509WorkloadIdentityAuth.retryHeaders(error),
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
throw error;
|
|
1214
|
+
}
|
|
1215
|
+
const { req, url } = built;
|
|
1216
|
+
const timeout = x509Authentication
|
|
1217
|
+
? Math.min(built.timeout, x509Authentication.requestSnapshot().timeout)
|
|
1218
|
+
: built.timeout;
|
|
1219
|
+
x509Authentication?.bindRequest(options, req, this.adminAPIKey);
|
|
1220
|
+
let hasStreamingBody = options.__metadata?.['hasStreamingBody'] === true;
|
|
1221
|
+
|
|
1222
|
+
if (!x509Authentication) {
|
|
1223
|
+
await this.prepareRequest(req, { url, options });
|
|
1224
|
+
await this._provider?.prepareRequest?.(req, { url, options });
|
|
1225
|
+
}
|
|
1226
|
+
x509Authentication?.adoptRequestHeaders(req);
|
|
1227
|
+
if (x509Authentication && X509WorkloadIdentityAuth.isStreamingRequestBody(req.body)) {
|
|
1228
|
+
hasStreamingBody = true;
|
|
1229
|
+
}
|
|
916
1230
|
|
|
917
1231
|
/** Not an API request ID, just for correlating local log entries. */
|
|
918
1232
|
const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
|
|
919
1233
|
const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
|
|
920
|
-
const startTime = Date.now();
|
|
1234
|
+
const startTime = x509Authentication?.requestStartedAt(options) ?? Date.now();
|
|
921
1235
|
|
|
922
1236
|
loggerFor(this).debug(
|
|
923
1237
|
`[${requestLogID}] sending request`,
|
|
@@ -925,28 +1239,36 @@ export class OpenAI {
|
|
|
925
1239
|
retryOfRequestLogID,
|
|
926
1240
|
method: options.method,
|
|
927
1241
|
url,
|
|
928
|
-
options,
|
|
1242
|
+
options: x509Authentication ? { body: req.body, ...x509Authentication.requestSnapshot() } : options,
|
|
929
1243
|
headers: req.headers,
|
|
930
1244
|
}),
|
|
931
1245
|
);
|
|
932
1246
|
|
|
933
|
-
|
|
934
|
-
|
|
1247
|
+
const callerSignal = x509Authentication ? x509Authentication.requestSnapshot().signal : options.signal;
|
|
1248
|
+
if (callerSignal?.aborted || req.signal?.aborted) {
|
|
1249
|
+
throw this._makeUserAbortError(callerSignal?.aborted ? callerSignal : req.signal!);
|
|
935
1250
|
}
|
|
936
|
-
|
|
937
1251
|
const security = options.__security ?? { bearerAuth: true };
|
|
938
1252
|
// Request hooks may replace the caller signal before it reaches fetch.
|
|
939
1253
|
const controller =
|
|
940
|
-
this.fetchWithTimeout === OpenAI.prototype.fetchWithTimeout
|
|
941
|
-
? createRequestController(
|
|
1254
|
+
x509Authentication || this.fetchWithTimeout === OpenAI.prototype.fetchWithTimeout
|
|
1255
|
+
? createRequestController(
|
|
1256
|
+
req.signal ?? (x509Authentication ? callerSignal : undefined),
|
|
1257
|
+
x509Authentication ? callerSignal : undefined,
|
|
1258
|
+
)
|
|
942
1259
|
: new AbortController();
|
|
943
|
-
const
|
|
1260
|
+
const remainingTimeout = x509Authentication?.remainingTimeout(options, timeout) ?? timeout;
|
|
1261
|
+
const fetchWithAuth = x509Authentication ? OpenAI.prototype.fetchWithAuth : this.fetchWithAuth;
|
|
1262
|
+
x509Authentication?.releaseRequestBody(req.body);
|
|
1263
|
+
const response = await fetchWithAuth
|
|
1264
|
+
.call(this, url, req, remainingTimeout, controller, security)
|
|
1265
|
+
.catch(castToError);
|
|
944
1266
|
const headersTime = Date.now();
|
|
945
1267
|
|
|
946
1268
|
if (response instanceof globalThis.Error) {
|
|
947
1269
|
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
948
|
-
if (
|
|
949
|
-
throw this._makeUserAbortError(
|
|
1270
|
+
if (callerSignal?.aborted || req.signal?.aborted) {
|
|
1271
|
+
throw this._makeUserAbortError(callerSignal?.aborted ? callerSignal : req.signal!);
|
|
950
1272
|
}
|
|
951
1273
|
// detect native connection timeout errors
|
|
952
1274
|
// deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
|
|
@@ -955,7 +1277,11 @@ export class OpenAI {
|
|
|
955
1277
|
const isTimeout =
|
|
956
1278
|
isAbortError(response) ||
|
|
957
1279
|
/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
|
|
958
|
-
if (
|
|
1280
|
+
if (
|
|
1281
|
+
retriesRemaining &&
|
|
1282
|
+
!hasStreamingBody &&
|
|
1283
|
+
(!x509Authentication || isTransientX509ConnectionError(response))
|
|
1284
|
+
) {
|
|
959
1285
|
loggerFor(this).info(
|
|
960
1286
|
`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`,
|
|
961
1287
|
);
|
|
@@ -965,7 +1291,7 @@ export class OpenAI {
|
|
|
965
1291
|
retryOfRequestLogID,
|
|
966
1292
|
url,
|
|
967
1293
|
durationMs: headersTime - startTime,
|
|
968
|
-
message: response.message,
|
|
1294
|
+
message: x509Authentication ? 'X.509 workload identity API connection failed.' : response.message,
|
|
969
1295
|
}),
|
|
970
1296
|
);
|
|
971
1297
|
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
|
|
@@ -982,7 +1308,7 @@ export class OpenAI {
|
|
|
982
1308
|
retryOfRequestLogID,
|
|
983
1309
|
url,
|
|
984
1310
|
durationMs: headersTime - startTime,
|
|
985
|
-
message: response.message,
|
|
1311
|
+
message: x509Authentication ? 'X.509 workload identity API connection failed.' : response.message,
|
|
986
1312
|
}),
|
|
987
1313
|
);
|
|
988
1314
|
if (response instanceof OAuthError || response instanceof SubjectTokenProviderError) {
|
|
@@ -1002,8 +1328,14 @@ export class OpenAI {
|
|
|
1002
1328
|
'configure a matching undici fetch and fetchOptions.dispatcher with an Agent whose headersTimeout is at least the SDK timeout.',
|
|
1003
1329
|
})
|
|
1004
1330
|
: new Errors.APIConnectionTimeoutError();
|
|
1331
|
+
if (x509Authentication) {
|
|
1332
|
+
throw new Errors.APIConnectionTimeoutError();
|
|
1333
|
+
}
|
|
1005
1334
|
throw Object.assign(timeoutError, { cause: response });
|
|
1006
1335
|
}
|
|
1336
|
+
if (x509Authentication) {
|
|
1337
|
+
throw new Errors.APIConnectionError({ message: 'X.509 workload identity API connection failed.' });
|
|
1338
|
+
}
|
|
1007
1339
|
throw new Errors.APIConnectionError({
|
|
1008
1340
|
message: getConnectionErrorMessage(response),
|
|
1009
1341
|
cause: response,
|
|
@@ -1019,35 +1351,57 @@ export class OpenAI {
|
|
|
1019
1351
|
} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
1020
1352
|
|
|
1021
1353
|
if (!response.ok) {
|
|
1354
|
+
const rejectedX509Credential =
|
|
1355
|
+
response.status === 401 &&
|
|
1356
|
+
x509Authentication &&
|
|
1357
|
+
security.bearerAuth &&
|
|
1358
|
+
x509Authentication.usedWorkloadToken(options);
|
|
1359
|
+
if (rejectedX509Credential) {
|
|
1360
|
+
x509Authentication.invalidateToken();
|
|
1361
|
+
}
|
|
1022
1362
|
if (
|
|
1023
1363
|
response.status === 401 &&
|
|
1024
|
-
this._workloadIdentityAuth &&
|
|
1364
|
+
(x509Authentication || this._workloadIdentityAuth) &&
|
|
1025
1365
|
security.bearerAuth &&
|
|
1026
|
-
!options
|
|
1366
|
+
(!x509Authentication || x509Authentication.usedWorkloadToken(options)) &&
|
|
1367
|
+
(!x509Authentication || retriesRemaining > 0) &&
|
|
1368
|
+
!hasStreamingBody &&
|
|
1027
1369
|
!options.__metadata?.['workloadIdentityTokenRefreshed']
|
|
1028
1370
|
) {
|
|
1029
|
-
|
|
1030
|
-
|
|
1371
|
+
if (x509Authentication) {
|
|
1372
|
+
void Shims.CancelReadableStream(response.body).catch(() => undefined);
|
|
1373
|
+
} else {
|
|
1374
|
+
await Shims.CancelReadableStream(response.body);
|
|
1375
|
+
this._workloadIdentityAuth?.invalidateToken();
|
|
1376
|
+
}
|
|
1031
1377
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
__metadata
|
|
1036
|
-
|
|
1037
|
-
workloadIdentityTokenRefreshed: true,
|
|
1038
|
-
},
|
|
1378
|
+
const replayOptions = {
|
|
1379
|
+
...options,
|
|
1380
|
+
__metadata: {
|
|
1381
|
+
...options.__metadata,
|
|
1382
|
+
workloadIdentityTokenRefreshed: true,
|
|
1039
1383
|
},
|
|
1040
|
-
|
|
1384
|
+
};
|
|
1385
|
+
return this.makeRequest(
|
|
1386
|
+
replayOptions,
|
|
1387
|
+
x509Authentication ? retriesRemaining - 1 : retriesRemaining,
|
|
1041
1388
|
retryOfRequestLogID ?? requestLogID,
|
|
1042
1389
|
);
|
|
1043
1390
|
}
|
|
1044
1391
|
|
|
1045
|
-
const shouldRetry =
|
|
1392
|
+
const shouldRetry =
|
|
1393
|
+
rejectedX509Credential && options.__metadata?.['workloadIdentityTokenRefreshed']
|
|
1394
|
+
? false
|
|
1395
|
+
: await this.shouldRetry(response);
|
|
1046
1396
|
if (retriesRemaining && shouldRetry && !hasStreamingBody) {
|
|
1047
1397
|
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
1048
1398
|
|
|
1049
1399
|
// We don't need the body of this response.
|
|
1050
|
-
|
|
1400
|
+
if (x509Authentication) {
|
|
1401
|
+
void Shims.CancelReadableStream(response.body).catch(() => undefined);
|
|
1402
|
+
} else {
|
|
1403
|
+
await Shims.CancelReadableStream(response.body);
|
|
1404
|
+
}
|
|
1051
1405
|
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
1052
1406
|
loggerFor(this).debug(
|
|
1053
1407
|
`[${requestLogID}] response error (${retryMessage})`,
|
|
@@ -1075,7 +1429,9 @@ export class OpenAI {
|
|
|
1075
1429
|
|
|
1076
1430
|
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
1077
1431
|
|
|
1078
|
-
const errText =
|
|
1432
|
+
const errText = x509Authentication
|
|
1433
|
+
? await this.readX509ResponseError(response, options, timeout, controller, x509Authentication)
|
|
1434
|
+
: await response.text().catch((err: any) => castToError(err).message);
|
|
1079
1435
|
const errJSON = safeJSON(errText) as any;
|
|
1080
1436
|
const errMessage = errJSON ? undefined : errText;
|
|
1081
1437
|
|
|
@@ -1107,7 +1463,16 @@ export class OpenAI {
|
|
|
1107
1463
|
}),
|
|
1108
1464
|
);
|
|
1109
1465
|
|
|
1110
|
-
|
|
1466
|
+
const continueRequest = x509Authentication?.continuation();
|
|
1467
|
+
x509Authentication?.releaseRequestCredentials();
|
|
1468
|
+
this.#responseAttempts.set(controller, {
|
|
1469
|
+
timeout,
|
|
1470
|
+
retriesRemaining,
|
|
1471
|
+
hasStreamingBody,
|
|
1472
|
+
...(x509Authentication ? { authentication: x509Authentication } : {}),
|
|
1473
|
+
helperMethod: options.__metadata?.['helperMethod'],
|
|
1474
|
+
...(continueRequest ? { continueRequest } : {}),
|
|
1475
|
+
});
|
|
1111
1476
|
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
|
|
1112
1477
|
}
|
|
1113
1478
|
|
|
@@ -1131,7 +1496,13 @@ export class OpenAI {
|
|
|
1131
1496
|
Page: new (...args: ConstructorParameters<typeof Pagination.AbstractPage>) => PageClass,
|
|
1132
1497
|
options: PromiseOrValue<FinalRequestOptions>,
|
|
1133
1498
|
): Pagination.PagePromise<PageClass, Item> {
|
|
1134
|
-
const
|
|
1499
|
+
const authentication = this.#x509Authentication ?? this._workloadIdentityAuth;
|
|
1500
|
+
const request =
|
|
1501
|
+
authentication instanceof X509WorkloadIdentityAuth
|
|
1502
|
+
? Promise.resolve(options).then((resolved) =>
|
|
1503
|
+
authentication.runRequest(() => this.makeRequest(resolved, null, undefined), this),
|
|
1504
|
+
)
|
|
1505
|
+
: this.makeRequest(options, null, undefined);
|
|
1135
1506
|
const page = new Pagination.PagePromise<PageClass, Item>(this as any as OpenAI, request, Page);
|
|
1136
1507
|
const guarded = this.responsePromise<PageClass>(request, async (client, props) => {
|
|
1137
1508
|
const body = await this.parseResponseWithTimeout(client, props);
|
|
@@ -1155,7 +1526,7 @@ export class OpenAI {
|
|
|
1155
1526
|
adminAPIKeyAuth: true,
|
|
1156
1527
|
},
|
|
1157
1528
|
): Promise<Response> {
|
|
1158
|
-
if (this._workloadIdentityAuth && schemes.bearerAuth) {
|
|
1529
|
+
if (this._workloadIdentityAuth && !this.#x509Fetch && schemes.bearerAuth) {
|
|
1159
1530
|
const headers = init.headers as Headers;
|
|
1160
1531
|
const authHeader = headers.get('Authorization');
|
|
1161
1532
|
if (!authHeader || authHeader === `Bearer ${WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER}`) {
|
|
@@ -1164,7 +1535,8 @@ export class OpenAI {
|
|
|
1164
1535
|
}
|
|
1165
1536
|
}
|
|
1166
1537
|
|
|
1167
|
-
const
|
|
1538
|
+
const fetchWithTimeout = this.#x509Fetch ? OpenAI.prototype.fetchWithTimeout : this.fetchWithTimeout;
|
|
1539
|
+
const response = await fetchWithTimeout.call(this, url, init, timeout, controller);
|
|
1168
1540
|
|
|
1169
1541
|
return response;
|
|
1170
1542
|
}
|
|
@@ -1200,7 +1572,7 @@ export class OpenAI {
|
|
|
1200
1572
|
|
|
1201
1573
|
try {
|
|
1202
1574
|
// use undefined this binding; fetch errors if bound to something else in browser/cloudflare
|
|
1203
|
-
return await this.fetch.call(undefined, url, fetchOptions);
|
|
1575
|
+
return await (this.#x509Fetch ?? this.fetch).call(undefined, url, fetchOptions);
|
|
1204
1576
|
} catch (err) {
|
|
1205
1577
|
if (signal && !composed) signal.removeEventListener('abort', abort);
|
|
1206
1578
|
throw err;
|
|
@@ -1271,7 +1643,21 @@ export class OpenAI {
|
|
|
1271
1643
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
1272
1644
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
1273
1645
|
}
|
|
1274
|
-
|
|
1646
|
+
const x509Authentication = this.#x509Authentication;
|
|
1647
|
+
if (x509Authentication) {
|
|
1648
|
+
const remaining = x509Authentication.remainingTimeout(
|
|
1649
|
+
options,
|
|
1650
|
+
x509Authentication.requestSnapshot().timeout,
|
|
1651
|
+
);
|
|
1652
|
+
if (timeoutMillis >= remaining) {
|
|
1653
|
+
throw new Errors.APIConnectionTimeoutError();
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
if (x509Authentication) {
|
|
1657
|
+
await x509Authentication.waitForRetry(timeoutMillis, x509Authentication.effectiveSignal());
|
|
1658
|
+
} else {
|
|
1659
|
+
await sleep(timeoutMillis);
|
|
1660
|
+
}
|
|
1275
1661
|
|
|
1276
1662
|
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
|
|
1277
1663
|
}
|
|
@@ -1295,12 +1681,46 @@ export class OpenAI {
|
|
|
1295
1681
|
inputOptions: FinalRequestOptions,
|
|
1296
1682
|
{ retryCount = 0 }: { retryCount?: number } = {},
|
|
1297
1683
|
): Promise<{ req: FinalizedRequestInit; url: string; timeout: number }> {
|
|
1684
|
+
if (this.#x509Authentication && !this.#x509Authentication.inRequest(this)) {
|
|
1685
|
+
const authentication = this.#x509Authentication;
|
|
1686
|
+
return await authentication.runRequest(async () => {
|
|
1687
|
+
const built = await OpenAI.prototype.buildRequest.call(this, inputOptions, { retryCount });
|
|
1688
|
+
authentication.releaseRequestBody(built.req.body);
|
|
1689
|
+
return built;
|
|
1690
|
+
}, this);
|
|
1691
|
+
}
|
|
1298
1692
|
const options = { ...inputOptions };
|
|
1693
|
+
const x509Authentication = this.#x509Authentication;
|
|
1694
|
+
const x509Tenant = x509Authentication?.snapshotTenant(this.organization, this.project);
|
|
1695
|
+
const x509Headers = x509Authentication?.snapshotHeaders(this._options.defaultHeaders, options.headers);
|
|
1696
|
+
if (x509Headers) {
|
|
1697
|
+
options.headers = x509Headers.requestHeaders;
|
|
1698
|
+
}
|
|
1699
|
+
const x509ClientFetchOptions = x509Authentication
|
|
1700
|
+
? snapshotX509RequestOptions(this.fetchOptions)
|
|
1701
|
+
: undefined;
|
|
1702
|
+
const x509RequestFetchOptions = x509Authentication
|
|
1703
|
+
? snapshotX509RequestOptions(options.fetchOptions)
|
|
1704
|
+
: undefined;
|
|
1299
1705
|
const { method, path, query, defaultBaseURL } = options;
|
|
1300
1706
|
|
|
1301
1707
|
const url = this.buildURL(path!, query as Record<string, unknown>, defaultBaseURL);
|
|
1302
|
-
|
|
1708
|
+
x509Authentication?.snapshotAPIURL(url);
|
|
1709
|
+
const explicitTimeout = 'timeout' in options;
|
|
1710
|
+
if (explicitTimeout) validatePositiveInteger('timeout', options.timeout);
|
|
1303
1711
|
options.timeout = options.timeout ?? this.timeout;
|
|
1712
|
+
if (x509Authentication && x509RequestFetchOptions) {
|
|
1713
|
+
x509Authentication.snapshotRequest(options.signal, options.timeout, x509RequestFetchOptions);
|
|
1714
|
+
}
|
|
1715
|
+
if (x509Authentication) {
|
|
1716
|
+
const snapshot = x509Authentication.requestSnapshot();
|
|
1717
|
+
options.timeout = snapshot.timeout;
|
|
1718
|
+
if (snapshot.signal === undefined) {
|
|
1719
|
+
delete options.signal;
|
|
1720
|
+
} else {
|
|
1721
|
+
options.signal = snapshot.signal;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1304
1724
|
const { bodyHeaders, body, isStreamingBody } = this.buildBody({ options });
|
|
1305
1725
|
|
|
1306
1726
|
if (isStreamingBody) {
|
|
@@ -1308,9 +1728,18 @@ export class OpenAI {
|
|
|
1308
1728
|
...inputOptions.__metadata,
|
|
1309
1729
|
hasStreamingBody: true,
|
|
1310
1730
|
};
|
|
1731
|
+
x509Authentication?.ownRequestBody(body, options.body);
|
|
1311
1732
|
}
|
|
1312
1733
|
|
|
1313
|
-
const reqHeaders = await this.buildHeaders({
|
|
1734
|
+
const reqHeaders = await this.buildHeaders({
|
|
1735
|
+
options: inputOptions,
|
|
1736
|
+
method,
|
|
1737
|
+
bodyHeaders,
|
|
1738
|
+
retryCount,
|
|
1739
|
+
x509Headers,
|
|
1740
|
+
x509Timeout: explicitTimeout ? options.timeout : undefined,
|
|
1741
|
+
x509Tenant,
|
|
1742
|
+
});
|
|
1314
1743
|
|
|
1315
1744
|
const req: FinalizedRequestInit = {
|
|
1316
1745
|
method,
|
|
@@ -1319,8 +1748,8 @@ export class OpenAI {
|
|
|
1319
1748
|
...((globalThis as any).ReadableStream &&
|
|
1320
1749
|
body instanceof (globalThis as any).ReadableStream && { duplex: 'half' }),
|
|
1321
1750
|
...(body && { body }),
|
|
1322
|
-
...((this.fetchOptions as any) ?? {}),
|
|
1323
|
-
...((options.fetchOptions as any) ?? {}),
|
|
1751
|
+
...(((x509Authentication ? x509ClientFetchOptions : this.fetchOptions) as any) ?? {}),
|
|
1752
|
+
...(((x509Authentication ? x509RequestFetchOptions : options.fetchOptions) as any) ?? {}),
|
|
1324
1753
|
};
|
|
1325
1754
|
|
|
1326
1755
|
return { req, url, timeout: options.timeout };
|
|
@@ -1331,11 +1760,17 @@ export class OpenAI {
|
|
|
1331
1760
|
method,
|
|
1332
1761
|
bodyHeaders,
|
|
1333
1762
|
retryCount,
|
|
1763
|
+
x509Headers,
|
|
1764
|
+
x509Timeout,
|
|
1765
|
+
x509Tenant,
|
|
1334
1766
|
}: {
|
|
1335
1767
|
options: FinalRequestOptions;
|
|
1336
1768
|
method: HTTPMethod;
|
|
1337
1769
|
bodyHeaders: HeadersLike;
|
|
1338
1770
|
retryCount: number;
|
|
1771
|
+
x509Headers?: { defaultHeaders: NullableHeaders; requestHeaders: NullableHeaders } | undefined;
|
|
1772
|
+
x509Timeout: number | undefined;
|
|
1773
|
+
x509Tenant?: { organization: string | null; project: string | null } | undefined;
|
|
1339
1774
|
}): Promise<Headers> {
|
|
1340
1775
|
let idempotencyHeaders: HeadersLike = {};
|
|
1341
1776
|
if (this.idempotencyHeader && method !== 'get') {
|
|
@@ -1344,27 +1779,28 @@ export class OpenAI {
|
|
|
1344
1779
|
}
|
|
1345
1780
|
|
|
1346
1781
|
const helperMethod = options.__metadata?.['helperMethod'];
|
|
1782
|
+
const timeout = x509Headers ? x509Timeout : options.timeout;
|
|
1347
1783
|
const headers = buildHeaders([
|
|
1348
1784
|
idempotencyHeaders,
|
|
1349
1785
|
{
|
|
1350
1786
|
Accept: 'application/json',
|
|
1351
1787
|
...(!isRunningInBrowserOrBrowserWorker() ? { 'User-Agent': this.getUserAgent() } : undefined),
|
|
1352
1788
|
'X-Stainless-Retry-Count': String(retryCount),
|
|
1353
|
-
...(
|
|
1789
|
+
...(timeout ? { 'X-Stainless-Timeout': String(Math.trunc(timeout / 1000)) } : {}),
|
|
1354
1790
|
...getPlatformHeaders(),
|
|
1355
1791
|
...(typeof helperMethod === 'string' ? { 'X-Stainless-Helper-Method': helperMethod } : {}),
|
|
1356
|
-
'OpenAI-Organization': this.organization,
|
|
1357
|
-
'OpenAI-Project': this.project,
|
|
1792
|
+
'OpenAI-Organization': x509Tenant ? x509Tenant.organization : this.organization,
|
|
1793
|
+
'OpenAI-Project': x509Tenant ? x509Tenant.project : this.project,
|
|
1358
1794
|
},
|
|
1359
|
-
this._provider
|
|
1795
|
+
this._provider || this.#x509Authentication?.isPlanningRequest()
|
|
1360
1796
|
? undefined
|
|
1361
1797
|
: await this.authHeaders(options, options.__security ?? { bearerAuth: true }),
|
|
1362
|
-
this._options.defaultHeaders,
|
|
1798
|
+
x509Headers?.defaultHeaders ?? this._options.defaultHeaders,
|
|
1363
1799
|
bodyHeaders,
|
|
1364
|
-
options.headers,
|
|
1800
|
+
x509Headers?.requestHeaders ?? options.headers,
|
|
1365
1801
|
]);
|
|
1366
1802
|
|
|
1367
|
-
if (!this._provider) {
|
|
1803
|
+
if (!this._provider && !this.#x509Authentication?.isPlanningRequest()) {
|
|
1368
1804
|
this.validateHeaders(headers, options.__security ?? { bearerAuth: true });
|
|
1369
1805
|
}
|
|
1370
1806
|
|
|
@@ -1563,7 +1999,10 @@ OpenAI.Videos = Videos;
|
|
|
1563
1999
|
|
|
1564
2000
|
const composedCallerSignals = new WeakMap<AbortController, AbortSignal>();
|
|
1565
2001
|
|
|
1566
|
-
function createRequestController(
|
|
2002
|
+
function createRequestController(
|
|
2003
|
+
callerSignal: AbortSignal | null | undefined,
|
|
2004
|
+
originalSignal?: AbortSignal | null,
|
|
2005
|
+
): AbortController {
|
|
1567
2006
|
const controller = new AbortController();
|
|
1568
2007
|
if (!callerSignal) return controller;
|
|
1569
2008
|
|
|
@@ -1575,7 +2014,11 @@ function createRequestController(callerSignal: AbortSignal | null | undefined):
|
|
|
1575
2014
|
try {
|
|
1576
2015
|
// Native composition keeps cancellation active after response headers without
|
|
1577
2016
|
// retaining an abort listener on the caller's signal or changing its reason.
|
|
1578
|
-
const
|
|
2017
|
+
const signals = [controller.signal, callerSignal];
|
|
2018
|
+
if (originalSignal && originalSignal !== callerSignal) {
|
|
2019
|
+
signals.push(originalSignal);
|
|
2020
|
+
}
|
|
2021
|
+
const composed = nativeAbortSignal.any(signals) as AbortSignal;
|
|
1579
2022
|
Object.defineProperty(controller, 'signal', { value: composed, configurable: true });
|
|
1580
2023
|
composedCallerSignals.set(controller, callerSignal);
|
|
1581
2024
|
} catch {
|
|
@@ -1619,6 +2062,7 @@ function isUndiciDispatcherVersionMismatchError(error: unknown): boolean {
|
|
|
1619
2062
|
}
|
|
1620
2063
|
|
|
1621
2064
|
export declare namespace OpenAI {
|
|
2065
|
+
export { type DataResidency as DataResidency };
|
|
1622
2066
|
export type RequestOptions = Opts.RequestOptions;
|
|
1623
2067
|
|
|
1624
2068
|
export import Page = Pagination.Page;
|