openai 7.7.0 → 7.8.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 +18 -0
- package/README.md +15 -30
- 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/types.d.mts +9 -4
- package/auth/types.d.mts.map +1 -1
- package/auth/types.d.ts +9 -4
- package/auth/types.d.ts.map +1 -1
- package/auth/workload-identity-auth.d.mts +1 -1
- package/auth/workload-identity-auth.d.mts.map +1 -1
- package/auth/workload-identity-auth.d.ts +1 -1
- package/auth/workload-identity-auth.d.ts.map +1 -1
- package/auth/workload-identity-auth.js +23 -6
- package/auth/workload-identity-auth.js.map +1 -1
- package/auth/workload-identity-auth.mjs +23 -6
- package/auth/workload-identity-auth.mjs.map +1 -1
- package/auth/x509-transport.d.mts +36 -1
- package/auth/x509-transport.d.mts.map +1 -1
- package/auth/x509-transport.d.ts +36 -1
- package/auth/x509-transport.d.ts.map +1 -1
- package/auth/x509-transport.js +223 -0
- package/auth/x509-transport.js.map +1 -1
- package/auth/x509-transport.mjs +222 -1
- package/auth/x509-transport.mjs.map +1 -1
- package/azure.d.mts +3 -1
- package/azure.d.mts.map +1 -1
- package/azure.d.ts +3 -1
- package/azure.d.ts.map +1 -1
- package/azure.js.map +1 -1
- package/azure.mjs.map +1 -1
- package/bedrock.d.mts +3 -1
- package/bedrock.d.mts.map +1 -1
- package/bedrock.d.ts +3 -1
- package/bedrock.d.ts.map +1 -1
- package/bedrock.js.map +1 -1
- package/bedrock.mjs.map +1 -1
- package/beta/realtime/ws.d.mts.map +1 -1
- package/beta/realtime/ws.d.ts.map +1 -1
- package/beta/realtime/ws.js +2 -0
- package/beta/realtime/ws.js.map +1 -1
- package/beta/realtime/ws.mjs +2 -0
- package/beta/realtime/ws.mjs.map +1 -1
- package/client.d.mts +3 -1
- package/client.d.mts.map +1 -1
- package/client.d.ts +3 -1
- package/client.d.ts.map +1 -1
- package/client.js +30 -37
- package/client.js.map +1 -1
- package/client.mjs +31 -38
- 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 +14 -1
- package/core/EventEmitter.js.map +1 -1
- package/core/EventEmitter.mjs +14 -1
- package/core/EventEmitter.mjs.map +1 -1
- package/internal/auth/x509-api-origin.d.mts +5 -0
- package/internal/auth/x509-api-origin.d.mts.map +1 -0
- package/internal/auth/x509-api-origin.d.ts +5 -0
- package/internal/auth/x509-api-origin.d.ts.map +1 -0
- package/internal/auth/x509-api-origin.js +28 -0
- package/internal/auth/x509-api-origin.js.map +1 -0
- package/internal/auth/x509-api-origin.mjs +24 -0
- package/internal/auth/x509-api-origin.mjs.map +1 -0
- package/internal/auth/x509-credential-options.d.mts +13 -0
- package/internal/auth/x509-credential-options.d.mts.map +1 -0
- package/internal/auth/x509-credential-options.d.ts +13 -0
- package/internal/auth/x509-credential-options.d.ts.map +1 -0
- package/internal/auth/x509-credential-options.js +122 -0
- package/internal/auth/x509-credential-options.js.map +1 -0
- package/internal/auth/x509-credential-options.mjs +118 -0
- package/internal/auth/x509-credential-options.mjs.map +1 -0
- package/internal/auth/x509-token-exchange.mjs +1 -1
- package/internal/auth/x509-transport-capability.d.mts +12 -5
- package/internal/auth/x509-transport-capability.d.mts.map +1 -1
- package/internal/auth/x509-transport-capability.d.ts +12 -5
- package/internal/auth/x509-transport-capability.d.ts.map +1 -1
- package/internal/auth/x509-transport-capability.js +5 -4
- package/internal/auth/x509-transport-capability.js.map +1 -1
- package/internal/auth/x509-transport-capability.mjs +6 -5
- package/internal/auth/x509-transport-capability.mjs.map +1 -1
- package/internal/auth/x509-transport-registry.d.mts +8 -0
- package/internal/auth/x509-transport-registry.d.mts.map +1 -1
- package/internal/auth/x509-transport-registry.d.ts +8 -0
- package/internal/auth/x509-transport-registry.d.ts.map +1 -1
- package/internal/auth/x509-transport-registry.js.map +1 -1
- package/internal/auth/x509-transport-registry.mjs +1 -1
- package/internal/auth/x509-transport-registry.mjs.map +1 -1
- package/internal/auth/x509-transport-state-browser.d.mts +4 -0
- package/internal/auth/x509-transport-state-browser.d.mts.map +1 -1
- package/internal/auth/x509-transport-state-browser.d.ts +4 -0
- package/internal/auth/x509-transport-state-browser.d.ts.map +1 -1
- package/internal/auth/x509-transport-state-browser.js +6 -1
- package/internal/auth/x509-transport-state-browser.js.map +1 -1
- package/internal/auth/x509-transport-state-browser.mjs +5 -0
- package/internal/auth/x509-transport-state-browser.mjs.map +1 -1
- package/internal/auth/x509-transport-state.cjs +6 -1
- package/internal/auth/x509-transport-state.cjs.map +1 -1
- package/internal/auth/x509-transport-state.d.cts +4 -0
- package/internal/auth/x509-transport-state.d.cts.map +1 -1
- package/internal/auth/x509-transport-state.js +36 -0
- package/internal/auth/x509-transport-state.mjs +19 -0
- package/internal/auth/x509-workload-identity-auth.d.mts +2 -4
- package/internal/auth/x509-workload-identity-auth.d.mts.map +1 -1
- package/internal/auth/x509-workload-identity-auth.d.ts +2 -4
- package/internal/auth/x509-workload-identity-auth.d.ts.map +1 -1
- package/internal/auth/x509-workload-identity-auth.js +43 -34
- package/internal/auth/x509-workload-identity-auth.js.map +1 -1
- package/internal/auth/x509-workload-identity-auth.mjs +40 -30
- package/internal/auth/x509-workload-identity-auth.mjs.map +1 -1
- package/internal/uploads.js +4 -2
- package/internal/uploads.js.map +1 -1
- package/internal/uploads.mjs +4 -2
- package/internal/uploads.mjs.map +1 -1
- package/internal/utils/log.d.mts +6 -0
- package/internal/utils/log.d.mts.map +1 -1
- package/internal/utils/log.d.ts +6 -0
- package/internal/utils/log.d.ts.map +1 -1
- package/internal/utils/log.js +72 -11
- package/internal/utils/log.js.map +1 -1
- package/internal/utils/log.mjs +69 -11
- package/internal/utils/log.mjs.map +1 -1
- package/lib/EventEmitter.d.mts.map +1 -1
- package/lib/EventEmitter.d.ts.map +1 -1
- package/lib/EventEmitter.js +14 -1
- package/lib/EventEmitter.js.map +1 -1
- package/lib/EventEmitter.mjs +14 -1
- package/lib/EventEmitter.mjs.map +1 -1
- package/package.json +5 -5
- package/realtime/ws.d.mts.map +1 -1
- package/realtime/ws.d.ts.map +1 -1
- package/realtime/ws.js +2 -0
- package/realtime/ws.js.map +1 -1
- package/realtime/ws.mjs +2 -0
- package/realtime/ws.mjs.map +1 -1
- package/resources/admin/organization/audit-logs.d.mts +2 -2
- package/resources/admin/organization/audit-logs.d.mts.map +1 -1
- package/resources/admin/organization/audit-logs.d.ts +2 -2
- package/resources/admin/organization/audit-logs.d.ts.map +1 -1
- package/resources/beta/responses/responses.d.mts +4 -0
- package/resources/beta/responses/responses.d.mts.map +1 -1
- package/resources/beta/responses/responses.d.ts +4 -0
- 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/responses/ws.d.mts.map +1 -1
- package/resources/beta/responses/ws.d.ts.map +1 -1
- package/resources/beta/responses/ws.js +2 -0
- package/resources/beta/responses/ws.js.map +1 -1
- package/resources/beta/responses/ws.mjs +2 -0
- package/resources/beta/responses/ws.mjs.map +1 -1
- package/resources/completions.d.mts +4 -0
- package/resources/completions.d.mts.map +1 -1
- package/resources/completions.d.ts +4 -0
- package/resources/completions.d.ts.map +1 -1
- package/resources/responses/responses.d.mts +4 -0
- package/resources/responses/responses.d.mts.map +1 -1
- package/resources/responses/responses.d.ts +4 -0
- 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/responses/ws.d.mts.map +1 -1
- package/resources/responses/ws.d.ts.map +1 -1
- package/resources/responses/ws.js +2 -0
- package/resources/responses/ws.js.map +1 -1
- package/resources/responses/ws.mjs +2 -0
- package/resources/responses/ws.mjs.map +1 -1
- package/src/_vendor/partial-json-parser/LICENSE +21 -0
- package/src/_vendor/partial-json-parser/README.md +11 -1
- package/src/auth/index.ts +1 -0
- package/src/auth/types.ts +10 -4
- package/src/auth/workload-identity-auth.ts +30 -6
- package/src/auth/x509-transport.ts +311 -2
- package/src/azure.ts +4 -1
- package/src/bedrock.ts +4 -1
- package/src/beta/realtime/ws.ts +2 -0
- package/src/client.ts +39 -34
- package/src/core/EventEmitter.ts +13 -1
- package/src/internal/auth/x509-api-origin.ts +27 -0
- package/src/internal/auth/x509-credential-options.ts +146 -0
- package/src/internal/auth/x509-transport-capability.ts +12 -5
- package/src/internal/auth/x509-transport-registry.ts +9 -0
- package/src/internal/auth/x509-transport-state-browser.ts +7 -0
- package/src/internal/auth/x509-transport-state.cts +7 -0
- package/src/internal/auth/x509-workload-identity-auth.ts +42 -33
- package/src/internal/uploads.ts +4 -2
- package/src/internal/utils/log.ts +76 -11
- package/src/lib/EventEmitter.ts +13 -1
- package/src/realtime/ws.ts +2 -0
- package/src/resources/admin/organization/audit-logs.ts +4 -0
- package/src/resources/beta/responses/responses.ts +5 -0
- package/src/resources/beta/responses/ws.ts +3 -0
- package/src/resources/completions.ts +5 -0
- package/src/resources/responses/responses.ts +5 -0
- package/src/resources/responses/ws.ts +3 -0
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/src/core/EventEmitter.ts
CHANGED
|
@@ -186,11 +186,20 @@ export class EventEmitter<EventTypes extends Record<string, (...args: any) => an
|
|
|
186
186
|
}
|
|
187
187
|
return !listener.once && !listener.removed;
|
|
188
188
|
}) as any;
|
|
189
|
+
let listenerThrew = false;
|
|
190
|
+
let firstListenerError: unknown;
|
|
189
191
|
this.#listenerDispatchDepth += 1;
|
|
190
192
|
try {
|
|
191
193
|
for (const registration of listeners as any) {
|
|
192
194
|
if (!registration.removed) {
|
|
193
|
-
|
|
195
|
+
try {
|
|
196
|
+
registration.listener(...(args as any));
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (!listenerThrew) {
|
|
199
|
+
listenerThrew = true;
|
|
200
|
+
firstListenerError = error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
194
203
|
}
|
|
195
204
|
}
|
|
196
205
|
} finally {
|
|
@@ -199,6 +208,9 @@ export class EventEmitter<EventTypes extends Record<string, (...args: any) => an
|
|
|
199
208
|
this.#cleanupEmittedListeners();
|
|
200
209
|
}
|
|
201
210
|
}
|
|
211
|
+
if (listenerThrew) {
|
|
212
|
+
throw firstListenerError;
|
|
213
|
+
}
|
|
202
214
|
}
|
|
203
215
|
}
|
|
204
216
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { OpenAIError } from '../../core/error';
|
|
2
|
+
import { isSensitiveQueryParameter } from '../utils/log';
|
|
3
|
+
|
|
4
|
+
/** Sole API authority approved for OpenAI X.509 workload-identity federation. */
|
|
5
|
+
export const X509_API_BASE_URL = 'https://mtls.api.openai.com/v1';
|
|
6
|
+
|
|
7
|
+
/** Validates the enrolled API authority and rejects credential-bearing query parameters. */
|
|
8
|
+
export function assertX509APIOrigin(value: string | URL): URL {
|
|
9
|
+
let target: URL;
|
|
10
|
+
try {
|
|
11
|
+
target = new URL(value);
|
|
12
|
+
} catch {
|
|
13
|
+
throw new OpenAIError('X.509 workload identity requires the approved global mTLS API origin.');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (target.origin !== 'https://mtls.api.openai.com' || target.username || target.password) {
|
|
17
|
+
throw new OpenAIError('X.509 workload identity requires the approved global mTLS API origin.');
|
|
18
|
+
}
|
|
19
|
+
for (const name of target.searchParams.keys()) {
|
|
20
|
+
if (isSensitiveQueryParameter(name)) {
|
|
21
|
+
throw new OpenAIError(
|
|
22
|
+
'X.509 workload identity cannot send conflicting query authentication credentials.',
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return target;
|
|
27
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { OpenAIError } from '../../core/error';
|
|
2
|
+
import type { ClientOptions } from '../../client';
|
|
3
|
+
import type { X509Credential } from '../../auth/types';
|
|
4
|
+
import { hasOwn } from '../utils/values';
|
|
5
|
+
import { isX509WorkloadIdentity } from './x509-workload-identity-auth';
|
|
6
|
+
import type { RegisteredX509Credential } from './x509-transport-registry';
|
|
7
|
+
import { findX509Credential } from '#x509-transport-state';
|
|
8
|
+
|
|
9
|
+
/** Validates one privately registered credential and suppresses ambient legacy authentication. */
|
|
10
|
+
export function normalizeX509CredentialOptions(options: ClientOptions): {
|
|
11
|
+
credential: X509Credential | undefined;
|
|
12
|
+
options: ClientOptions;
|
|
13
|
+
} {
|
|
14
|
+
const { credential } = options;
|
|
15
|
+
if (credential === undefined) {
|
|
16
|
+
return { credential, options };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const registered: RegisteredX509Credential | undefined = findX509Credential(credential);
|
|
20
|
+
if (!registered) {
|
|
21
|
+
throw new OpenAIError('An X.509 credential must be created by the SDK authentication helper.');
|
|
22
|
+
}
|
|
23
|
+
const conflicting = (['apiKey', 'adminAPIKey', 'workloadIdentity', 'x509Transport'] as const).filter(
|
|
24
|
+
(name) => {
|
|
25
|
+
const value = options[name];
|
|
26
|
+
return value !== null && value !== undefined;
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
if (conflicting.length > 0) {
|
|
30
|
+
throw new OpenAIError(
|
|
31
|
+
`The \`credential\` option cannot be combined with ${conflicting.map((name) => `\`${name}\``).join(', ')}.`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
credential,
|
|
37
|
+
options: {
|
|
38
|
+
...options,
|
|
39
|
+
apiKey: null,
|
|
40
|
+
adminAPIKey: null,
|
|
41
|
+
baseURL: options.baseURL ?? null,
|
|
42
|
+
organization: options.organization ?? null,
|
|
43
|
+
project: options.project ?? null,
|
|
44
|
+
workloadIdentity: registered.identity,
|
|
45
|
+
x509Transport: registered.transport,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Distinguishes explicitly supplied ordinary credentials from nullish inheritance. */
|
|
51
|
+
function overridesOrdinaryAuthentication({ apiKey, adminAPIKey }: Partial<ClientOptions>): boolean {
|
|
52
|
+
return (apiKey !== null && apiKey !== undefined) || (adminAPIKey !== null && adminAPIKey !== undefined);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Keeps origin-bound configuration with its owning provider during a client clone. */
|
|
56
|
+
function prepareProviderClone(
|
|
57
|
+
inherited: ClientOptions,
|
|
58
|
+
overrides: Partial<ClientOptions>,
|
|
59
|
+
): ClientOptions['provider'] {
|
|
60
|
+
const inheritedProvider = inherited.provider;
|
|
61
|
+
const replacingProvider = overrides.credential ?? overrides.workloadIdentity;
|
|
62
|
+
const provider = overrides.provider ?? (replacingProvider ? undefined : inheritedProvider);
|
|
63
|
+
|
|
64
|
+
if (provider !== inheritedProvider) {
|
|
65
|
+
delete inherited.baseURL;
|
|
66
|
+
delete inherited.organization;
|
|
67
|
+
delete inherited.project;
|
|
68
|
+
delete inherited.defaultHeaders;
|
|
69
|
+
delete inherited.defaultQuery;
|
|
70
|
+
delete inherited.fetchOptions;
|
|
71
|
+
delete inherited.fetch;
|
|
72
|
+
}
|
|
73
|
+
if (provider) {
|
|
74
|
+
delete inherited.apiKey;
|
|
75
|
+
delete inherited.adminAPIKey;
|
|
76
|
+
delete inherited.credential;
|
|
77
|
+
delete inherited.workloadIdentity;
|
|
78
|
+
delete inherited.x509Transport;
|
|
79
|
+
delete inherited.baseURL;
|
|
80
|
+
}
|
|
81
|
+
return provider;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Reconciles one client's credential and provider ownership before cloning its options. */
|
|
85
|
+
export function prepareX509ClientClone(
|
|
86
|
+
inherited: ClientOptions,
|
|
87
|
+
overrides: Partial<ClientOptions>,
|
|
88
|
+
credential: X509Credential | undefined,
|
|
89
|
+
currentlyX509: boolean,
|
|
90
|
+
): { credential: X509Credential | undefined; provider: ClientOptions['provider'] } {
|
|
91
|
+
const nextIdentity = hasOwn(overrides, 'workloadIdentity')
|
|
92
|
+
? overrides.workloadIdentity
|
|
93
|
+
: inherited.workloadIdentity;
|
|
94
|
+
const dropping =
|
|
95
|
+
credential !== undefined &&
|
|
96
|
+
((overridesOrdinaryAuthentication(overrides) && overrides.workloadIdentity === undefined) ||
|
|
97
|
+
overrides.provider !== undefined);
|
|
98
|
+
if (credential !== undefined && hasOwn(overrides, 'workloadIdentity')) {
|
|
99
|
+
delete inherited.x509Transport;
|
|
100
|
+
}
|
|
101
|
+
const inheritedCredential =
|
|
102
|
+
credential !== undefined &&
|
|
103
|
+
!dropping &&
|
|
104
|
+
overrides.credential === undefined &&
|
|
105
|
+
!hasOwn(overrides, 'workloadIdentity') &&
|
|
106
|
+
!hasOwn(overrides, 'x509Transport')
|
|
107
|
+
? credential
|
|
108
|
+
: undefined;
|
|
109
|
+
const nextCredential = overrides.credential === undefined ? inheritedCredential : overrides.credential;
|
|
110
|
+
const nextX509 = nextCredential !== undefined || (!dropping && isX509WorkloadIdentity(nextIdentity));
|
|
111
|
+
|
|
112
|
+
if (currentlyX509 !== nextX509) {
|
|
113
|
+
delete inherited.fetch;
|
|
114
|
+
delete inherited.baseURL;
|
|
115
|
+
delete inherited.organization;
|
|
116
|
+
delete inherited.project;
|
|
117
|
+
delete inherited.defaultHeaders;
|
|
118
|
+
delete inherited.defaultQuery;
|
|
119
|
+
delete inherited.fetchOptions;
|
|
120
|
+
if (nextX509) {
|
|
121
|
+
inherited.apiKey = null;
|
|
122
|
+
} else {
|
|
123
|
+
delete inherited.x509Transport;
|
|
124
|
+
if (dropping) {
|
|
125
|
+
delete inherited.workloadIdentity;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (nextCredential !== undefined) {
|
|
131
|
+
delete inherited.apiKey;
|
|
132
|
+
delete inherited.adminAPIKey;
|
|
133
|
+
delete inherited.workloadIdentity;
|
|
134
|
+
delete inherited.x509Transport;
|
|
135
|
+
inherited.credential = nextCredential;
|
|
136
|
+
if (overrides.credential !== undefined) {
|
|
137
|
+
delete inherited.organization;
|
|
138
|
+
delete inherited.project;
|
|
139
|
+
delete inherited.defaultHeaders;
|
|
140
|
+
delete inherited.defaultQuery;
|
|
141
|
+
delete inherited.fetchOptions;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { credential: nextCredential, provider: prepareProviderClone(inherited, overrides) };
|
|
146
|
+
}
|
|
@@ -15,7 +15,13 @@ export interface X509TransportOptions {
|
|
|
15
15
|
/** X.509 transport currently supports genuine Node.js runtimes only. */
|
|
16
16
|
runtime: 'node';
|
|
17
17
|
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Caller-owned Undici Agent or ProxyAgent; the SDK never closes or inspects it.
|
|
20
|
+
*
|
|
21
|
+
* The application attests that its dispatcher, factories, TLS verification,
|
|
22
|
+
* certificate selection, and CONNECT proxy configuration are trustworthy.
|
|
23
|
+
* Use `fromX509` when the SDK should own and enforce transport configuration.
|
|
24
|
+
*/
|
|
19
25
|
dispatcher: Agent | ProxyAgent;
|
|
20
26
|
|
|
21
27
|
/** Attests that the dispatcher uses one static workload-certificate identity. */
|
|
@@ -150,10 +156,11 @@ function assertConnectProxySupport(): void {
|
|
|
150
156
|
* `certificateIdentity: 'static'` is an application attestation: the SDK does
|
|
151
157
|
* not inspect certificates, private dispatcher internals, callbacks, or TLS
|
|
152
158
|
* options and cannot cryptographically prove certificate selection. Configure
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
159
|
+
* trusted dispatcher factories, verified target and proxy TLS, one static
|
|
160
|
+
* certificate identity, and independently scoped CONNECT credentials.
|
|
161
|
+
* Prefer the SDK-owned `fromX509` credential when these guarantees should be
|
|
162
|
+
* enforced at construction. Rotation requires a fresh caller-owned dispatcher
|
|
163
|
+
* and capability; the application remains responsible for draining it.
|
|
157
164
|
*
|
|
158
165
|
* This Node-only preview entrypoint requires the optional `undici` peer at
|
|
159
166
|
* version 5.2.0 or later. CONNECT proxy modes require version 5.5.1 or
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OpenAIError } from '../../core/error';
|
|
2
2
|
import type { NullableHeaders } from '../headers';
|
|
3
|
+
import type { X509WorkloadIdentity } from '../../auth/types';
|
|
3
4
|
import type { ReadableStream } from '../shim-types';
|
|
4
5
|
import type { MergedRequestInit } from '../types';
|
|
5
6
|
import { findRegisteredX509Transport } from '#x509-transport-state';
|
|
@@ -49,6 +50,12 @@ export interface X509Transport {
|
|
|
49
50
|
readonly [x509TransportBrand]: true;
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
/** Immutable selectors and transport privately registered for an SDK-owned credential. */
|
|
54
|
+
export interface RegisteredX509Credential {
|
|
55
|
+
readonly identity: X509WorkloadIdentity;
|
|
56
|
+
readonly transport: X509Transport;
|
|
57
|
+
}
|
|
58
|
+
|
|
52
59
|
/** Validated short-lived token exchanged using a registered certificate identity. */
|
|
53
60
|
export interface X509ExchangedToken {
|
|
54
61
|
/** Header-safe, in-memory OpenAI bearer credential. */
|
|
@@ -63,6 +70,8 @@ export interface X509RequestScope {
|
|
|
63
70
|
wallStartedAt: number;
|
|
64
71
|
monotonicStartedAt: number;
|
|
65
72
|
deadlineArmed?: boolean;
|
|
73
|
+
preparationStartedAt?: number;
|
|
74
|
+
preparationWallStartedAt?: number;
|
|
66
75
|
request?: { signal: AbortSignal | null | undefined; timeout: number; fetchOptions: MergedRequestInit };
|
|
67
76
|
phase?: 'planning' | 'authorizing';
|
|
68
77
|
effectiveSignal?: AbortSignal;
|
|
@@ -4,6 +4,7 @@ const transientX509ConnectionErrors = new WeakSet();
|
|
|
4
4
|
const retryableX509IssuerErrors = new WeakSet();
|
|
5
5
|
const approvedX509Clients = new WeakSet();
|
|
6
6
|
const approvedX509OAuthErrors = new WeakMap();
|
|
7
|
+
const approvedX509Credentials = new WeakMap();
|
|
7
8
|
|
|
8
9
|
/** Looks up an opaque capability without exposing the registry itself. */
|
|
9
10
|
export const findRegisteredX509Transport = WeakMap.prototype.get.bind(registeredX509Transports);
|
|
@@ -34,3 +35,9 @@ export const rememberX509OAuthError = WeakMap.prototype.set.bind(approvedX509OAu
|
|
|
34
35
|
|
|
35
36
|
/** Retrieves trusted metadata when public OAuth errors cross module formats. */
|
|
36
37
|
export const findX509OAuthError = WeakMap.prototype.get.bind(approvedX509OAuthErrors);
|
|
38
|
+
|
|
39
|
+
/** Privately binds SDK-owned credentials without importing Node or optional transport peers. */
|
|
40
|
+
export const rememberX509Credential = WeakMap.prototype.set.bind(approvedX509Credentials);
|
|
41
|
+
|
|
42
|
+
/** Resolves only credentials registered by the optional Node authentication helper. */
|
|
43
|
+
export const findX509Credential = WeakMap.prototype.get.bind(approvedX509Credentials);
|
|
@@ -4,6 +4,7 @@ const transientX509ConnectionErrors = new WeakSet();
|
|
|
4
4
|
const retryableX509IssuerErrors = new WeakSet();
|
|
5
5
|
const approvedX509Clients = new WeakSet();
|
|
6
6
|
const approvedX509OAuthErrors = new WeakMap();
|
|
7
|
+
const approvedX509Credentials = new WeakMap();
|
|
7
8
|
|
|
8
9
|
/** Looks up an opaque capability without exposing the registry itself. */
|
|
9
10
|
export const findRegisteredX509Transport = WeakMap.prototype.get.bind(registeredX509Transports);
|
|
@@ -34,3 +35,9 @@ export const rememberX509OAuthError = WeakMap.prototype.set.bind(approvedX509OAu
|
|
|
34
35
|
|
|
35
36
|
/** Retrieves trusted OAuth metadata for public cross-module error normalization. */
|
|
36
37
|
export const findX509OAuthError = WeakMap.prototype.get.bind(approvedX509OAuthErrors);
|
|
38
|
+
|
|
39
|
+
/** Privately binds SDK-owned credentials to their immutable identity and approved transport. */
|
|
40
|
+
export const rememberX509Credential = WeakMap.prototype.set.bind(approvedX509Credentials);
|
|
41
|
+
|
|
42
|
+
/** Resolves only first-class credentials created by the optional Node transport helper. */
|
|
43
|
+
export const findX509Credential = WeakMap.prototype.get.bind(approvedX509Credentials);
|
|
@@ -6,7 +6,9 @@ import type { HeadersLike, NullableHeaders } from '../headers';
|
|
|
6
6
|
import type { FinalRequestOptions } from '../request-options';
|
|
7
7
|
import { CancelReadableStream } from '../shims';
|
|
8
8
|
import type { MergedRequestInit } from '../types';
|
|
9
|
+
import { isSensitiveHeader } from '../utils/log';
|
|
9
10
|
import { hasOwn } from '../utils/values';
|
|
11
|
+
import { assertX509APIOrigin } from './x509-api-origin';
|
|
10
12
|
import { resolveX509Transport } from './x509-transport-registry';
|
|
11
13
|
import {
|
|
12
14
|
isApprovedX509Client,
|
|
@@ -21,10 +23,6 @@ import type {
|
|
|
21
23
|
X509Transport,
|
|
22
24
|
} from './x509-transport-registry';
|
|
23
25
|
|
|
24
|
-
/** Sole API authority approved for OpenAI X.509 workload-identity federation. */
|
|
25
|
-
export const X509_API_BASE_URL = 'https://mtls.api.openai.com/v1';
|
|
26
|
-
|
|
27
|
-
const X509_API_ORIGIN = 'https://mtls.api.openai.com';
|
|
28
26
|
const FORBIDDEN_TRANSPORT_OPTIONS = ['dispatcher', 'agent', 'client', 'tls', 'proxy'];
|
|
29
27
|
const headerValue = (headers: Headers, name: string): string | null =>
|
|
30
28
|
Headers.prototype.get.call(headers, name);
|
|
@@ -39,12 +37,7 @@ const userAbortError = (signal: AbortSignal): APIUserAbortError => {
|
|
|
39
37
|
function assertSafeHeaders(headers: Headers): void {
|
|
40
38
|
for (const name of Headers.prototype.keys.call(headers)) {
|
|
41
39
|
const canonical = name.toLowerCase().split('_').join('-');
|
|
42
|
-
if (
|
|
43
|
-
canonical === 'api-key' ||
|
|
44
|
-
canonical === 'x-api-key' ||
|
|
45
|
-
canonical === 'proxy-authorization' ||
|
|
46
|
-
canonical === 'host'
|
|
47
|
-
) {
|
|
40
|
+
if ((canonical !== 'authorization' && isSensitiveHeader(canonical)) || canonical === 'host') {
|
|
48
41
|
throw new OpenAIError('X.509 workload identity cannot send conflicting authentication credentials.');
|
|
49
42
|
}
|
|
50
43
|
}
|
|
@@ -180,21 +173,6 @@ export function assertX509WebSocketSupported(client: unknown): void {
|
|
|
180
173
|
}
|
|
181
174
|
}
|
|
182
175
|
|
|
183
|
-
/** Rejects every destination outside the sole enrolled, global X.509 API authority. */
|
|
184
|
-
export function assertX509APIOrigin(value: string | URL): URL {
|
|
185
|
-
let target: URL;
|
|
186
|
-
try {
|
|
187
|
-
target = new URL(value);
|
|
188
|
-
} catch {
|
|
189
|
-
throw new OpenAIError('X.509 workload identity requires the approved global mTLS API origin.');
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (target.origin !== X509_API_ORIGIN || target.username || target.password) {
|
|
193
|
-
throw new OpenAIError('X.509 workload identity requires the approved global mTLS API origin.');
|
|
194
|
-
}
|
|
195
|
-
return target;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
176
|
/** Prevents caller options from replacing the immutable transport selected at construction. */
|
|
199
177
|
export function assertX509FetchOptions(options: MergedRequestInit | RequestInit | undefined): void {
|
|
200
178
|
if (!options) {
|
|
@@ -235,6 +213,7 @@ export class X509WorkloadIdentityAuth {
|
|
|
235
213
|
readonly #identityProviderId: string;
|
|
236
214
|
readonly #serviceAccountId: string;
|
|
237
215
|
readonly #configuredRefreshBufferMs: number | undefined;
|
|
216
|
+
readonly #configuredRefreshBufferSeconds: number | undefined;
|
|
238
217
|
readonly #organization: string | null;
|
|
239
218
|
readonly #project: string | null;
|
|
240
219
|
readonly #transport: RegisteredX509Transport;
|
|
@@ -254,15 +233,32 @@ export class X509WorkloadIdentityAuth {
|
|
|
254
233
|
this.#identityProviderId = identity.identityProviderId;
|
|
255
234
|
this.#serviceAccountId = identity.serviceAccountId;
|
|
256
235
|
this.#configuredRefreshBufferMs = identity.refreshBufferMs;
|
|
236
|
+
this.#configuredRefreshBufferSeconds = identity.refreshBufferSeconds;
|
|
257
237
|
this.#organization = organization;
|
|
258
238
|
this.#project = project;
|
|
239
|
+
if (this.#configuredRefreshBufferMs !== undefined && this.#configuredRefreshBufferSeconds !== undefined) {
|
|
240
|
+
throw new OpenAIError(
|
|
241
|
+
'X.509 workload identity cannot combine refreshBufferSeconds and refreshBufferMs.',
|
|
242
|
+
);
|
|
243
|
+
}
|
|
259
244
|
if (
|
|
260
245
|
this.#configuredRefreshBufferMs !== undefined &&
|
|
261
246
|
(!Number.isSafeInteger(this.#configuredRefreshBufferMs) || this.#configuredRefreshBufferMs < 0)
|
|
262
247
|
) {
|
|
263
248
|
throw new OpenAIError('X.509 workload identity requires a nonnegative integer refreshBufferMs.');
|
|
264
249
|
}
|
|
265
|
-
|
|
250
|
+
if (
|
|
251
|
+
this.#configuredRefreshBufferSeconds !== undefined &&
|
|
252
|
+
(!Number.isSafeInteger(this.#configuredRefreshBufferSeconds) ||
|
|
253
|
+
this.#configuredRefreshBufferSeconds < 0 ||
|
|
254
|
+
!Number.isSafeInteger(this.#configuredRefreshBufferSeconds * 1000))
|
|
255
|
+
) {
|
|
256
|
+
throw new OpenAIError('X.509 workload identity requires a nonnegative integer refreshBufferSeconds.');
|
|
257
|
+
}
|
|
258
|
+
this.#refreshBufferMs =
|
|
259
|
+
this.#configuredRefreshBufferSeconds === undefined
|
|
260
|
+
? (this.#configuredRefreshBufferMs ?? DEFAULT_REFRESH_BUFFER_MS)
|
|
261
|
+
: this.#configuredRefreshBufferSeconds * 1000;
|
|
266
262
|
}
|
|
267
263
|
|
|
268
264
|
/** Reconstructs the immutable selectors captured before caller-owned identity mutation. */
|
|
@@ -274,6 +270,9 @@ export class X509WorkloadIdentityAuth {
|
|
|
274
270
|
...(this.#configuredRefreshBufferMs === undefined
|
|
275
271
|
? {}
|
|
276
272
|
: { refreshBufferMs: this.#configuredRefreshBufferMs }),
|
|
273
|
+
...(this.#configuredRefreshBufferSeconds === undefined
|
|
274
|
+
? {}
|
|
275
|
+
: { refreshBufferSeconds: this.#configuredRefreshBufferSeconds }),
|
|
277
276
|
};
|
|
278
277
|
}
|
|
279
278
|
|
|
@@ -365,6 +364,15 @@ export class X509WorkloadIdentityAuth {
|
|
|
365
364
|
return request;
|
|
366
365
|
}
|
|
367
366
|
|
|
367
|
+
/** Suspends an already-running network budget during retry-local asynchronous preparation. */
|
|
368
|
+
beginRequestPreparation(): void {
|
|
369
|
+
const scope = this.#scope();
|
|
370
|
+
if (scope.deadlineArmed && scope.preparationStartedAt === undefined) {
|
|
371
|
+
scope.preparationStartedAt = performance.now();
|
|
372
|
+
scope.preparationWallStartedAt = Date.now();
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
368
376
|
/** Begins local request construction without charging protected hook latency to the network. */
|
|
369
377
|
beginRequestPlanning(): void {
|
|
370
378
|
this.#scope().phase = 'planning';
|
|
@@ -377,6 +385,11 @@ export class X509WorkloadIdentityAuth {
|
|
|
377
385
|
scope.wallStartedAt = Date.now();
|
|
378
386
|
scope.monotonicStartedAt = performance.now();
|
|
379
387
|
scope.deadlineArmed = true;
|
|
388
|
+
} else if (scope.preparationStartedAt !== undefined) {
|
|
389
|
+
scope.monotonicStartedAt += performance.now() - scope.preparationStartedAt;
|
|
390
|
+
scope.wallStartedAt += Date.now() - (scope.preparationWallStartedAt ?? Date.now());
|
|
391
|
+
delete scope.preparationStartedAt;
|
|
392
|
+
delete scope.preparationWallStartedAt;
|
|
380
393
|
}
|
|
381
394
|
}
|
|
382
395
|
|
|
@@ -550,6 +563,8 @@ export class X509WorkloadIdentityAuth {
|
|
|
550
563
|
delete scope.request;
|
|
551
564
|
delete scope.phase;
|
|
552
565
|
delete scope.deadlineArmed;
|
|
566
|
+
delete scope.preparationStartedAt;
|
|
567
|
+
delete scope.preparationWallStartedAt;
|
|
553
568
|
delete scope.effectiveSignal;
|
|
554
569
|
delete scope.materializedBody;
|
|
555
570
|
delete scope.apiURL;
|
|
@@ -820,13 +835,7 @@ export class X509WorkloadIdentityAuth {
|
|
|
820
835
|
'X.509 workload identity cannot override its enrolled organization or project.',
|
|
821
836
|
);
|
|
822
837
|
}
|
|
823
|
-
if (
|
|
824
|
-
canonical === 'authorization' ||
|
|
825
|
-
canonical === 'api-key' ||
|
|
826
|
-
canonical === 'x-api-key' ||
|
|
827
|
-
canonical === 'proxy-authorization' ||
|
|
828
|
-
canonical === 'host'
|
|
829
|
-
) {
|
|
838
|
+
if (isSensitiveHeader(canonical) || canonical === 'host') {
|
|
830
839
|
throw new OpenAIError(
|
|
831
840
|
'X.509 workload identity cannot use caller-supplied authentication credentials.',
|
|
832
841
|
);
|
package/src/internal/uploads.ts
CHANGED
|
@@ -348,7 +348,8 @@ const hasStreamingUploadableValue = (value: unknown): boolean => {
|
|
|
348
348
|
return value.some(hasStreamingUploadableValue);
|
|
349
349
|
}
|
|
350
350
|
if (value && typeof value === 'object' && !isBlob(value) && !(value instanceof Response)) {
|
|
351
|
-
|
|
351
|
+
// Own properties only, matching what form encoding serializes; inherited values are never encoded.
|
|
352
|
+
for (const k of Object.keys(value)) {
|
|
352
353
|
if (hasStreamingUploadableValue((value as Record<string, unknown>)[k])) {
|
|
353
354
|
return true;
|
|
354
355
|
}
|
|
@@ -365,7 +366,8 @@ const hasUploadableValue = (value: unknown): boolean => {
|
|
|
365
366
|
return value.some(hasUploadableValue);
|
|
366
367
|
}
|
|
367
368
|
if (value && typeof value === 'object') {
|
|
368
|
-
|
|
369
|
+
// Own properties only, matching what form encoding serializes; inherited values are never encoded.
|
|
370
|
+
for (const k of Object.keys(value)) {
|
|
369
371
|
if (hasUploadableValue((value as any)[k])) {
|
|
370
372
|
return true;
|
|
371
373
|
}
|
|
@@ -82,6 +82,62 @@ export function loggerFor(client: OpenAI): Logger {
|
|
|
82
82
|
return levelLogger;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
const sensitiveQueryNames = new Set([
|
|
86
|
+
'apikey',
|
|
87
|
+
'accesstoken',
|
|
88
|
+
'refreshtoken',
|
|
89
|
+
'sessiontoken',
|
|
90
|
+
'sessionid',
|
|
91
|
+
'idtoken',
|
|
92
|
+
'authtoken',
|
|
93
|
+
'authorization',
|
|
94
|
+
'token',
|
|
95
|
+
'password',
|
|
96
|
+
'clientsecret',
|
|
97
|
+
'xamzsecuritytoken',
|
|
98
|
+
'xamzsignature',
|
|
99
|
+
'xamzcredential',
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
/** Recognizes credential-bearing query names across ordinary and provider authentication. */
|
|
103
|
+
export function isSensitiveQueryParameter(name: string): boolean {
|
|
104
|
+
const normalized = name.toLowerCase().replace(/[-_]/gu, '');
|
|
105
|
+
return sensitiveQueryNames.has(normalized) || sensitiveQueryNames.has(normalized.replace(/^x/u, ''));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const sensitiveHeaderNames = new Set([
|
|
109
|
+
'authorization',
|
|
110
|
+
'proxy-authorization',
|
|
111
|
+
'api-key',
|
|
112
|
+
'x-api-key',
|
|
113
|
+
'x-amz-security-token',
|
|
114
|
+
'cookie',
|
|
115
|
+
'set-cookie',
|
|
116
|
+
'x-session-token',
|
|
117
|
+
'x-session-id',
|
|
118
|
+
'x-auth-token',
|
|
119
|
+
'x-id-token',
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
/** Recognizes credential-bearing request headers across provider and workload authentication. */
|
|
123
|
+
export function isSensitiveHeader(name: string): boolean {
|
|
124
|
+
return sensitiveHeaderNames.has(name.toLowerCase().replace(/_/gu, '-')) || isSensitiveQueryParameter(name);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Removes credential-valued query parameters before a request URL reaches any logger. */
|
|
128
|
+
export function redactURL(value: string): string {
|
|
129
|
+
const url = new URL(value);
|
|
130
|
+
url.username = '';
|
|
131
|
+
url.password = '';
|
|
132
|
+
url.hash = '';
|
|
133
|
+
for (const name of url.searchParams.keys()) {
|
|
134
|
+
if (isSensitiveQueryParameter(name)) {
|
|
135
|
+
url.searchParams.set(name, '***');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return url.href;
|
|
139
|
+
}
|
|
140
|
+
|
|
85
141
|
export const formatRequestDetails = (details: {
|
|
86
142
|
options?: RequestOptions | undefined;
|
|
87
143
|
headers?: Headers | Record<string, string> | undefined;
|
|
@@ -97,21 +153,30 @@ export const formatRequestDetails = (details: {
|
|
|
97
153
|
if (details.options) {
|
|
98
154
|
details.options = { ...details.options };
|
|
99
155
|
delete details.options['headers']; // redundant + leaks internals
|
|
156
|
+
if (details.options.path) {
|
|
157
|
+
const path = details.options.path;
|
|
158
|
+
const redacted = new URL(redactURL(new URL(path, 'https://redacted.invalid').href));
|
|
159
|
+
details.options.path =
|
|
160
|
+
redacted.origin === 'https://redacted.invalid'
|
|
161
|
+
? `${path.startsWith('/') ? '/' : ''}${redacted.pathname.slice(1)}${redacted.search}`
|
|
162
|
+
: redacted.href;
|
|
163
|
+
}
|
|
164
|
+
if (details.options.query) {
|
|
165
|
+
details.options.query = Object.fromEntries(
|
|
166
|
+
Object.entries(details.options.query).map(([name, value]) => [
|
|
167
|
+
name,
|
|
168
|
+
isSensitiveQueryParameter(name) ? '***' : value,
|
|
169
|
+
]),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (details.url) {
|
|
174
|
+
details.url = redactURL(details.url);
|
|
100
175
|
}
|
|
101
176
|
if (details.headers) {
|
|
102
177
|
details.headers = Object.fromEntries(
|
|
103
178
|
(details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(
|
|
104
|
-
([name, value]) => [
|
|
105
|
-
name,
|
|
106
|
-
name.toLowerCase() === 'authorization' ||
|
|
107
|
-
name.toLowerCase() === 'api-key' ||
|
|
108
|
-
name.toLowerCase() === 'x-api-key' ||
|
|
109
|
-
name.toLowerCase() === 'x-amz-security-token' ||
|
|
110
|
-
name.toLowerCase() === 'cookie' ||
|
|
111
|
-
name.toLowerCase() === 'set-cookie'
|
|
112
|
-
? '***'
|
|
113
|
-
: value,
|
|
114
|
-
],
|
|
179
|
+
([name, value]) => [name, isSensitiveHeader(name) ? '***' : value],
|
|
115
180
|
),
|
|
116
181
|
);
|
|
117
182
|
}
|
package/src/lib/EventEmitter.ts
CHANGED
|
@@ -184,11 +184,20 @@ export class EventEmitter<EventTypes extends Record<string, (...args: any) => an
|
|
|
184
184
|
}
|
|
185
185
|
return !listener.once && !listener.removed;
|
|
186
186
|
}) as any;
|
|
187
|
+
let listenerThrew = false;
|
|
188
|
+
let firstListenerError: unknown;
|
|
187
189
|
this.#listenerDispatchDepth += 1;
|
|
188
190
|
try {
|
|
189
191
|
for (const registration of listeners as any) {
|
|
190
192
|
if (!registration.removed) {
|
|
191
|
-
|
|
193
|
+
try {
|
|
194
|
+
registration.listener(...(args as any));
|
|
195
|
+
} catch (error) {
|
|
196
|
+
if (!listenerThrew) {
|
|
197
|
+
listenerThrew = true;
|
|
198
|
+
firstListenerError = error;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
192
201
|
}
|
|
193
202
|
}
|
|
194
203
|
} finally {
|
|
@@ -197,6 +206,9 @@ export class EventEmitter<EventTypes extends Record<string, (...args: any) => an
|
|
|
197
206
|
this.#cleanupEmittedListeners();
|
|
198
207
|
}
|
|
199
208
|
}
|
|
209
|
+
if (listenerThrew) {
|
|
210
|
+
throw firstListenerError;
|
|
211
|
+
}
|
|
200
212
|
}
|
|
201
213
|
}
|
|
202
214
|
|
package/src/realtime/ws.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { assertBedrockWebSocketOrigin } from '../internal/bedrock';
|
|
|
3
3
|
import { protectWebSocketOptionsFromCredentialRedirects } from '../internal/ws';
|
|
4
4
|
import type { AzureOpenAI } from '../index';
|
|
5
5
|
import { OpenAI } from '../index';
|
|
6
|
+
import { VERSION } from '../version';
|
|
6
7
|
import type { RealtimeClientEvent } from '../resources/realtime/realtime';
|
|
7
8
|
import {
|
|
8
9
|
OpenAIRealtimeEmitter,
|
|
@@ -62,6 +63,7 @@ export class OpenAIRealtimeWS extends OpenAIRealtimeEmitter {
|
|
|
62
63
|
this.url = buildRealtimeURL(client, props);
|
|
63
64
|
assertBedrockWebSocketOrigin(client, this.url);
|
|
64
65
|
const headers = {
|
|
66
|
+
'User-Agent': `${client.constructor.name}/JS ${VERSION}`,
|
|
65
67
|
...props.options?.headers,
|
|
66
68
|
...(isAzure(client) && !props.__resolvedApiKey ? {} : { Authorization: `Bearer ${client.apiKey}` }),
|
|
67
69
|
};
|
|
@@ -130,6 +130,8 @@ export interface AuditLogListResponse {
|
|
|
130
130
|
| 'tenant.admin_api_key.updated'
|
|
131
131
|
| 'tenant.admin_api_key.deleted'
|
|
132
132
|
| 'tenant.project_api_key.created'
|
|
133
|
+
| 'tenant.trusted_access.business_verification.started'
|
|
134
|
+
| 'tenant.trusted_access.application.submitted'
|
|
133
135
|
| 'tenant.chatgpt_access_token.revoked'
|
|
134
136
|
| 'tenant.migration.completed'
|
|
135
137
|
| 'tenant.sso.migrated'
|
|
@@ -1936,6 +1938,8 @@ export interface AuditLogListParams extends ConversationCursorPageParams {
|
|
|
1936
1938
|
| 'tenant.admin_api_key.updated'
|
|
1937
1939
|
| 'tenant.admin_api_key.deleted'
|
|
1938
1940
|
| 'tenant.project_api_key.created'
|
|
1941
|
+
| 'tenant.trusted_access.business_verification.started'
|
|
1942
|
+
| 'tenant.trusted_access.application.submitted'
|
|
1939
1943
|
| 'tenant.chatgpt_access_token.revoked'
|
|
1940
1944
|
| 'tenant.migration.completed'
|
|
1941
1945
|
| 'tenant.sso.migrated'
|
|
@@ -10525,6 +10525,11 @@ export interface BetaResponseUsage {
|
|
|
10525
10525
|
* The total number of tokens used.
|
|
10526
10526
|
*/
|
|
10527
10527
|
total_tokens: number;
|
|
10528
|
+
|
|
10529
|
+
/**
|
|
10530
|
+
* Compute units for the request. Currently null when available.
|
|
10531
|
+
*/
|
|
10532
|
+
compute_units?: number | null;
|
|
10528
10533
|
}
|
|
10529
10534
|
|
|
10530
10535
|
export namespace BetaResponseUsage {
|