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
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
var _ChatCompletionStream_instances, _ChatCompletionStream_params, _ChatCompletionStream_audioDoneChoiceIndexes, _ChatCompletionStream_choiceEventStates, _ChatCompletionStream_currentChatCompletionSnapshot, _ChatCompletionStream_beginRequest, _ChatCompletionStream_getChoiceEventState, _ChatCompletionStream_addChunk, _ChatCompletionStream_emitToolCallDoneEvent, _ChatCompletionStream_emitContentDoneEvents, _ChatCompletionStream_endRequest, _ChatCompletionStream_accumulateChatCompletion;
|
|
1
|
+
var _ChatCompletionStream_instances, _ChatCompletionStream_params, _ChatCompletionStream_audioDoneChoiceIndexes, _ChatCompletionStream_choiceEventStates, _ChatCompletionStream_currentChatCompletionSnapshot, _ChatCompletionStream_hasAutoParseableTool, _ChatCompletionStream_partialJSONParseBudget, _ChatCompletionStream_beginRequest, _ChatCompletionStream_getChoiceEventState, _ChatCompletionStream_addChunk, _ChatCompletionStream_emitToolCallDoneEvent, _ChatCompletionStream_emitContentDoneEvents, _ChatCompletionStream_validateStructuredSnapshots, _ChatCompletionStream_endRequest, _ChatCompletionStream_accumulateChatCompletion;
|
|
2
2
|
import { __classPrivateFieldGet, __classPrivateFieldSet } from "../internal/tslib.mjs";
|
|
3
|
-
import { partialParse } from "../_vendor/partial-json-parser/parser.mjs";
|
|
3
|
+
import { MalformedJSON, partialParse } from "../_vendor/partial-json-parser/parser.mjs";
|
|
4
4
|
import { APIUserAbortError, ContentFilterFinishReasonError, LengthFinishReasonError, OpenAIError, } from "../error.mjs";
|
|
5
|
+
import { observeJSONRequestBody } from "../internal/request-options.mjs";
|
|
5
6
|
import { uuid4 } from "../internal/utils/uuid.mjs";
|
|
6
7
|
import { hasOwn } from "../internal/utils/values.mjs";
|
|
7
8
|
import { hasAutoParseableInput, isAutoParsableTool, isChatCompletionFunctionTool, isParseableResponseFormat, maybeParseChatCompletion, parseResponseFormatContent, shouldParseToolCall, } from "../lib/parser.mjs";
|
|
8
9
|
import { Stream } from "../streaming.mjs";
|
|
9
10
|
import { AbstractChatCompletionRunner } from "./AbstractChatCompletionRunner.mjs";
|
|
11
|
+
function parseStructuredStreamingJSON(content) {
|
|
12
|
+
try {
|
|
13
|
+
return partialParse(content);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error instanceof MalformedJSON || error instanceof SyntaxError) {
|
|
17
|
+
return parseResponseFormatContent({ type: 'json_schema', $parseRaw: undefined }, content);
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
10
22
|
// Keep message records readable as empty chunks by older SDKs. Their finalizer
|
|
11
23
|
// overwrites `object`, so the encoded payload does not leak into completions.
|
|
12
24
|
const CHAT_COMPLETION_READABLE_STREAM_MESSAGE_PREFIX = 'chat.completion.chunk.message:';
|
|
@@ -42,6 +54,232 @@ function getChatCompletionReadableStreamMessage(item) {
|
|
|
42
54
|
// conservative ceiling to prevent sparse tool-call arrays from growing unbounded.
|
|
43
55
|
const MAX_STREAM_CHOICES = 128;
|
|
44
56
|
const MAX_STREAM_TOOL_CALLS = 128;
|
|
57
|
+
const MAX_PARTIAL_JSON_BYTES = 16 * 1024 * 1024;
|
|
58
|
+
const MAX_PARTIAL_JSON_FRAGMENTS = 65536;
|
|
59
|
+
const MAX_PARTIAL_JSON_DEPTH = 128;
|
|
60
|
+
const MAX_PARTIAL_JSON_PARSE_WORK = 64 * 1024 * 1024;
|
|
61
|
+
const EAGER_PARTIAL_JSON_BYTES = 1024;
|
|
62
|
+
function createPartialJSONParseState() {
|
|
63
|
+
return {
|
|
64
|
+
bytes: 0,
|
|
65
|
+
depth: 0,
|
|
66
|
+
fragments: 0,
|
|
67
|
+
work: 0,
|
|
68
|
+
escaped: false,
|
|
69
|
+
has_non_whitespace: false,
|
|
70
|
+
in_string: false,
|
|
71
|
+
last_parsed_bytes: 0,
|
|
72
|
+
pending_high_surrogate: false,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function recordPartialJSONFragment(state, budget, fragment, validationWorkBudget) {
|
|
76
|
+
if (budget.fragments >= MAX_PARTIAL_JSON_FRAGMENTS) {
|
|
77
|
+
throw new OpenAIError('Chat completion stream exceeded its structured JSON fragment limit');
|
|
78
|
+
}
|
|
79
|
+
let bytes = 0;
|
|
80
|
+
let { depth, escaped, has_non_whitespace: hasNonWhitespace, in_string: inString } = state;
|
|
81
|
+
let completed = false;
|
|
82
|
+
let firstCharacter = true;
|
|
83
|
+
for (const character of fragment) {
|
|
84
|
+
const previousBytes = bytes;
|
|
85
|
+
const codePoint = character.codePointAt(0);
|
|
86
|
+
if (firstCharacter && state.pending_high_surrogate && codePoint >= 56320 && codePoint <= 57343) {
|
|
87
|
+
bytes += 1;
|
|
88
|
+
}
|
|
89
|
+
else if (codePoint <= 0x7f) {
|
|
90
|
+
bytes += 1;
|
|
91
|
+
}
|
|
92
|
+
else if (codePoint <= 2047) {
|
|
93
|
+
bytes += 2;
|
|
94
|
+
}
|
|
95
|
+
else if (codePoint <= 65535) {
|
|
96
|
+
bytes += 3;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
bytes += 4;
|
|
100
|
+
}
|
|
101
|
+
firstCharacter = false;
|
|
102
|
+
if (budget.bytes + bytes > MAX_PARTIAL_JSON_BYTES) {
|
|
103
|
+
throw new OpenAIError('Chat completion stream exceeded its structured JSON byte limit');
|
|
104
|
+
}
|
|
105
|
+
if (validationWorkBudget && validationWorkBudget.work + bytes > MAX_PARTIAL_JSON_PARSE_WORK) {
|
|
106
|
+
validationWorkBudget.work += previousBytes;
|
|
107
|
+
throw new OpenAIError('Chat completion stream exceeded its structured JSON parse-work limit');
|
|
108
|
+
}
|
|
109
|
+
if (character !== ' ' && character !== '\n' && character !== '\r' && character !== '\t') {
|
|
110
|
+
hasNonWhitespace = true;
|
|
111
|
+
}
|
|
112
|
+
if (inString) {
|
|
113
|
+
if (escaped) {
|
|
114
|
+
escaped = false;
|
|
115
|
+
}
|
|
116
|
+
else if (character === '\\') {
|
|
117
|
+
escaped = true;
|
|
118
|
+
}
|
|
119
|
+
else if (character === '"') {
|
|
120
|
+
inString = false;
|
|
121
|
+
completed || (completed = depth === 0);
|
|
122
|
+
}
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (character === '"') {
|
|
126
|
+
inString = true;
|
|
127
|
+
}
|
|
128
|
+
else if (character === '{' || character === '[') {
|
|
129
|
+
depth += 1;
|
|
130
|
+
if (depth > MAX_PARTIAL_JSON_DEPTH) {
|
|
131
|
+
throw new OpenAIError('Chat completion stream exceeded its structured JSON nesting depth limit');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else if ((character === '}' || character === ']') && depth > 0) {
|
|
135
|
+
depth -= 1;
|
|
136
|
+
completed || (completed = depth === 0);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
state.bytes += bytes;
|
|
140
|
+
state.fragments += 1;
|
|
141
|
+
state.depth = depth;
|
|
142
|
+
state.escaped = escaped;
|
|
143
|
+
state.has_non_whitespace = hasNonWhitespace;
|
|
144
|
+
state.in_string = inString;
|
|
145
|
+
if (fragment.length > 0) {
|
|
146
|
+
const finalCodeUnit = fragment.codePointAt(fragment.length - 1) ?? 0;
|
|
147
|
+
state.pending_high_surrogate = finalCodeUnit >= 55296 && finalCodeUnit <= 56319;
|
|
148
|
+
}
|
|
149
|
+
budget.bytes += bytes;
|
|
150
|
+
budget.fragments += 1;
|
|
151
|
+
if (validationWorkBudget) {
|
|
152
|
+
validationWorkBudget.work += bytes;
|
|
153
|
+
}
|
|
154
|
+
if (!hasNonWhitespace || bytes === 0) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
const minimumGrowth = Math.max(EAGER_PARTIAL_JSON_BYTES, Math.floor(state.last_parsed_bytes / 2));
|
|
158
|
+
if (state.bytes > EAGER_PARTIAL_JSON_BYTES &&
|
|
159
|
+
!completed &&
|
|
160
|
+
state.bytes - state.last_parsed_bytes < minimumGrowth) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
function reservePartialJSONParse(state, budget) {
|
|
166
|
+
if (budget.work + state.bytes > MAX_PARTIAL_JSON_PARSE_WORK) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
budget.work += state.bytes;
|
|
170
|
+
state.work += state.bytes;
|
|
171
|
+
state.last_parsed_bytes = state.bytes;
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
function captureStructuredJSONSnapshot(snapshot, property) {
|
|
175
|
+
const descriptor = Object.getOwnPropertyDescriptor(snapshot, property);
|
|
176
|
+
if (!descriptor) {
|
|
177
|
+
let prototype = Object.getPrototypeOf(snapshot);
|
|
178
|
+
for (let depth = 0; prototype !== null; depth += 1) {
|
|
179
|
+
if (depth >= MAX_PARTIAL_JSON_DEPTH || Object.getOwnPropertyDescriptor(prototype, property)) {
|
|
180
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
181
|
+
}
|
|
182
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
183
|
+
}
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
if (!('value' in descriptor) ||
|
|
187
|
+
(typeof descriptor.value !== 'string' && descriptor.value !== null && descriptor.value !== undefined)) {
|
|
188
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
189
|
+
}
|
|
190
|
+
return descriptor.value;
|
|
191
|
+
}
|
|
192
|
+
function captureStructuredMessageSnapshot(choice) {
|
|
193
|
+
const descriptor = Object.getOwnPropertyDescriptor(choice, 'message');
|
|
194
|
+
if (!descriptor ||
|
|
195
|
+
!('value' in descriptor) ||
|
|
196
|
+
typeof descriptor.value !== 'object' ||
|
|
197
|
+
descriptor.value === null) {
|
|
198
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
199
|
+
}
|
|
200
|
+
return descriptor.value;
|
|
201
|
+
}
|
|
202
|
+
function captureSnapshotArray(snapshot, property, maximum, kind) {
|
|
203
|
+
const descriptor = Object.getOwnPropertyDescriptor(snapshot, property);
|
|
204
|
+
if (!descriptor) {
|
|
205
|
+
let prototype = Object.getPrototypeOf(snapshot);
|
|
206
|
+
for (let depth = 0; prototype !== null; depth += 1) {
|
|
207
|
+
if (depth >= MAX_PARTIAL_JSON_DEPTH || Object.getOwnPropertyDescriptor(prototype, property)) {
|
|
208
|
+
throw new OpenAIError(`Chat completion stream contains an unsafe snapshot ${kind} collection`);
|
|
209
|
+
}
|
|
210
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
211
|
+
}
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
if (!('value' in descriptor) || !Array.isArray(descriptor.value)) {
|
|
215
|
+
throw new OpenAIError(`Chat completion stream contains an unsafe snapshot ${kind} collection`);
|
|
216
|
+
}
|
|
217
|
+
const length = Object.getOwnPropertyDescriptor(descriptor.value, 'length');
|
|
218
|
+
if (!length || !('value' in length) || !Number.isSafeInteger(length.value) || length.value > maximum) {
|
|
219
|
+
throw new OpenAIError(`Chat completion stream exceeded its snapshot ${kind} limit`);
|
|
220
|
+
}
|
|
221
|
+
return descriptor.value;
|
|
222
|
+
}
|
|
223
|
+
function captureSnapshotArrayItem(array, index) {
|
|
224
|
+
const descriptor = Object.getOwnPropertyDescriptor(array, index);
|
|
225
|
+
if (!descriptor) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
if (!('value' in descriptor)) {
|
|
229
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
230
|
+
}
|
|
231
|
+
return descriptor.value;
|
|
232
|
+
}
|
|
233
|
+
function mapCapturedSnapshotArray(array, maximum, kind, map) {
|
|
234
|
+
const descriptor = Object.getOwnPropertyDescriptor(array, 'length');
|
|
235
|
+
const length = descriptor && 'value' in descriptor ? descriptor.value : undefined;
|
|
236
|
+
if (typeof length !== 'number' || !Number.isSafeInteger(length) || length < 0 || length > maximum) {
|
|
237
|
+
throw new OpenAIError(`Chat completion stream exceeded its snapshot ${kind} limit`);
|
|
238
|
+
}
|
|
239
|
+
const mapped = [];
|
|
240
|
+
mapped.length = length;
|
|
241
|
+
for (let index = 0; index < length; index += 1) {
|
|
242
|
+
const item = Object.getOwnPropertyDescriptor(array, index);
|
|
243
|
+
if (!item) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (!('value' in item)) {
|
|
247
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
248
|
+
}
|
|
249
|
+
mapped[index] = map(item.value, index);
|
|
250
|
+
}
|
|
251
|
+
return mapped;
|
|
252
|
+
}
|
|
253
|
+
function validateStructuredJSONSnapshot(value, budget, validationWorkBudget) {
|
|
254
|
+
const state = createPartialJSONParseState();
|
|
255
|
+
const parseBudget = budget ?? { bytes: 0, fragments: 0, work: 0 };
|
|
256
|
+
recordPartialJSONFragment(state, parseBudget, value, validationWorkBudget);
|
|
257
|
+
if (!reservePartialJSONParse(state, parseBudget)) {
|
|
258
|
+
throw new OpenAIError('Chat completion stream exceeded its structured JSON parse-work limit');
|
|
259
|
+
}
|
|
260
|
+
return value;
|
|
261
|
+
}
|
|
262
|
+
function ownFunctionToolIdentity(toolCall) {
|
|
263
|
+
const type = Object.getOwnPropertyDescriptor(toolCall, 'type');
|
|
264
|
+
const fn = Object.getOwnPropertyDescriptor(toolCall, 'function');
|
|
265
|
+
if (!type || !('value' in type) || type.value !== 'function' || !fn || !('value' in fn)) {
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
if (typeof fn.value !== 'object' || fn.value === null) {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
const name = Object.getOwnPropertyDescriptor(fn.value, 'name');
|
|
272
|
+
if (!name || !('value' in name) || typeof name.value !== 'string' || name.value.length === 0) {
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
return { type: 'function', name: name.value };
|
|
276
|
+
}
|
|
277
|
+
function assertBoundToolCallIdentity(toolCall, identity) {
|
|
278
|
+
const current = ownFunctionToolIdentity(toolCall);
|
|
279
|
+
if (!current || current.name !== identity.name || current.type !== identity.type) {
|
|
280
|
+
throw new OpenAIError('Chat completion stream contains a changed tool call identity');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
45
283
|
function assignOwnProperties(target, source) {
|
|
46
284
|
if (Object.prototype.propertyIsEnumerable.call(source, '__proto__') && !hasOwn(target, '__proto__')) {
|
|
47
285
|
Object.defineProperty(target, '__proto__', {
|
|
@@ -53,6 +291,474 @@ function assignOwnProperties(target, source) {
|
|
|
53
291
|
}
|
|
54
292
|
return Object.assign(target, source);
|
|
55
293
|
}
|
|
294
|
+
function cloneParserConfigObject(value, stableFields = []) {
|
|
295
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
296
|
+
for (const field of stableFields) {
|
|
297
|
+
const descriptor = descriptors[field];
|
|
298
|
+
if (!descriptor && !(field in value)) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
descriptors[field] = {
|
|
302
|
+
value: descriptor && 'value' in descriptor ? descriptor.value : Reflect.get(value, field, value),
|
|
303
|
+
enumerable: descriptor?.enumerable ?? false,
|
|
304
|
+
configurable: descriptor?.configurable ?? true,
|
|
305
|
+
writable: descriptor && 'writable' in descriptor ? descriptor.writable : false,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
return Object.create(Object.getPrototypeOf(value), descriptors);
|
|
309
|
+
}
|
|
310
|
+
function snapshotChatCompletionParserParams(params) {
|
|
311
|
+
const snapshot = cloneParserConfigObject(params);
|
|
312
|
+
if (params.tools) {
|
|
313
|
+
const stableTools = [];
|
|
314
|
+
const lengthDescriptor = Object.getOwnPropertyDescriptor(params.tools, 'length');
|
|
315
|
+
const length = lengthDescriptor && 'value' in lengthDescriptor ? lengthDescriptor.value : undefined;
|
|
316
|
+
const toolCount = typeof length === 'number' && Number.isSafeInteger(length) && length >= 0
|
|
317
|
+
? Math.min(length, MAX_STREAM_TOOL_CALLS)
|
|
318
|
+
: 0;
|
|
319
|
+
for (let index = 0; index < toolCount; index += 1) {
|
|
320
|
+
const item = Object.getOwnPropertyDescriptor(params.tools, String(index));
|
|
321
|
+
if (!item || !('value' in item)) {
|
|
322
|
+
stableTools.length = index + 1;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
const tool = item.value;
|
|
326
|
+
const stableTool = cloneParserConfigObject(tool, [
|
|
327
|
+
'type',
|
|
328
|
+
'$brand',
|
|
329
|
+
'$parseRaw',
|
|
330
|
+
'$callback',
|
|
331
|
+
'function',
|
|
332
|
+
]);
|
|
333
|
+
const descriptors = Object.getOwnPropertyDescriptors(stableTool);
|
|
334
|
+
if (isChatCompletionFunctionTool(stableTool)) {
|
|
335
|
+
const descriptor = descriptors.function;
|
|
336
|
+
descriptors.function = {
|
|
337
|
+
...(descriptor && 'value' in descriptor
|
|
338
|
+
? descriptor
|
|
339
|
+
: { configurable: true, enumerable: true, writable: true }),
|
|
340
|
+
value: cloneParserConfigObject(stableTool.function, ['name', 'strict']),
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
stableTools[index] = Object.create(Object.getPrototypeOf(tool), descriptors);
|
|
344
|
+
}
|
|
345
|
+
snapshot.tools = stableTools;
|
|
346
|
+
}
|
|
347
|
+
if (params.response_format) {
|
|
348
|
+
snapshot.response_format = cloneParserConfigObject(params.response_format, [
|
|
349
|
+
'type',
|
|
350
|
+
'$brand',
|
|
351
|
+
'$parseRaw',
|
|
352
|
+
]);
|
|
353
|
+
}
|
|
354
|
+
return snapshot;
|
|
355
|
+
}
|
|
356
|
+
const MAX_SERIALIZED_PARSER_SCHEMA_NODES = 4096;
|
|
357
|
+
const stringifyParserSchemaValue = JSON.stringify;
|
|
358
|
+
const MAX_SERIALIZED_PARSER_SCHEMA_BYTES = 1024 * 1024;
|
|
359
|
+
const MAX_SERIALIZED_PARSER_SCHEMA_DEPTH = 64;
|
|
360
|
+
const OMITTED_SERIALIZED_PARSER_VALUE = Symbol('omitted serialized parser value');
|
|
361
|
+
const UNSAFE_SERIALIZED_PARSER_VALUE = Symbol('unsafe serialized parser value');
|
|
362
|
+
function canonicalSerializedParserSchema(value, budget) {
|
|
363
|
+
const ancestors = new WeakSet();
|
|
364
|
+
const charge = (bytes) => {
|
|
365
|
+
if (!Number.isSafeInteger(bytes) ||
|
|
366
|
+
bytes < 0 ||
|
|
367
|
+
budget.bytes + bytes > MAX_SERIALIZED_PARSER_SCHEMA_BYTES) {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
budget.bytes += bytes;
|
|
371
|
+
return true;
|
|
372
|
+
};
|
|
373
|
+
const visit = (current, depth) => {
|
|
374
|
+
if (depth > MAX_SERIALIZED_PARSER_SCHEMA_DEPTH || budget.nodes >= MAX_SERIALIZED_PARSER_SCHEMA_NODES) {
|
|
375
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
376
|
+
}
|
|
377
|
+
budget.nodes += 1;
|
|
378
|
+
if (current === undefined || typeof current === 'function' || typeof current === 'symbol') {
|
|
379
|
+
return OMITTED_SERIALIZED_PARSER_VALUE;
|
|
380
|
+
}
|
|
381
|
+
if (typeof current === 'bigint') {
|
|
382
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
383
|
+
}
|
|
384
|
+
if (current === null || typeof current === 'boolean' || typeof current === 'number') {
|
|
385
|
+
const serialized = stringifyParserSchemaValue(current);
|
|
386
|
+
return typeof serialized === 'string' && charge(serialized.length)
|
|
387
|
+
? serialized
|
|
388
|
+
: UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
389
|
+
}
|
|
390
|
+
if (typeof current === 'string') {
|
|
391
|
+
if (!charge(current.length * 6 + 2)) {
|
|
392
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
393
|
+
}
|
|
394
|
+
return stringifyParserSchemaValue(current);
|
|
395
|
+
}
|
|
396
|
+
if (typeof current !== 'object' || ancestors.has(current)) {
|
|
397
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
398
|
+
}
|
|
399
|
+
const array = Array.isArray(current);
|
|
400
|
+
const prototype = Object.getPrototypeOf(current);
|
|
401
|
+
if ((array && prototype !== Array.prototype) ||
|
|
402
|
+
(!array && prototype !== null && prototype !== Object.prototype)) {
|
|
403
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
404
|
+
}
|
|
405
|
+
for (let owner = current; owner !== null; owner = Object.getPrototypeOf(owner)) {
|
|
406
|
+
const serializer = Object.getOwnPropertyDescriptor(owner, 'toJSON');
|
|
407
|
+
if (!serializer) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (!('value' in serializer) || typeof serializer.value === 'function') {
|
|
411
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
412
|
+
}
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
ancestors.add(current);
|
|
416
|
+
try {
|
|
417
|
+
if (!charge(2)) {
|
|
418
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
419
|
+
}
|
|
420
|
+
if (array) {
|
|
421
|
+
const lengthDescriptor = Object.getOwnPropertyDescriptor(current, 'length');
|
|
422
|
+
const length = lengthDescriptor && 'value' in lengthDescriptor ? lengthDescriptor.value : undefined;
|
|
423
|
+
if (typeof length !== 'number' ||
|
|
424
|
+
!Number.isSafeInteger(length) ||
|
|
425
|
+
length < 0 ||
|
|
426
|
+
length > MAX_SERIALIZED_PARSER_SCHEMA_NODES - budget.nodes) {
|
|
427
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
428
|
+
}
|
|
429
|
+
const items = [];
|
|
430
|
+
for (let index = 0; index < length; index += 1) {
|
|
431
|
+
const key = String(index);
|
|
432
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, key);
|
|
433
|
+
if (!descriptor) {
|
|
434
|
+
if (Object.getOwnPropertyDescriptor(Array.prototype, key) ||
|
|
435
|
+
Object.getOwnPropertyDescriptor(Object.prototype, key)) {
|
|
436
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
437
|
+
}
|
|
438
|
+
budget.nodes += 1;
|
|
439
|
+
if (!charge(4)) {
|
|
440
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
441
|
+
}
|
|
442
|
+
items.push('null');
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if (!('value' in descriptor)) {
|
|
446
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
447
|
+
}
|
|
448
|
+
const item = visit(descriptor.value, depth + 1);
|
|
449
|
+
if (item === UNSAFE_SERIALIZED_PARSER_VALUE) {
|
|
450
|
+
return item;
|
|
451
|
+
}
|
|
452
|
+
items.push(item === OMITTED_SERIALIZED_PARSER_VALUE ? 'null' : item);
|
|
453
|
+
}
|
|
454
|
+
return `[${items.join(',')}]`;
|
|
455
|
+
}
|
|
456
|
+
const keys = Reflect.ownKeys(current);
|
|
457
|
+
if (keys.length > MAX_SERIALIZED_PARSER_SCHEMA_NODES - budget.nodes) {
|
|
458
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
459
|
+
}
|
|
460
|
+
const entries = [];
|
|
461
|
+
for (const key of keys) {
|
|
462
|
+
if (typeof key !== 'string') {
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, key);
|
|
466
|
+
if (!descriptor) {
|
|
467
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
468
|
+
}
|
|
469
|
+
if (!descriptor.enumerable) {
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
if (!('value' in descriptor)) {
|
|
473
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
474
|
+
}
|
|
475
|
+
entries.push([key, descriptor.value]);
|
|
476
|
+
}
|
|
477
|
+
entries.sort(([left], [right]) => {
|
|
478
|
+
if (left === right) {
|
|
479
|
+
return 0;
|
|
480
|
+
}
|
|
481
|
+
return left < right ? -1 : 1;
|
|
482
|
+
});
|
|
483
|
+
const fields = [];
|
|
484
|
+
for (const [key, entry] of entries) {
|
|
485
|
+
const normalized = visit(entry, depth + 1);
|
|
486
|
+
if (normalized === UNSAFE_SERIALIZED_PARSER_VALUE) {
|
|
487
|
+
return normalized;
|
|
488
|
+
}
|
|
489
|
+
if (normalized === OMITTED_SERIALIZED_PARSER_VALUE) {
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
if (!charge(key.length * 6 + 3)) {
|
|
493
|
+
return UNSAFE_SERIALIZED_PARSER_VALUE;
|
|
494
|
+
}
|
|
495
|
+
fields.push(`${stringifyParserSchemaValue(key)}:${normalized}`);
|
|
496
|
+
}
|
|
497
|
+
return `{${fields.join(',')}}`;
|
|
498
|
+
}
|
|
499
|
+
finally {
|
|
500
|
+
ancestors.delete(current);
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
try {
|
|
504
|
+
const normalized = visit(value, 0);
|
|
505
|
+
return typeof normalized === 'string' ? normalized : undefined;
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
return undefined;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
function rememberSerializedParserSchema(signatures, source, holder, key) {
|
|
512
|
+
const parser = Object.getOwnPropertyDescriptor(source, '$parseRaw');
|
|
513
|
+
const schema = Object.getOwnPropertyDescriptor(holder, key);
|
|
514
|
+
if (!parser ||
|
|
515
|
+
!('value' in parser) ||
|
|
516
|
+
typeof parser.value !== 'function' ||
|
|
517
|
+
!schema ||
|
|
518
|
+
!('value' in schema)) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const normalized = canonicalSerializedParserSchema(schema.value, { nodes: 0, bytes: 0 });
|
|
522
|
+
if (normalized !== undefined) {
|
|
523
|
+
signatures.set(source, normalized);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
function hasMatchingSerializedParserSchema(signatures, source, holder, key, value) {
|
|
527
|
+
const expected = source && signatures.get(source);
|
|
528
|
+
const descriptor = Object.getOwnPropertyDescriptor(holder, key);
|
|
529
|
+
return (expected !== undefined &&
|
|
530
|
+
descriptor !== undefined &&
|
|
531
|
+
'value' in descriptor &&
|
|
532
|
+
canonicalSerializedParserSchema(value, { nodes: 0, bytes: 0 }) === expected);
|
|
533
|
+
}
|
|
534
|
+
function serializedParserDescriptor(descriptor, value) {
|
|
535
|
+
return descriptor && 'value' in descriptor
|
|
536
|
+
? { ...descriptor, value }
|
|
537
|
+
: { configurable: true, enumerable: true, writable: true, value };
|
|
538
|
+
}
|
|
539
|
+
function shadowSerializedParserMetadata(descriptors, source, fields) {
|
|
540
|
+
for (const field of fields) {
|
|
541
|
+
const descriptor = descriptors[field];
|
|
542
|
+
if (!descriptor && !(field in source)) {
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
descriptors[field] =
|
|
546
|
+
descriptor && 'value' in descriptor
|
|
547
|
+
? { ...descriptor, value: undefined }
|
|
548
|
+
: {
|
|
549
|
+
configurable: descriptor?.configurable ?? true,
|
|
550
|
+
enumerable: descriptor?.enumerable ?? false,
|
|
551
|
+
writable: false,
|
|
552
|
+
value: undefined,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function snapshotSerializedParserTool(serialized) {
|
|
557
|
+
const source = serialized.source ??
|
|
558
|
+
{
|
|
559
|
+
type: serialized.type,
|
|
560
|
+
...(serialized.type === 'function' ? { function: {} } : {}),
|
|
561
|
+
};
|
|
562
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
563
|
+
descriptors.type = serializedParserDescriptor(descriptors.type, serialized.type);
|
|
564
|
+
if (serialized.type !== 'function' || !serialized.function) {
|
|
565
|
+
if (descriptors.function) {
|
|
566
|
+
descriptors.function = serializedParserDescriptor(descriptors.function, undefined);
|
|
567
|
+
}
|
|
568
|
+
shadowSerializedParserMetadata(descriptors, source, ['$brand', '$parseRaw', '$callback']);
|
|
569
|
+
return Object.create(Object.getPrototypeOf(source), descriptors);
|
|
570
|
+
}
|
|
571
|
+
const descriptor = descriptors.function;
|
|
572
|
+
const original = descriptor && 'value' in descriptor && typeof descriptor.value === 'object' && descriptor.value !== null
|
|
573
|
+
? descriptor.value
|
|
574
|
+
: {};
|
|
575
|
+
const functionDescriptors = Object.getOwnPropertyDescriptors(original);
|
|
576
|
+
functionDescriptors['name'] = serializedParserDescriptor(functionDescriptors['name'], serialized.function.name);
|
|
577
|
+
functionDescriptors['strict'] = serializedParserDescriptor(functionDescriptors['strict'], serialized.function.strict);
|
|
578
|
+
descriptors.function = serializedParserDescriptor(descriptor, Object.create(Object.getPrototypeOf(original), functionDescriptors));
|
|
579
|
+
if (!serialized.function.schemaMatches) {
|
|
580
|
+
shadowSerializedParserMetadata(descriptors, source, ['$brand', '$parseRaw', '$callback']);
|
|
581
|
+
}
|
|
582
|
+
return Object.create(Object.getPrototypeOf(source), descriptors);
|
|
583
|
+
}
|
|
584
|
+
function snapshotSerializedResponseFormat(serialized) {
|
|
585
|
+
const source = serialized.source ?? { type: serialized.type };
|
|
586
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
587
|
+
descriptors.type = serializedParserDescriptor(descriptors.type, serialized.type);
|
|
588
|
+
if (serialized.type !== 'json_schema' || !serialized.source || !serialized.schemaMatches) {
|
|
589
|
+
shadowSerializedParserMetadata(descriptors, source, ['$brand', '$parseRaw']);
|
|
590
|
+
}
|
|
591
|
+
return Object.create(Object.getPrototypeOf(source), descriptors);
|
|
592
|
+
}
|
|
593
|
+
function ownSerializedParserObject(holder, key) {
|
|
594
|
+
const descriptor = Object.getOwnPropertyDescriptor(holder, key);
|
|
595
|
+
if (!descriptor || !('value' in descriptor)) {
|
|
596
|
+
return undefined;
|
|
597
|
+
}
|
|
598
|
+
const { value } = descriptor;
|
|
599
|
+
return typeof value === 'object' && value !== null ? value : undefined;
|
|
600
|
+
}
|
|
601
|
+
function observeSerializedChatCompletionParserParams(body, initial, update) {
|
|
602
|
+
const originalToolOwners = new WeakMap();
|
|
603
|
+
const originalSchemaSignatures = new WeakMap();
|
|
604
|
+
// At most 128 tools plus one response format each receive an independent
|
|
605
|
+
// 4,096-node/1 MiB source and wire allowance (129 MiB maximum per pass).
|
|
606
|
+
if (body.tools) {
|
|
607
|
+
for (let index = 0; index < body.tools.length && index < MAX_STREAM_TOOL_CALLS; index += 1) {
|
|
608
|
+
const owner = ownSerializedParserObject(body.tools, String(index));
|
|
609
|
+
const source = initial.tools?.[index];
|
|
610
|
+
if (owner && source) {
|
|
611
|
+
originalToolOwners.set(owner, source);
|
|
612
|
+
const originalFunction = ownSerializedParserObject(source, 'function');
|
|
613
|
+
if (originalFunction) {
|
|
614
|
+
rememberSerializedParserSchema(originalSchemaSignatures, source, originalFunction, 'parameters');
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
if (initial.response_format) {
|
|
620
|
+
rememberSerializedParserSchema(originalSchemaSignatures, initial.response_format, initial.response_format, 'json_schema');
|
|
621
|
+
}
|
|
622
|
+
let root;
|
|
623
|
+
let tools;
|
|
624
|
+
let responseFormat;
|
|
625
|
+
let responseFrame;
|
|
626
|
+
let frames = [];
|
|
627
|
+
let toolFrames = new WeakMap();
|
|
628
|
+
let actualToolOwners = new Map();
|
|
629
|
+
let functionFrames = new WeakMap();
|
|
630
|
+
return observeJSONRequestBody(body, {
|
|
631
|
+
value(holder, key, value) {
|
|
632
|
+
if (!root && key === '' && typeof value === 'object' && value !== null) {
|
|
633
|
+
root = value;
|
|
634
|
+
tools = undefined;
|
|
635
|
+
responseFormat = undefined;
|
|
636
|
+
responseFrame = undefined;
|
|
637
|
+
frames = [];
|
|
638
|
+
toolFrames = new WeakMap();
|
|
639
|
+
actualToolOwners = new Map();
|
|
640
|
+
functionFrames = new WeakMap();
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
if (holder === root && key === 'response_format') {
|
|
644
|
+
if (typeof value === 'object' && value !== null) {
|
|
645
|
+
responseFormat = value;
|
|
646
|
+
const owner = ownSerializedParserObject(holder, key);
|
|
647
|
+
responseFrame = {
|
|
648
|
+
source: owner === body.response_format ? initial.response_format : undefined,
|
|
649
|
+
schemaMatches: false,
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
if (holder === root && key === 'tools') {
|
|
655
|
+
if (Array.isArray(value)) {
|
|
656
|
+
tools = new Proxy(value, {
|
|
657
|
+
get(target, property) {
|
|
658
|
+
const actual = Reflect.get(target, property, target);
|
|
659
|
+
if (typeof property === 'string') {
|
|
660
|
+
const index = Number(property);
|
|
661
|
+
if (Number.isSafeInteger(index) &&
|
|
662
|
+
index >= 0 &&
|
|
663
|
+
index < MAX_STREAM_TOOL_CALLS &&
|
|
664
|
+
String(index) === property) {
|
|
665
|
+
actualToolOwners.set(index, typeof actual === 'object' && actual !== null ? actual : undefined);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return actual;
|
|
669
|
+
},
|
|
670
|
+
});
|
|
671
|
+
return tools;
|
|
672
|
+
}
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
if (holder === tools) {
|
|
676
|
+
const index = Number(key);
|
|
677
|
+
if (!Number.isSafeInteger(index) ||
|
|
678
|
+
index < 0 ||
|
|
679
|
+
index >= MAX_STREAM_TOOL_CALLS ||
|
|
680
|
+
typeof value !== 'object' ||
|
|
681
|
+
value === null) {
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
const owner = actualToolOwners.get(index);
|
|
685
|
+
const source = owner ? originalToolOwners.get(owner) : undefined;
|
|
686
|
+
const frame = { source };
|
|
687
|
+
frames[index] = frame;
|
|
688
|
+
toolFrames.set(value, frame);
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
const tool = toolFrames.get(holder);
|
|
692
|
+
if (tool) {
|
|
693
|
+
if (key === 'type' && typeof value === 'string') {
|
|
694
|
+
tool.type = value;
|
|
695
|
+
}
|
|
696
|
+
else if (key === 'function' && typeof value === 'object' && value !== null) {
|
|
697
|
+
const fn = { source: tool.source, schemaMatches: false };
|
|
698
|
+
tool.function = fn;
|
|
699
|
+
functionFrames.set(value, fn);
|
|
700
|
+
}
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
if (holder === responseFormat && responseFrame) {
|
|
704
|
+
if (key === 'type' && typeof value === 'string') {
|
|
705
|
+
responseFrame.type = value;
|
|
706
|
+
}
|
|
707
|
+
else if (key === 'json_schema') {
|
|
708
|
+
responseFrame.schemaMatches = hasMatchingSerializedParserSchema(originalSchemaSignatures, responseFrame.source, holder, key, value);
|
|
709
|
+
}
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
const fn = functionFrames.get(holder);
|
|
713
|
+
if (fn) {
|
|
714
|
+
if (key === 'name' && typeof value === 'string') {
|
|
715
|
+
fn.name = value;
|
|
716
|
+
}
|
|
717
|
+
else if (key === 'strict' && typeof value === 'boolean') {
|
|
718
|
+
fn.strict = value;
|
|
719
|
+
}
|
|
720
|
+
else if (key === 'parameters') {
|
|
721
|
+
fn.schemaMatches = hasMatchingSerializedParserSchema(originalSchemaSignatures, fn.source, holder, key, value);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return undefined;
|
|
725
|
+
},
|
|
726
|
+
complete() {
|
|
727
|
+
if (!root) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
const snapshot = cloneParserConfigObject(initial);
|
|
731
|
+
if (tools) {
|
|
732
|
+
const serializedTools = [];
|
|
733
|
+
for (let index = 0; index < frames.length; index += 1) {
|
|
734
|
+
const frame = frames[index];
|
|
735
|
+
if (frame) {
|
|
736
|
+
serializedTools[index] = snapshotSerializedParserTool(frame);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
snapshot.tools = serializedTools;
|
|
740
|
+
}
|
|
741
|
+
else {
|
|
742
|
+
delete snapshot.tools;
|
|
743
|
+
}
|
|
744
|
+
if (responseFrame) {
|
|
745
|
+
snapshot.response_format = snapshotSerializedResponseFormat(responseFrame);
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
delete snapshot.response_format;
|
|
749
|
+
}
|
|
750
|
+
update(snapshot);
|
|
751
|
+
root = undefined;
|
|
752
|
+
tools = undefined;
|
|
753
|
+
responseFormat = undefined;
|
|
754
|
+
responseFrame = undefined;
|
|
755
|
+
frames = [];
|
|
756
|
+
toolFrames = new WeakMap();
|
|
757
|
+
actualToolOwners = new Map();
|
|
758
|
+
functionFrames = new WeakMap();
|
|
759
|
+
},
|
|
760
|
+
});
|
|
761
|
+
}
|
|
56
762
|
/** Streams chat completion chunks while accumulating snapshots, parsed output, and events. */
|
|
57
763
|
export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
58
764
|
/** Creates an unstarted stream, retaining request parameters for structured-output parsing. */
|
|
@@ -63,9 +769,30 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
63
769
|
_ChatCompletionStream_audioDoneChoiceIndexes.set(this, void 0);
|
|
64
770
|
_ChatCompletionStream_choiceEventStates.set(this, void 0);
|
|
65
771
|
_ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0);
|
|
772
|
+
_ChatCompletionStream_hasAutoParseableTool.set(this, void 0);
|
|
773
|
+
_ChatCompletionStream_partialJSONParseBudget.set(this, void 0);
|
|
66
774
|
__classPrivateFieldSet(this, _ChatCompletionStream_params, params, "f");
|
|
67
775
|
__classPrivateFieldSet(this, _ChatCompletionStream_audioDoneChoiceIndexes, new Set(), "f");
|
|
68
776
|
__classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
|
|
777
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_hasAutoParseableTool, false, "f");
|
|
778
|
+
const tools = params?.tools;
|
|
779
|
+
const lengthDescriptor = tools && Object.getOwnPropertyDescriptor(tools, 'length');
|
|
780
|
+
const length = lengthDescriptor && 'value' in lengthDescriptor ? lengthDescriptor.value : undefined;
|
|
781
|
+
if (tools && typeof length === 'number' && Number.isSafeInteger(length) && length >= 0) {
|
|
782
|
+
for (let index = 0; index < Math.min(length, MAX_STREAM_TOOL_CALLS); index += 1) {
|
|
783
|
+
const descriptor = Object.getOwnPropertyDescriptor(tools, String(index));
|
|
784
|
+
if (!descriptor || !('value' in descriptor)) {
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
const tool = descriptor.value;
|
|
788
|
+
if (isChatCompletionFunctionTool(tool) &&
|
|
789
|
+
(isAutoParsableTool(tool) || tool.function.strict === true)) {
|
|
790
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_hasAutoParseableTool, true, "f");
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_partialJSONParseBudget, { bytes: 0, fragments: 0, work: 0 }, "f");
|
|
69
796
|
}
|
|
70
797
|
/** The latest accumulated completion, or `undefined` before a chunk arrives or after finalization. */
|
|
71
798
|
get currentChatCompletionSnapshot() {
|
|
@@ -91,8 +818,25 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
91
818
|
}
|
|
92
819
|
async _createChatCompletion(client, params, options) {
|
|
93
820
|
this._listenForAbort(options?.signal);
|
|
821
|
+
const requestParams = { ...params, stream: true };
|
|
822
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_params, requestParams, "f");
|
|
94
823
|
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
|
|
95
|
-
const
|
|
824
|
+
const parserParams = snapshotChatCompletionParserParams(requestParams);
|
|
825
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_params, parserParams, "f");
|
|
826
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_hasAutoParseableTool, parserParams.tools?.some((tool) => isChatCompletionFunctionTool(tool) && (isAutoParsableTool(tool) || tool.function.strict === true)) ?? false, "f");
|
|
827
|
+
const stopObserving = requestParams.tools || requestParams.response_format
|
|
828
|
+
? observeSerializedChatCompletionParserParams(requestParams, parserParams, (serialized) => {
|
|
829
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_params, serialized, "f");
|
|
830
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_hasAutoParseableTool, serialized.tools?.some((tool) => isChatCompletionFunctionTool(tool) &&
|
|
831
|
+
(isAutoParsableTool(tool) || tool.function.strict === true)) ?? false, "f");
|
|
832
|
+
})
|
|
833
|
+
: undefined;
|
|
834
|
+
const stream = await client.chat.completions
|
|
835
|
+
.create(requestParams, {
|
|
836
|
+
...options,
|
|
837
|
+
signal: this.controller.signal,
|
|
838
|
+
})
|
|
839
|
+
.finally(stopObserving);
|
|
96
840
|
this._connected();
|
|
97
841
|
for await (const chunk of stream) {
|
|
98
842
|
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
|
|
@@ -148,12 +892,13 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
148
892
|
throw new OpenAIError(`request ended without sending any chunks`);
|
|
149
893
|
}
|
|
150
894
|
/** Iterates over raw API chunks; stopping iteration early aborts the underlying request. */
|
|
151
|
-
[(_ChatCompletionStream_params = new WeakMap(), _ChatCompletionStream_audioDoneChoiceIndexes = new WeakMap(), _ChatCompletionStream_choiceEventStates = new WeakMap(), _ChatCompletionStream_currentChatCompletionSnapshot = new WeakMap(), _ChatCompletionStream_instances = new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest() {
|
|
895
|
+
[(_ChatCompletionStream_params = new WeakMap(), _ChatCompletionStream_audioDoneChoiceIndexes = new WeakMap(), _ChatCompletionStream_choiceEventStates = new WeakMap(), _ChatCompletionStream_currentChatCompletionSnapshot = new WeakMap(), _ChatCompletionStream_hasAutoParseableTool = new WeakMap(), _ChatCompletionStream_partialJSONParseBudget = new WeakMap(), _ChatCompletionStream_instances = new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest() {
|
|
152
896
|
if (this.ended) {
|
|
153
897
|
return;
|
|
154
898
|
}
|
|
155
899
|
__classPrivateFieldSet(this, _ChatCompletionStream_audioDoneChoiceIndexes, new Set(), "f");
|
|
156
900
|
__classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
|
|
901
|
+
__classPrivateFieldSet(this, _ChatCompletionStream_partialJSONParseBudget, { bytes: 0, fragments: 0, work: 0 }, "f");
|
|
157
902
|
}, _ChatCompletionStream_getChoiceEventState = function _ChatCompletionStream_getChoiceEventState(choice) {
|
|
158
903
|
let state = __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index];
|
|
159
904
|
if (state) {
|
|
@@ -161,11 +906,14 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
161
906
|
}
|
|
162
907
|
state = {
|
|
163
908
|
content_done: false,
|
|
909
|
+
content_parse_state: undefined,
|
|
164
910
|
refusal_done: false,
|
|
165
911
|
logprobs_content_done: false,
|
|
166
912
|
logprobs_refusal_done: false,
|
|
167
913
|
done_tool_calls: new Set(),
|
|
168
914
|
current_tool_call_index: null,
|
|
915
|
+
tool_call_parse_states: new Map(),
|
|
916
|
+
tool_call_identities: new Map(),
|
|
169
917
|
};
|
|
170
918
|
__classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index] = state;
|
|
171
919
|
return state;
|
|
@@ -173,36 +921,47 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
173
921
|
if (this.ended) {
|
|
174
922
|
return;
|
|
175
923
|
}
|
|
176
|
-
const
|
|
924
|
+
const capturedChoiceFrames = new WeakMap();
|
|
925
|
+
const completion = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk, capturedChoiceFrames);
|
|
177
926
|
this._emit('chunk', chunk, completion);
|
|
178
927
|
for (const choice of chunk.choices) {
|
|
179
|
-
const
|
|
928
|
+
const capturedChoice = capturedChoiceFrames.get(choice);
|
|
929
|
+
const choiceSnapshot = completion.choices[capturedChoice?.index ?? choice.index];
|
|
930
|
+
const capturedToolCalls = capturedChoice?.tool_calls ?? [];
|
|
180
931
|
const { delta } = choice;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
932
|
+
const structuredResponse = isParseableResponseFormat(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format);
|
|
933
|
+
const boundedSnapshot = structuredResponse || __classPrivateFieldGet(this, _ChatCompletionStream_hasAutoParseableTool, "f");
|
|
934
|
+
const messageSnapshot = boundedSnapshot
|
|
935
|
+
? captureStructuredMessageSnapshot(choiceSnapshot)
|
|
936
|
+
: choiceSnapshot.message;
|
|
937
|
+
const refusal = boundedSnapshot
|
|
938
|
+
? captureStructuredJSONSnapshot(messageSnapshot, 'refusal')
|
|
939
|
+
: messageSnapshot.refusal;
|
|
940
|
+
const parseableContent = !refusal && structuredResponse;
|
|
941
|
+
const messageContent = parseableContent
|
|
942
|
+
? captureStructuredJSONSnapshot(messageSnapshot, 'content')
|
|
943
|
+
: messageSnapshot.content;
|
|
944
|
+
if (delta?.content != null && messageSnapshot.role === 'assistant' && messageContent) {
|
|
945
|
+
this._emit('content', delta.content, messageContent);
|
|
185
946
|
this._emit('content.delta', {
|
|
186
947
|
delta: delta.content,
|
|
187
|
-
snapshot:
|
|
188
|
-
parsed:
|
|
948
|
+
snapshot: messageContent,
|
|
949
|
+
parsed: messageSnapshot.parsed,
|
|
189
950
|
});
|
|
190
951
|
}
|
|
191
|
-
if (delta?.refusal != null &&
|
|
192
|
-
choiceSnapshot.message?.role === 'assistant' &&
|
|
193
|
-
choiceSnapshot.message?.refusal) {
|
|
952
|
+
if (delta?.refusal != null && messageSnapshot.role === 'assistant' && refusal) {
|
|
194
953
|
this._emit('refusal.delta', {
|
|
195
954
|
delta: delta.refusal,
|
|
196
|
-
snapshot:
|
|
955
|
+
snapshot: refusal,
|
|
197
956
|
});
|
|
198
957
|
}
|
|
199
|
-
if (choice.logprobs?.content != null &&
|
|
958
|
+
if (choice.logprobs?.content != null && messageSnapshot.role === 'assistant') {
|
|
200
959
|
this._emit('logprobs.content.delta', {
|
|
201
960
|
content: choice.logprobs?.content,
|
|
202
961
|
snapshot: choiceSnapshot.logprobs?.content ?? [],
|
|
203
962
|
});
|
|
204
963
|
}
|
|
205
|
-
if (choice.logprobs?.refusal != null &&
|
|
964
|
+
if (choice.logprobs?.refusal != null && messageSnapshot.role === 'assistant') {
|
|
206
965
|
this._emit('logprobs.refusal.delta', {
|
|
207
966
|
refusal: choice.logprobs?.refusal,
|
|
208
967
|
snapshot: choiceSnapshot.logprobs?.refusal ?? [],
|
|
@@ -215,7 +974,7 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
215
974
|
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index);
|
|
216
975
|
}
|
|
217
976
|
}
|
|
218
|
-
for (const toolCall of
|
|
977
|
+
for (const toolCall of capturedToolCalls) {
|
|
219
978
|
if (state.current_tool_call_index !== toolCall.index) {
|
|
220
979
|
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
|
|
221
980
|
// new tool call started, the previous one is done
|
|
@@ -225,18 +984,30 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
225
984
|
}
|
|
226
985
|
state.current_tool_call_index = toolCall.index;
|
|
227
986
|
}
|
|
228
|
-
for (const toolCallDelta of
|
|
229
|
-
const toolCallSnapshot =
|
|
987
|
+
for (const toolCallDelta of capturedToolCalls) {
|
|
988
|
+
const toolCallSnapshot = messageSnapshot.tool_calls?.[toolCallDelta.index];
|
|
230
989
|
if (!toolCallSnapshot?.type) {
|
|
231
990
|
continue;
|
|
232
991
|
}
|
|
233
992
|
if (toolCallSnapshot.type === 'function') {
|
|
993
|
+
const boundIdentity = state.tool_call_identities.get(toolCallDelta.index);
|
|
994
|
+
let argumentsSnapshot;
|
|
995
|
+
if (boundIdentity?.parseable) {
|
|
996
|
+
const capturedArguments = captureStructuredJSONSnapshot(toolCallSnapshot.function, 'arguments');
|
|
997
|
+
if (typeof capturedArguments !== 'string') {
|
|
998
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
999
|
+
}
|
|
1000
|
+
argumentsSnapshot = capturedArguments;
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
argumentsSnapshot = toolCallSnapshot.function.arguments;
|
|
1004
|
+
}
|
|
234
1005
|
this._emit('tool_calls.function.arguments.delta', {
|
|
235
1006
|
name: toolCallSnapshot.function.name,
|
|
236
1007
|
index: toolCallDelta.index,
|
|
237
|
-
arguments:
|
|
1008
|
+
arguments: argumentsSnapshot,
|
|
238
1009
|
parsed_arguments: toolCallSnapshot.function.parsed_arguments,
|
|
239
|
-
arguments_delta: toolCallDelta.
|
|
1010
|
+
arguments_delta: toolCallDelta.arguments_delta,
|
|
240
1011
|
});
|
|
241
1012
|
}
|
|
242
1013
|
else if (toolCallSnapshot.type !== 'custom') {
|
|
@@ -250,26 +1021,48 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
250
1021
|
// we've already fired the done event
|
|
251
1022
|
return;
|
|
252
1023
|
}
|
|
253
|
-
const
|
|
1024
|
+
const messageSnapshot = __classPrivateFieldGet(this, _ChatCompletionStream_hasAutoParseableTool, "f")
|
|
1025
|
+
? captureStructuredMessageSnapshot(choiceSnapshot)
|
|
1026
|
+
: choiceSnapshot.message;
|
|
1027
|
+
const toolCallSnapshot = messageSnapshot.tool_calls?.[toolCallIndex];
|
|
254
1028
|
if (!toolCallSnapshot) {
|
|
255
1029
|
throw new Error('no tool call snapshot');
|
|
256
1030
|
}
|
|
1031
|
+
const boundIdentity = state.tool_call_identities.get(toolCallIndex);
|
|
1032
|
+
if (boundIdentity) {
|
|
1033
|
+
assertBoundToolCallIdentity(toolCallSnapshot, boundIdentity);
|
|
1034
|
+
}
|
|
257
1035
|
if (!toolCallSnapshot.type) {
|
|
258
1036
|
throw new Error('tool call snapshot missing `type`');
|
|
259
1037
|
}
|
|
260
1038
|
if (toolCallSnapshot.type === 'function') {
|
|
261
1039
|
const inputTool = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.tools?.find((tool) => isChatCompletionFunctionTool(tool) && tool.function.name === toolCallSnapshot.function.name); // TS doesn't narrow based on isChatCompletionTool
|
|
262
1040
|
let parsedArguments = null;
|
|
1041
|
+
const parseable = isAutoParsableTool(inputTool) || inputTool?.function.strict === true;
|
|
1042
|
+
let argumentsSnapshot;
|
|
1043
|
+
if (parseable) {
|
|
1044
|
+
if (__classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f")) {
|
|
1045
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_validateStructuredSnapshots).call(this, __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"));
|
|
1046
|
+
}
|
|
1047
|
+
const capturedArguments = captureStructuredJSONSnapshot(toolCallSnapshot.function, 'arguments');
|
|
1048
|
+
if (typeof capturedArguments !== 'string') {
|
|
1049
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1050
|
+
}
|
|
1051
|
+
argumentsSnapshot = capturedArguments;
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
argumentsSnapshot = toolCallSnapshot.function.arguments;
|
|
1055
|
+
}
|
|
263
1056
|
if (isAutoParsableTool(inputTool)) {
|
|
264
|
-
parsedArguments = inputTool.$parseRaw(
|
|
1057
|
+
parsedArguments = inputTool.$parseRaw(validateStructuredJSONSnapshot(argumentsSnapshot));
|
|
265
1058
|
}
|
|
266
1059
|
else if (inputTool?.function.strict) {
|
|
267
|
-
parsedArguments =
|
|
1060
|
+
parsedArguments = parseResponseFormatContent({ type: 'json_schema', $parseRaw: undefined }, validateStructuredJSONSnapshot(argumentsSnapshot));
|
|
268
1061
|
}
|
|
269
1062
|
this._emit('tool_calls.function.arguments.done', {
|
|
270
1063
|
name: toolCallSnapshot.function.name,
|
|
271
1064
|
index: toolCallIndex,
|
|
272
|
-
arguments:
|
|
1065
|
+
arguments: argumentsSnapshot,
|
|
273
1066
|
parsed_arguments: parsedArguments,
|
|
274
1067
|
});
|
|
275
1068
|
}
|
|
@@ -278,23 +1071,36 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
278
1071
|
}
|
|
279
1072
|
}, _ChatCompletionStream_emitContentDoneEvents = function _ChatCompletionStream_emitContentDoneEvents(choiceSnapshot) {
|
|
280
1073
|
const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
1074
|
+
const structuredResponse = isParseableResponseFormat(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format);
|
|
1075
|
+
const boundedSnapshot = structuredResponse || __classPrivateFieldGet(this, _ChatCompletionStream_hasAutoParseableTool, "f");
|
|
1076
|
+
const messageSnapshot = boundedSnapshot
|
|
1077
|
+
? captureStructuredMessageSnapshot(choiceSnapshot)
|
|
1078
|
+
: choiceSnapshot.message;
|
|
1079
|
+
const refusal = boundedSnapshot
|
|
1080
|
+
? captureStructuredJSONSnapshot(messageSnapshot, 'refusal')
|
|
1081
|
+
: messageSnapshot.refusal;
|
|
1082
|
+
const parseableContent = !refusal && structuredResponse;
|
|
1083
|
+
const content = parseableContent
|
|
1084
|
+
? captureStructuredJSONSnapshot(messageSnapshot, 'content')
|
|
1085
|
+
: messageSnapshot.content;
|
|
1086
|
+
if (content != null &&
|
|
1087
|
+
(content !== '' ||
|
|
1088
|
+
(!refusal && !messageSnapshot.tool_calls?.length && !messageSnapshot.function_call)) &&
|
|
286
1089
|
!state.content_done) {
|
|
1090
|
+
if (parseableContent && __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f")) {
|
|
1091
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_validateStructuredSnapshots).call(this, __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"));
|
|
1092
|
+
}
|
|
287
1093
|
state.content_done = true;
|
|
288
1094
|
this._emit('content.done', {
|
|
289
|
-
content
|
|
290
|
-
parsed:
|
|
1095
|
+
content,
|
|
1096
|
+
parsed: refusal
|
|
291
1097
|
? null
|
|
292
|
-
: parseResponseFormatContent(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format,
|
|
1098
|
+
: parseResponseFormatContent(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format, parseableContent ? validateStructuredJSONSnapshot(content) : content),
|
|
293
1099
|
});
|
|
294
1100
|
}
|
|
295
|
-
if (
|
|
1101
|
+
if (refusal && !state.refusal_done) {
|
|
296
1102
|
state.refusal_done = true;
|
|
297
|
-
this._emit('refusal.done', { refusal
|
|
1103
|
+
this._emit('refusal.done', { refusal });
|
|
298
1104
|
}
|
|
299
1105
|
if (choiceSnapshot.logprobs?.content && !state.logprobs_content_done) {
|
|
300
1106
|
state.logprobs_content_done = true;
|
|
@@ -304,6 +1110,97 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
304
1110
|
state.logprobs_refusal_done = true;
|
|
305
1111
|
this._emit('logprobs.refusal.done', { refusal: choiceSnapshot.logprobs.refusal });
|
|
306
1112
|
}
|
|
1113
|
+
}, _ChatCompletionStream_validateStructuredSnapshots = function _ChatCompletionStream_validateStructuredSnapshots(snapshot) {
|
|
1114
|
+
const finalJSONBudget = { bytes: 0, fragments: 0, work: 0 };
|
|
1115
|
+
const parseableContent = isParseableResponseFormat(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format);
|
|
1116
|
+
const validatedMessages = new WeakMap();
|
|
1117
|
+
const choices = captureSnapshotArray(snapshot, 'choices', MAX_STREAM_CHOICES, 'choice');
|
|
1118
|
+
if (!choices) {
|
|
1119
|
+
throw new OpenAIError('Chat completion stream contains an unsafe snapshot choice collection');
|
|
1120
|
+
}
|
|
1121
|
+
for (let choiceIndex = 0; choiceIndex < choices.length; choiceIndex += 1) {
|
|
1122
|
+
const choice = captureSnapshotArrayItem(choices, choiceIndex);
|
|
1123
|
+
if (!choice) {
|
|
1124
|
+
continue;
|
|
1125
|
+
}
|
|
1126
|
+
const message = captureStructuredMessageSnapshot(choice);
|
|
1127
|
+
const refusal = captureStructuredJSONSnapshot(message, 'refusal');
|
|
1128
|
+
const content = captureStructuredJSONSnapshot(message, 'content');
|
|
1129
|
+
const validatedTools = new Map();
|
|
1130
|
+
const toolCalls = captureSnapshotArray(message, 'tool_calls', MAX_STREAM_TOOL_CALLS, 'tool-call');
|
|
1131
|
+
validatedMessages.set(choice, Object.freeze({
|
|
1132
|
+
message,
|
|
1133
|
+
content,
|
|
1134
|
+
refusal,
|
|
1135
|
+
toolCallCollection: toolCalls,
|
|
1136
|
+
toolCalls: validatedTools,
|
|
1137
|
+
}));
|
|
1138
|
+
const state = __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index];
|
|
1139
|
+
if (parseableContent && !refusal && typeof content === 'string') {
|
|
1140
|
+
validateStructuredJSONSnapshot(content, finalJSONBudget, __classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f"));
|
|
1141
|
+
}
|
|
1142
|
+
for (const [index, identity] of state?.tool_call_identities ?? []) {
|
|
1143
|
+
const toolCall = toolCalls && captureSnapshotArrayItem(toolCalls, index);
|
|
1144
|
+
if (!toolCall) {
|
|
1145
|
+
throw new OpenAIError('Chat completion stream contains a changed tool call identity');
|
|
1146
|
+
}
|
|
1147
|
+
assertBoundToolCallIdentity(toolCall, identity);
|
|
1148
|
+
}
|
|
1149
|
+
if (!__classPrivateFieldGet(this, _ChatCompletionStream_hasAutoParseableTool, "f")) {
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
for (let toolCallIndex = 0; toolCallIndex < (toolCalls?.length ?? 0); toolCallIndex += 1) {
|
|
1153
|
+
const toolCall = captureSnapshotArrayItem(toolCalls, toolCallIndex);
|
|
1154
|
+
if (!toolCall) {
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
const identity = ownFunctionToolIdentity(toolCall);
|
|
1158
|
+
if (!identity) {
|
|
1159
|
+
const type = Object.getOwnPropertyDescriptor(toolCall, 'type');
|
|
1160
|
+
if (type && !('value' in type)) {
|
|
1161
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1162
|
+
}
|
|
1163
|
+
if (type?.value !== 'function') {
|
|
1164
|
+
continue;
|
|
1165
|
+
}
|
|
1166
|
+
const fn = Object.getOwnPropertyDescriptor(toolCall, 'function');
|
|
1167
|
+
if (fn && !('value' in fn)) {
|
|
1168
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1169
|
+
}
|
|
1170
|
+
if (fn && typeof fn.value === 'object' && fn.value !== null) {
|
|
1171
|
+
const name = Object.getOwnPropertyDescriptor(fn.value, 'name');
|
|
1172
|
+
if (name && !('value' in name)) {
|
|
1173
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
continue;
|
|
1177
|
+
}
|
|
1178
|
+
if (!shouldParseToolCall(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), {
|
|
1179
|
+
type: identity.type,
|
|
1180
|
+
function: { name: identity.name },
|
|
1181
|
+
})) {
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
const descriptor = Object.getOwnPropertyDescriptor(toolCall, 'function');
|
|
1185
|
+
if (!descriptor || !('value' in descriptor)) {
|
|
1186
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1187
|
+
}
|
|
1188
|
+
const fn = descriptor.value;
|
|
1189
|
+
const argumentsSnapshot = captureStructuredJSONSnapshot(fn, 'arguments');
|
|
1190
|
+
if (typeof argumentsSnapshot !== 'string') {
|
|
1191
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1192
|
+
}
|
|
1193
|
+
validateStructuredJSONSnapshot(argumentsSnapshot, finalJSONBudget, __classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f"));
|
|
1194
|
+
validatedTools.set(toolCallIndex, Object.freeze({
|
|
1195
|
+
tool: toolCall,
|
|
1196
|
+
function: fn,
|
|
1197
|
+
type: identity.type,
|
|
1198
|
+
name: identity.name,
|
|
1199
|
+
arguments: argumentsSnapshot,
|
|
1200
|
+
}));
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return validatedMessages;
|
|
307
1204
|
}, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest() {
|
|
308
1205
|
if (this.ended) {
|
|
309
1206
|
throw new OpenAIError(`stream has ended, this shouldn't happen`);
|
|
@@ -312,15 +1209,16 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
312
1209
|
if (!snapshot) {
|
|
313
1210
|
throw new OpenAIError(`request ended without sending any chunks`);
|
|
314
1211
|
}
|
|
1212
|
+
const validatedMessages = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_validateStructuredSnapshots).call(this, snapshot);
|
|
315
1213
|
const audioDoneChoiceIndexes = __classPrivateFieldGet(this, _ChatCompletionStream_audioDoneChoiceIndexes, "f");
|
|
316
1214
|
__classPrivateFieldSet(this, _ChatCompletionStream_audioDoneChoiceIndexes, new Set(), "f");
|
|
317
1215
|
__classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
|
|
318
1216
|
__classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
|
|
319
|
-
return finalizeChatCompletion(snapshot, __classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), audioDoneChoiceIndexes);
|
|
320
|
-
}, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion(chunk) {
|
|
1217
|
+
return finalizeChatCompletion(snapshot, __classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), audioDoneChoiceIndexes, validatedMessages);
|
|
1218
|
+
}, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion(chunk, capturedChoiceFrames) {
|
|
321
1219
|
var _a, _b, _c, _d, _e;
|
|
322
1220
|
let snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
|
|
323
|
-
const { choices, ...rest } = chunk;
|
|
1221
|
+
const { choices, obfuscation: _obfuscation, ...rest } = chunk;
|
|
324
1222
|
if (!snapshot) {
|
|
325
1223
|
const newSnapshot = {
|
|
326
1224
|
...rest,
|
|
@@ -338,16 +1236,22 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
338
1236
|
requestedChoiceCount > 0
|
|
339
1237
|
? Math.min(requestedChoiceCount, MAX_STREAM_CHOICES)
|
|
340
1238
|
: MAX_STREAM_CHOICES;
|
|
341
|
-
for (const
|
|
1239
|
+
for (const chunkChoice of chunk.choices) {
|
|
1240
|
+
const { delta, finish_reason, index, logprobs = null, ...other } = chunkChoice;
|
|
1241
|
+
const capturedToolCalls = [];
|
|
1242
|
+
capturedChoiceFrames.set(chunkChoice, Object.freeze({ index, tool_calls: capturedToolCalls }));
|
|
342
1243
|
if (!Number.isSafeInteger(index) || index < 0 || index >= maxChoices) {
|
|
343
1244
|
throw new OpenAIError(`Chat completion stream contains an invalid choice index: ${index}`);
|
|
344
1245
|
}
|
|
345
1246
|
let choice = snapshot.choices[index];
|
|
346
1247
|
if (!choice) {
|
|
347
|
-
const newChoice = { finish_reason, index, message: {}, logprobs, ...other };
|
|
1248
|
+
const newChoice = { finish_reason, index, message: {}, logprobs: null, ...other };
|
|
348
1249
|
snapshot.choices[index] = newChoice;
|
|
349
1250
|
choice = newChoice;
|
|
350
1251
|
}
|
|
1252
|
+
if (isParseableResponseFormat(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format) || __classPrivateFieldGet(this, _ChatCompletionStream_hasAutoParseableTool, "f")) {
|
|
1253
|
+
captureStructuredJSONSnapshot(captureStructuredMessageSnapshot(choice), 'refusal');
|
|
1254
|
+
}
|
|
351
1255
|
if (logprobs) {
|
|
352
1256
|
if (choice.logprobs) {
|
|
353
1257
|
const { content, refusal, ...rest } = logprobs;
|
|
@@ -364,6 +1268,12 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
364
1268
|
}
|
|
365
1269
|
else {
|
|
366
1270
|
choice.logprobs = { ...logprobs };
|
|
1271
|
+
if (logprobs.content) {
|
|
1272
|
+
choice.logprobs.content = [...logprobs.content];
|
|
1273
|
+
}
|
|
1274
|
+
if (logprobs.refusal) {
|
|
1275
|
+
choice.logprobs.refusal = [...logprobs.refusal];
|
|
1276
|
+
}
|
|
367
1277
|
}
|
|
368
1278
|
}
|
|
369
1279
|
if (finish_reason) {
|
|
@@ -379,10 +1289,13 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
379
1289
|
}
|
|
380
1290
|
assignOwnProperties(choice, other);
|
|
381
1291
|
if (!delta) {
|
|
1292
|
+
Object.freeze(capturedToolCalls);
|
|
382
1293
|
continue;
|
|
383
1294
|
} // Shouldn't happen; just in case.
|
|
384
1295
|
__classPrivateFieldGet(this, _ChatCompletionStream_audioDoneChoiceIndexes, "f").delete(index);
|
|
385
|
-
const { audio, content, refusal, function_call, role,
|
|
1296
|
+
const { audio, content, refusal, function_call, role, ...capturedDeltaFields } = delta;
|
|
1297
|
+
const { tool_calls: capturedToolCallDelta, ...rest } = capturedDeltaFields;
|
|
1298
|
+
const tool_calls = hasOwn(capturedDeltaFields, 'tool_calls') ? capturedToolCallDelta : delta.tool_calls;
|
|
386
1299
|
assertIsEmpty(rest);
|
|
387
1300
|
assignOwnProperties(choice.message, rest);
|
|
388
1301
|
if (audio?.expires_at != null &&
|
|
@@ -433,10 +1346,26 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
433
1346
|
}
|
|
434
1347
|
}
|
|
435
1348
|
if (content != null) {
|
|
436
|
-
choice.message.content = (choice.message.content || '') + content;
|
|
437
1349
|
if (!choice.message.refusal && isParseableResponseFormat(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format)) {
|
|
438
|
-
|
|
439
|
-
|
|
1350
|
+
const eventState = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choice);
|
|
1351
|
+
const parseState = (eventState.content_parse_state ?? (eventState.content_parse_state = createPartialJSONParseState()));
|
|
1352
|
+
const shouldParse = recordPartialJSONFragment(parseState, __classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f"), content);
|
|
1353
|
+
choice.message.content = (captureStructuredJSONSnapshot(choice.message, 'content') || '') + content;
|
|
1354
|
+
// The partial parser does not accept whitespace-only input. Once output
|
|
1355
|
+
// grows, coalesce prefix reparses while preserving every raw snapshot.
|
|
1356
|
+
if (!parseState.has_non_whitespace) {
|
|
1357
|
+
choice.message.parsed = null;
|
|
1358
|
+
}
|
|
1359
|
+
else if (shouldParse && reservePartialJSONParse(parseState, __classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f"))) {
|
|
1360
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_validateStructuredSnapshots).call(this, snapshot);
|
|
1361
|
+
choice.message.parsed = parseStructuredStreamingJSON(validateStructuredJSONSnapshot(choice.message.content));
|
|
1362
|
+
}
|
|
1363
|
+
else if (content.length > 0) {
|
|
1364
|
+
choice.message.parsed = null;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
else {
|
|
1368
|
+
choice.message.content = (choice.message.content || '') + content;
|
|
440
1369
|
}
|
|
441
1370
|
}
|
|
442
1371
|
if (tool_calls) {
|
|
@@ -444,11 +1373,23 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
444
1373
|
// entries are only partially filled in; they match `ChatCompletionSnapshot.Choice.Message.ToolCall`
|
|
445
1374
|
// once every delta for them has been accumulated.
|
|
446
1375
|
const toolCallSnapshots = ((_e = choice.message).tool_calls ?? (_e.tool_calls = []));
|
|
447
|
-
for (const
|
|
1376
|
+
for (const toolCallDelta of tool_calls) {
|
|
1377
|
+
const { index, id, type, function: fn, custom, ...rest } = toolCallDelta;
|
|
448
1378
|
if (!Number.isSafeInteger(index) || index < 0 || index >= MAX_STREAM_TOOL_CALLS) {
|
|
449
1379
|
throw new OpenAIError(`Chat completion stream contains an invalid tool call index: ${index}`);
|
|
450
1380
|
}
|
|
1381
|
+
let argumentsDelta = '';
|
|
451
1382
|
const tool_call = (toolCallSnapshots[index] ?? (toolCallSnapshots[index] = {}));
|
|
1383
|
+
const functionName = fn?.name;
|
|
1384
|
+
const eventState = __classPrivateFieldGet(this, _ChatCompletionStream_hasAutoParseableTool, "f") ? __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choice) : undefined;
|
|
1385
|
+
let boundIdentity = eventState?.tool_call_identities.get(index);
|
|
1386
|
+
if (boundIdentity) {
|
|
1387
|
+
assertBoundToolCallIdentity(tool_call, boundIdentity);
|
|
1388
|
+
if ((type !== undefined && type !== boundIdentity.type) ||
|
|
1389
|
+
(functionName !== undefined && functionName !== boundIdentity.name)) {
|
|
1390
|
+
throw new OpenAIError('Chat completion stream contains a changed tool call identity');
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
452
1393
|
assignOwnProperties(tool_call, rest);
|
|
453
1394
|
if (id) {
|
|
454
1395
|
tool_call.id = id;
|
|
@@ -466,19 +1407,69 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
466
1407
|
}
|
|
467
1408
|
}
|
|
468
1409
|
if (fn) {
|
|
469
|
-
const functionSnapshot = (tool_call.function ?? (tool_call.function = { name:
|
|
470
|
-
if (
|
|
471
|
-
functionSnapshot.name =
|
|
1410
|
+
const functionSnapshot = (tool_call.function ?? (tool_call.function = { name: functionName ?? '', arguments: '' }));
|
|
1411
|
+
if (functionName) {
|
|
1412
|
+
functionSnapshot.name = functionName;
|
|
472
1413
|
}
|
|
473
|
-
if (
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
1414
|
+
if (eventState && !boundIdentity) {
|
|
1415
|
+
const identity = ownFunctionToolIdentity(tool_call);
|
|
1416
|
+
const configuredTool = identity &&
|
|
1417
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.tools?.find((tool) => isChatCompletionFunctionTool(tool) && tool.function.name === identity.name);
|
|
1418
|
+
if (identity) {
|
|
1419
|
+
boundIdentity = {
|
|
1420
|
+
...identity,
|
|
1421
|
+
parseable: configuredTool !== undefined &&
|
|
1422
|
+
shouldParseToolCall(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), {
|
|
1423
|
+
type: identity.type,
|
|
1424
|
+
function: { name: identity.name },
|
|
1425
|
+
}),
|
|
1426
|
+
};
|
|
1427
|
+
eventState.tool_call_identities.set(index, boundIdentity);
|
|
1428
|
+
if (!boundIdentity.parseable) {
|
|
1429
|
+
const provisionalState = eventState.tool_call_parse_states.get(index);
|
|
1430
|
+
if (provisionalState) {
|
|
1431
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f").bytes -= provisionalState.bytes;
|
|
1432
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f").fragments -= provisionalState.fragments;
|
|
1433
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f").work -= provisionalState.work;
|
|
1434
|
+
eventState.tool_call_parse_states.delete(index);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
const argumentFragment = fn.arguments;
|
|
1440
|
+
if (argumentFragment != null) {
|
|
1441
|
+
argumentsDelta = argumentFragment;
|
|
1442
|
+
if (eventState && boundIdentity?.parseable !== false) {
|
|
1443
|
+
let parseState = eventState.tool_call_parse_states.get(index);
|
|
1444
|
+
if (!parseState) {
|
|
1445
|
+
parseState = createPartialJSONParseState();
|
|
1446
|
+
eventState.tool_call_parse_states.set(index, parseState);
|
|
1447
|
+
}
|
|
1448
|
+
const shouldParse = recordPartialJSONFragment(parseState, __classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f"), argumentFragment);
|
|
1449
|
+
const previousArguments = captureStructuredJSONSnapshot(functionSnapshot, 'arguments');
|
|
1450
|
+
if (typeof previousArguments !== 'string') {
|
|
1451
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1452
|
+
}
|
|
1453
|
+
functionSnapshot.arguments = previousArguments + argumentFragment;
|
|
1454
|
+
if (shouldParse &&
|
|
1455
|
+
boundIdentity?.parseable === true &&
|
|
1456
|
+
reservePartialJSONParse(parseState, __classPrivateFieldGet(this, _ChatCompletionStream_partialJSONParseBudget, "f"))) {
|
|
1457
|
+
__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_validateStructuredSnapshots).call(this, snapshot);
|
|
1458
|
+
functionSnapshot.parsed_arguments = parseStructuredStreamingJSON(validateStructuredJSONSnapshot(functionSnapshot.arguments));
|
|
1459
|
+
}
|
|
1460
|
+
else if (argumentFragment.length > 0 && hasOwn(functionSnapshot, 'parsed_arguments')) {
|
|
1461
|
+
functionSnapshot.parsed_arguments = undefined;
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
else {
|
|
1465
|
+
functionSnapshot.arguments += argumentFragment;
|
|
477
1466
|
}
|
|
478
1467
|
}
|
|
479
1468
|
}
|
|
1469
|
+
capturedToolCalls.push(Object.freeze({ index, arguments_delta: argumentsDelta }));
|
|
480
1470
|
}
|
|
481
1471
|
}
|
|
1472
|
+
Object.freeze(capturedToolCalls);
|
|
482
1473
|
}
|
|
483
1474
|
return snapshot;
|
|
484
1475
|
}, Symbol.asyncIterator)]() {
|
|
@@ -494,12 +1485,36 @@ export class ChatCompletionStream extends AbstractChatCompletionRunner {
|
|
|
494
1485
|
return stream.toReadableStream();
|
|
495
1486
|
}
|
|
496
1487
|
}
|
|
497
|
-
function finalizeChatCompletion(snapshot, params, audioDoneChoiceIndexes) {
|
|
1488
|
+
function finalizeChatCompletion(snapshot, params, audioDoneChoiceIndexes, validatedMessages) {
|
|
498
1489
|
const { id, choices, created, model, system_fingerprint, ...rest } = snapshot;
|
|
499
1490
|
const completion = {
|
|
500
1491
|
...rest,
|
|
501
1492
|
id,
|
|
502
|
-
choices: choices
|
|
1493
|
+
choices: mapCapturedSnapshotArray(choices, MAX_STREAM_CHOICES, 'choice', (choice) => {
|
|
1494
|
+
const validated = validatedMessages.get(choice);
|
|
1495
|
+
if (!validated) {
|
|
1496
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1497
|
+
}
|
|
1498
|
+
const stableChoice = new Proxy(choice, {
|
|
1499
|
+
get(target, property, receiver) {
|
|
1500
|
+
return property === 'message' ? validated.message : Reflect.get(target, property, receiver);
|
|
1501
|
+
},
|
|
1502
|
+
});
|
|
1503
|
+
const { message: sourceMessage, finish_reason, index, logprobs, ...choiceRest } = stableChoice;
|
|
1504
|
+
const message = new Proxy(sourceMessage, {
|
|
1505
|
+
get(target, property, receiver) {
|
|
1506
|
+
if (property === 'content') {
|
|
1507
|
+
return validated.content;
|
|
1508
|
+
}
|
|
1509
|
+
if (property === 'refusal') {
|
|
1510
|
+
return validated.refusal;
|
|
1511
|
+
}
|
|
1512
|
+
if (property === 'tool_calls') {
|
|
1513
|
+
return validated.toolCallCollection;
|
|
1514
|
+
}
|
|
1515
|
+
return Reflect.get(target, property, receiver);
|
|
1516
|
+
},
|
|
1517
|
+
});
|
|
503
1518
|
const { content = null, function_call, tool_calls, audio, ...messageRest } = message;
|
|
504
1519
|
// Audio streams can end with an expires_at-only chunk after the
|
|
505
1520
|
// generated audio, without a separate finish_reason.
|
|
@@ -546,15 +1561,54 @@ function finalizeChatCompletion(snapshot, params, audioDoneChoiceIndexes) {
|
|
|
546
1561
|
role,
|
|
547
1562
|
content,
|
|
548
1563
|
refusal: message.refusal ?? null,
|
|
549
|
-
tool_calls: tool_calls
|
|
550
|
-
|
|
551
|
-
|
|
1564
|
+
tool_calls: mapCapturedSnapshotArray(tool_calls, MAX_STREAM_TOOL_CALLS, 'tool-call', (tool_call, i) => {
|
|
1565
|
+
const captured = validated.toolCalls.get(i);
|
|
1566
|
+
if (!captured) {
|
|
1567
|
+
const identity = ownFunctionToolIdentity(tool_call);
|
|
1568
|
+
if (identity &&
|
|
1569
|
+
shouldParseToolCall(params, {
|
|
1570
|
+
type: identity.type,
|
|
1571
|
+
function: { name: identity.name },
|
|
1572
|
+
})) {
|
|
1573
|
+
throw new OpenAIError('Chat completion stream contains an unsafe structured JSON snapshot');
|
|
1574
|
+
}
|
|
552
1575
|
}
|
|
553
|
-
if (
|
|
554
|
-
|
|
1576
|
+
if (captured && captured.tool !== tool_call) {
|
|
1577
|
+
throw new OpenAIError('Chat completion stream contains a changed tool call identity');
|
|
1578
|
+
}
|
|
1579
|
+
const stableFunction = captured &&
|
|
1580
|
+
new Proxy(captured.function, {
|
|
1581
|
+
get(target, property, receiver) {
|
|
1582
|
+
if (property === 'arguments') {
|
|
1583
|
+
return captured.arguments;
|
|
1584
|
+
}
|
|
1585
|
+
if (property === 'name') {
|
|
1586
|
+
return captured.name;
|
|
1587
|
+
}
|
|
1588
|
+
return Reflect.get(target, property, receiver);
|
|
1589
|
+
},
|
|
1590
|
+
});
|
|
1591
|
+
const stableTool = captured && stableFunction
|
|
1592
|
+
? new Proxy(tool_call, {
|
|
1593
|
+
get(target, property, receiver) {
|
|
1594
|
+
if (property === 'type') {
|
|
1595
|
+
return captured.type;
|
|
1596
|
+
}
|
|
1597
|
+
if (property === 'function') {
|
|
1598
|
+
return stableFunction;
|
|
1599
|
+
}
|
|
1600
|
+
return Reflect.get(target, property, receiver);
|
|
1601
|
+
},
|
|
1602
|
+
})
|
|
1603
|
+
: tool_call;
|
|
1604
|
+
if (stableTool.type == null) {
|
|
1605
|
+
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].type`);
|
|
1606
|
+
}
|
|
1607
|
+
if (stableTool.type === 'custom') {
|
|
1608
|
+
const { custom, type, id, ...toolRest } = stableTool;
|
|
555
1609
|
const { input = '', name, ...customRest } = custom || {};
|
|
556
1610
|
if (name == null) {
|
|
557
|
-
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].custom.name
|
|
1611
|
+
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].custom.name`);
|
|
558
1612
|
}
|
|
559
1613
|
return {
|
|
560
1614
|
...toolRest,
|
|
@@ -563,13 +1617,13 @@ function finalizeChatCompletion(snapshot, params, audioDoneChoiceIndexes) {
|
|
|
563
1617
|
custom: { ...customRest, name, input },
|
|
564
1618
|
};
|
|
565
1619
|
}
|
|
566
|
-
const { function: fn, type, id, ...toolRest } =
|
|
1620
|
+
const { function: fn, type, id, ...toolRest } = stableTool;
|
|
567
1621
|
const { arguments: args, name, ...fnRest } = fn || {};
|
|
568
1622
|
if (name == null) {
|
|
569
|
-
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name
|
|
1623
|
+
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name`);
|
|
570
1624
|
}
|
|
571
1625
|
if (args == null) {
|
|
572
|
-
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments
|
|
1626
|
+
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments`);
|
|
573
1627
|
}
|
|
574
1628
|
return {
|
|
575
1629
|
...toolRest,
|
|
@@ -599,9 +1653,6 @@ function finalizeChatCompletion(snapshot, params, audioDoneChoiceIndexes) {
|
|
|
599
1653
|
function isCompleteAudio(audio) {
|
|
600
1654
|
return audio?.id != null && audio.data != null && audio.transcript != null && audio.expires_at != null;
|
|
601
1655
|
}
|
|
602
|
-
function str(x) {
|
|
603
|
-
return JSON.stringify(x);
|
|
604
|
-
}
|
|
605
1656
|
/**
|
|
606
1657
|
* Ensures the given argument is an empty object, useful for
|
|
607
1658
|
* asserting that all known properties on an object have been
|