@discomedia/utils 1.0.64 → 1.0.66
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/dist/index-frontend.cjs +198 -11
- package/dist/index-frontend.cjs.map +1 -1
- package/dist/index-frontend.mjs +198 -11
- package/dist/index-frontend.mjs.map +1 -1
- package/dist/index.cjs +244 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +244 -63
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +6 -6
- package/dist/test.js +290 -67
- package/dist/test.js.map +1 -1
- package/dist/types/alpaca-market-data-api.d.ts +10 -0
- package/dist/types/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types/llm-config.d.ts.map +1 -1
- package/dist/types/llm-images.d.ts.map +1 -1
- package/dist/types/llm-openai.d.ts.map +1 -1
- package/dist/types/types/llm-types.d.ts +2 -2
- package/dist/types/types/llm-types.d.ts.map +1 -1
- package/dist/types-frontend/alpaca-market-data-api.d.ts +10 -0
- package/dist/types-frontend/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types-frontend/llm-config.d.ts.map +1 -1
- package/dist/types-frontend/llm-images.d.ts.map +1 -1
- package/dist/types-frontend/llm-openai.d.ts.map +1 -1
- package/dist/types-frontend/types/llm-types.d.ts +2 -2
- package/dist/types-frontend/types/llm-types.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index-frontend.mjs
CHANGED
|
@@ -5,6 +5,7 @@ function isOpenRouterModel(model) {
|
|
|
5
5
|
const openRouterModels = [
|
|
6
6
|
'openai/gpt-5',
|
|
7
7
|
'openai/gpt-5-mini',
|
|
8
|
+
'openai/gpt-5.4-mini',
|
|
8
9
|
'openai/gpt-5-nano',
|
|
9
10
|
'openai/gpt-5.1',
|
|
10
11
|
'openai/gpt-5.4',
|
|
@@ -208,6 +209,37 @@ class InvalidWebhookSignatureError extends Error {
|
|
|
208
209
|
super(message);
|
|
209
210
|
}
|
|
210
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Error thrown by the API server during OAuth token exchange.
|
|
214
|
+
* Can have status codes 400, 401, or 403.
|
|
215
|
+
* Other status codes from OAuth endpoints are raised as normal APIError types.
|
|
216
|
+
*/
|
|
217
|
+
class OAuthError extends APIError {
|
|
218
|
+
constructor(status, error, headers) {
|
|
219
|
+
let finalMessage = 'OAuth2 authentication error';
|
|
220
|
+
let error_code = undefined;
|
|
221
|
+
if (error && typeof error === 'object') {
|
|
222
|
+
const errorData = error;
|
|
223
|
+
error_code = errorData['error'];
|
|
224
|
+
const description = errorData['error_description'];
|
|
225
|
+
if (description && typeof description === 'string') {
|
|
226
|
+
finalMessage = description;
|
|
227
|
+
}
|
|
228
|
+
else if (error_code) {
|
|
229
|
+
finalMessage = error_code;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
super(status, error, finalMessage, headers);
|
|
233
|
+
this.error_code = error_code;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
class SubjectTokenProviderError extends OpenAIError {
|
|
237
|
+
constructor(message, provider, cause) {
|
|
238
|
+
super(message);
|
|
239
|
+
this.provider = provider;
|
|
240
|
+
this.cause = cause;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
211
243
|
|
|
212
244
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
213
245
|
// https://url.spec.whatwg.org/#url-scheme-string
|
|
@@ -260,7 +292,7 @@ const safeJSON = (text) => {
|
|
|
260
292
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
261
293
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
262
294
|
|
|
263
|
-
const VERSION = '6.
|
|
295
|
+
const VERSION = '6.34.0'; // x-release-please-version
|
|
264
296
|
|
|
265
297
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
266
298
|
const isRunningInBrowser = () => {
|
|
@@ -1641,6 +1673,91 @@ class ConversationCursorPage extends AbstractPage {
|
|
|
1641
1673
|
}
|
|
1642
1674
|
}
|
|
1643
1675
|
|
|
1676
|
+
const SUBJECT_TOKEN_TYPES = {
|
|
1677
|
+
jwt: 'urn:ietf:params:oauth:token-type:jwt',
|
|
1678
|
+
id: 'urn:ietf:params:oauth:token-type:id_token',
|
|
1679
|
+
};
|
|
1680
|
+
const TOKEN_EXCHANGE_GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:token-exchange';
|
|
1681
|
+
class WorkloadIdentityAuth {
|
|
1682
|
+
constructor(config, fetch) {
|
|
1683
|
+
this.cachedToken = null;
|
|
1684
|
+
this.refreshPromise = null;
|
|
1685
|
+
this.tokenExchangeUrl = 'https://auth.openai.com/oauth/token';
|
|
1686
|
+
this.config = config;
|
|
1687
|
+
this.fetch = fetch ?? getDefaultFetch();
|
|
1688
|
+
}
|
|
1689
|
+
async getToken() {
|
|
1690
|
+
if (!this.cachedToken || this.isTokenExpired(this.cachedToken)) {
|
|
1691
|
+
if (this.refreshPromise) {
|
|
1692
|
+
return await this.refreshPromise;
|
|
1693
|
+
}
|
|
1694
|
+
this.refreshPromise = this.refreshToken();
|
|
1695
|
+
try {
|
|
1696
|
+
const token = await this.refreshPromise;
|
|
1697
|
+
return token;
|
|
1698
|
+
}
|
|
1699
|
+
finally {
|
|
1700
|
+
this.refreshPromise = null;
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
if (this.needsRefresh(this.cachedToken) && !this.refreshPromise) {
|
|
1704
|
+
this.refreshPromise = this.refreshToken().finally(() => {
|
|
1705
|
+
this.refreshPromise = null;
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1708
|
+
return this.cachedToken.token;
|
|
1709
|
+
}
|
|
1710
|
+
async refreshToken() {
|
|
1711
|
+
const subjectToken = await this.config.provider.getToken();
|
|
1712
|
+
const response = await this.fetch(this.tokenExchangeUrl, {
|
|
1713
|
+
method: 'POST',
|
|
1714
|
+
headers: {
|
|
1715
|
+
'Content-Type': 'application/json',
|
|
1716
|
+
},
|
|
1717
|
+
body: JSON.stringify({
|
|
1718
|
+
grant_type: TOKEN_EXCHANGE_GRANT_TYPE,
|
|
1719
|
+
client_id: this.config.clientId,
|
|
1720
|
+
subject_token: subjectToken,
|
|
1721
|
+
subject_token_type: SUBJECT_TOKEN_TYPES[this.config.provider.tokenType],
|
|
1722
|
+
identity_provider_id: this.config.identityProviderId,
|
|
1723
|
+
service_account_id: this.config.serviceAccountId,
|
|
1724
|
+
}),
|
|
1725
|
+
});
|
|
1726
|
+
if (!response.ok) {
|
|
1727
|
+
const errorText = await response.text();
|
|
1728
|
+
let body = undefined;
|
|
1729
|
+
try {
|
|
1730
|
+
body = JSON.parse(errorText);
|
|
1731
|
+
}
|
|
1732
|
+
catch { }
|
|
1733
|
+
if (response.status === 400 || response.status === 401 || response.status === 403) {
|
|
1734
|
+
throw new OAuthError(response.status, body, response.headers);
|
|
1735
|
+
}
|
|
1736
|
+
throw APIError.generate(response.status, body, `Token exchange failed with status ${response.status}`, response.headers);
|
|
1737
|
+
}
|
|
1738
|
+
const tokenResponse = (await response.json());
|
|
1739
|
+
const expiresIn = tokenResponse.expires_in || 3600;
|
|
1740
|
+
const expiresAt = Date.now() + expiresIn * 1000;
|
|
1741
|
+
this.cachedToken = {
|
|
1742
|
+
token: tokenResponse.access_token,
|
|
1743
|
+
expiresAt,
|
|
1744
|
+
};
|
|
1745
|
+
return tokenResponse.access_token;
|
|
1746
|
+
}
|
|
1747
|
+
isTokenExpired(cachedToken) {
|
|
1748
|
+
return Date.now() >= cachedToken.expiresAt;
|
|
1749
|
+
}
|
|
1750
|
+
needsRefresh(cachedToken) {
|
|
1751
|
+
const bufferSeconds = this.config.refreshBufferSeconds ?? 1200;
|
|
1752
|
+
const bufferMs = bufferSeconds * 1000;
|
|
1753
|
+
return Date.now() >= cachedToken.expiresAt - bufferMs;
|
|
1754
|
+
}
|
|
1755
|
+
invalidateToken() {
|
|
1756
|
+
this.cachedToken = null;
|
|
1757
|
+
this.refreshPromise = null;
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1644
1761
|
const checkFileSupport = () => {
|
|
1645
1762
|
if (typeof File === 'undefined') {
|
|
1646
1763
|
const { process } = globalThis;
|
|
@@ -6946,6 +7063,7 @@ _Webhooks_instances = new WeakSet(), _Webhooks_validateSecret = function _Webhoo
|
|
|
6946
7063
|
|
|
6947
7064
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6948
7065
|
var _OpenAI_instances, _a$1, _OpenAI_encoder, _OpenAI_baseURLOverridden;
|
|
7066
|
+
const WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER = 'workload-identity-auth';
|
|
6949
7067
|
/**
|
|
6950
7068
|
* API Client for interfacing with the OpenAI API.
|
|
6951
7069
|
*/
|
|
@@ -6966,7 +7084,7 @@ class OpenAI {
|
|
|
6966
7084
|
* @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
|
|
6967
7085
|
* @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers.
|
|
6968
7086
|
*/
|
|
6969
|
-
constructor({ baseURL = readEnv('OPENAI_BASE_URL'), apiKey = readEnv('OPENAI_API_KEY'), organization = readEnv('OPENAI_ORG_ID') ?? null, project = readEnv('OPENAI_PROJECT_ID') ?? null, webhookSecret = readEnv('OPENAI_WEBHOOK_SECRET') ?? null, ...opts } = {}) {
|
|
7087
|
+
constructor({ baseURL = readEnv('OPENAI_BASE_URL'), apiKey = readEnv('OPENAI_API_KEY'), organization = readEnv('OPENAI_ORG_ID') ?? null, project = readEnv('OPENAI_PROJECT_ID') ?? null, webhookSecret = readEnv('OPENAI_WEBHOOK_SECRET') ?? null, workloadIdentity, ...opts } = {}) {
|
|
6970
7088
|
_OpenAI_instances.add(this);
|
|
6971
7089
|
_OpenAI_encoder.set(this, void 0);
|
|
6972
7090
|
/**
|
|
@@ -7021,14 +7139,21 @@ class OpenAI {
|
|
|
7021
7139
|
this.containers = new Containers(this);
|
|
7022
7140
|
this.skills = new Skills(this);
|
|
7023
7141
|
this.videos = new Videos(this);
|
|
7024
|
-
if (
|
|
7025
|
-
|
|
7142
|
+
if (workloadIdentity) {
|
|
7143
|
+
if (apiKey && apiKey !== WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER) {
|
|
7144
|
+
throw new OpenAIError('The `apiKey` and `workloadIdentity` arguments are mutually exclusive; only one can be passed at a time.');
|
|
7145
|
+
}
|
|
7146
|
+
apiKey = WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER;
|
|
7147
|
+
}
|
|
7148
|
+
else if (apiKey === undefined) {
|
|
7149
|
+
throw new OpenAIError('Missing credentials. Please pass an `apiKey`, `workloadIdentity`, or set the `OPENAI_API_KEY` environment variable.');
|
|
7026
7150
|
}
|
|
7027
7151
|
const options = {
|
|
7028
7152
|
apiKey,
|
|
7029
7153
|
organization,
|
|
7030
7154
|
project,
|
|
7031
7155
|
webhookSecret,
|
|
7156
|
+
workloadIdentity,
|
|
7032
7157
|
...opts,
|
|
7033
7158
|
baseURL: baseURL || `https://api.openai.com/v1`,
|
|
7034
7159
|
};
|
|
@@ -7050,6 +7175,9 @@ class OpenAI {
|
|
|
7050
7175
|
this.fetch = options.fetch ?? getDefaultFetch();
|
|
7051
7176
|
__classPrivateFieldSet(this, _OpenAI_encoder, FallbackEncoder);
|
|
7052
7177
|
this._options = options;
|
|
7178
|
+
if (workloadIdentity) {
|
|
7179
|
+
this._workloadIdentityAuth = new WorkloadIdentityAuth(workloadIdentity, this.fetch);
|
|
7180
|
+
}
|
|
7053
7181
|
this.apiKey = typeof apiKey === 'string' ? apiKey : 'Missing Key';
|
|
7054
7182
|
this.organization = organization;
|
|
7055
7183
|
this.project = project;
|
|
@@ -7069,6 +7197,7 @@ class OpenAI {
|
|
|
7069
7197
|
fetch: this.fetch,
|
|
7070
7198
|
fetchOptions: this.fetchOptions,
|
|
7071
7199
|
apiKey: this.apiKey,
|
|
7200
|
+
workloadIdentity: this._options.workloadIdentity,
|
|
7072
7201
|
organization: this.organization,
|
|
7073
7202
|
project: this.project,
|
|
7074
7203
|
webhookSecret: this.webhookSecret,
|
|
@@ -7195,7 +7324,7 @@ class OpenAI {
|
|
|
7195
7324
|
throw new APIUserAbortError();
|
|
7196
7325
|
}
|
|
7197
7326
|
const controller = new AbortController();
|
|
7198
|
-
const response = await this.
|
|
7327
|
+
const response = await this.fetchWithAuth(url, req, timeout, controller).catch(castToError);
|
|
7199
7328
|
const headersTime = Date.now();
|
|
7200
7329
|
if (response instanceof globalThis.Error) {
|
|
7201
7330
|
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
@@ -7225,6 +7354,9 @@ class OpenAI {
|
|
|
7225
7354
|
durationMs: headersTime - startTime,
|
|
7226
7355
|
message: response.message,
|
|
7227
7356
|
}));
|
|
7357
|
+
if (response instanceof OAuthError || response instanceof SubjectTokenProviderError) {
|
|
7358
|
+
throw response;
|
|
7359
|
+
}
|
|
7228
7360
|
if (isTimeout) {
|
|
7229
7361
|
throw new APIConnectionTimeoutError();
|
|
7230
7362
|
}
|
|
@@ -7236,6 +7368,20 @@ class OpenAI {
|
|
|
7236
7368
|
.join('');
|
|
7237
7369
|
const responseInfo = `[${requestLogID}${retryLogStr}${specialHeaders}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
7238
7370
|
if (!response.ok) {
|
|
7371
|
+
if (response.status === 401 &&
|
|
7372
|
+
this._workloadIdentityAuth &&
|
|
7373
|
+
!options.__metadata?.['hasStreamingBody'] &&
|
|
7374
|
+
!options.__metadata?.['workloadIdentityTokenRefreshed']) {
|
|
7375
|
+
await CancelReadableStream(response.body);
|
|
7376
|
+
this._workloadIdentityAuth.invalidateToken();
|
|
7377
|
+
return this.makeRequest({
|
|
7378
|
+
...options,
|
|
7379
|
+
__metadata: {
|
|
7380
|
+
...options.__metadata,
|
|
7381
|
+
workloadIdentityTokenRefreshed: true,
|
|
7382
|
+
},
|
|
7383
|
+
}, retriesRemaining, retryOfRequestLogID ?? requestLogID);
|
|
7384
|
+
}
|
|
7239
7385
|
const shouldRetry = await this.shouldRetry(response);
|
|
7240
7386
|
if (retriesRemaining && shouldRetry) {
|
|
7241
7387
|
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
@@ -7286,6 +7432,18 @@ class OpenAI {
|
|
|
7286
7432
|
const request = this.makeRequest(options, null, undefined);
|
|
7287
7433
|
return new PagePromise(this, request, Page);
|
|
7288
7434
|
}
|
|
7435
|
+
async fetchWithAuth(url, init, timeout, controller) {
|
|
7436
|
+
if (this._workloadIdentityAuth) {
|
|
7437
|
+
const headers = init.headers;
|
|
7438
|
+
const authHeader = headers.get('Authorization');
|
|
7439
|
+
if (!authHeader || authHeader === `Bearer ${WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER}`) {
|
|
7440
|
+
const token = await this._workloadIdentityAuth.getToken();
|
|
7441
|
+
headers.set('Authorization', `Bearer ${token}`);
|
|
7442
|
+
}
|
|
7443
|
+
}
|
|
7444
|
+
const response = await this.fetchWithTimeout(url, init, timeout, controller);
|
|
7445
|
+
return response;
|
|
7446
|
+
}
|
|
7289
7447
|
async fetchWithTimeout(url, init, ms, controller) {
|
|
7290
7448
|
const { signal, method, ...options } = init || {};
|
|
7291
7449
|
const abort = this._makeAbort(controller);
|
|
@@ -7382,7 +7540,13 @@ class OpenAI {
|
|
|
7382
7540
|
if ('timeout' in options)
|
|
7383
7541
|
validatePositiveInteger('timeout', options.timeout);
|
|
7384
7542
|
options.timeout = options.timeout ?? this.timeout;
|
|
7385
|
-
const { bodyHeaders, body } = this.buildBody({ options });
|
|
7543
|
+
const { bodyHeaders, body, isStreamingBody } = this.buildBody({ options });
|
|
7544
|
+
if (isStreamingBody) {
|
|
7545
|
+
inputOptions.__metadata = {
|
|
7546
|
+
...inputOptions.__metadata,
|
|
7547
|
+
hasStreamingBody: true,
|
|
7548
|
+
};
|
|
7549
|
+
}
|
|
7386
7550
|
const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
|
|
7387
7551
|
const req = {
|
|
7388
7552
|
method,
|
|
@@ -7429,9 +7593,18 @@ class OpenAI {
|
|
|
7429
7593
|
}
|
|
7430
7594
|
buildBody({ options: { body, headers: rawHeaders } }) {
|
|
7431
7595
|
if (!body) {
|
|
7432
|
-
return { bodyHeaders: undefined, body: undefined };
|
|
7596
|
+
return { bodyHeaders: undefined, body: undefined, isStreamingBody: false };
|
|
7433
7597
|
}
|
|
7434
7598
|
const headers = buildHeaders([rawHeaders]);
|
|
7599
|
+
const isReadableStream = typeof globalThis.ReadableStream !== 'undefined' &&
|
|
7600
|
+
body instanceof globalThis.ReadableStream;
|
|
7601
|
+
const isRetryableBody = !isReadableStream &&
|
|
7602
|
+
(typeof body === 'string' ||
|
|
7603
|
+
body instanceof ArrayBuffer ||
|
|
7604
|
+
ArrayBuffer.isView(body) ||
|
|
7605
|
+
(typeof globalThis.Blob !== 'undefined' && body instanceof globalThis.Blob) ||
|
|
7606
|
+
body instanceof URLSearchParams ||
|
|
7607
|
+
body instanceof FormData);
|
|
7435
7608
|
if (
|
|
7436
7609
|
// Pass raw type verbatim
|
|
7437
7610
|
ArrayBuffer.isView(body) ||
|
|
@@ -7447,23 +7620,28 @@ class OpenAI {
|
|
|
7447
7620
|
// `URLSearchParams` -> `application/x-www-form-urlencoded`
|
|
7448
7621
|
body instanceof URLSearchParams ||
|
|
7449
7622
|
// Send chunked stream (each chunk has own `length`)
|
|
7450
|
-
|
|
7451
|
-
return { bodyHeaders: undefined, body: body };
|
|
7623
|
+
isReadableStream) {
|
|
7624
|
+
return { bodyHeaders: undefined, body: body, isStreamingBody: !isRetryableBody };
|
|
7452
7625
|
}
|
|
7453
7626
|
else if (typeof body === 'object' &&
|
|
7454
7627
|
(Symbol.asyncIterator in body ||
|
|
7455
7628
|
(Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
|
|
7456
|
-
return {
|
|
7629
|
+
return {
|
|
7630
|
+
bodyHeaders: undefined,
|
|
7631
|
+
body: ReadableStreamFrom(body),
|
|
7632
|
+
isStreamingBody: true,
|
|
7633
|
+
};
|
|
7457
7634
|
}
|
|
7458
7635
|
else if (typeof body === 'object' &&
|
|
7459
7636
|
headers.values.get('content-type') === 'application/x-www-form-urlencoded') {
|
|
7460
7637
|
return {
|
|
7461
7638
|
bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
7462
7639
|
body: this.stringifyQuery(body),
|
|
7640
|
+
isStreamingBody: false,
|
|
7463
7641
|
};
|
|
7464
7642
|
}
|
|
7465
7643
|
else {
|
|
7466
|
-
return __classPrivateFieldGet(this, _OpenAI_encoder, "f").call(this, { body, headers });
|
|
7644
|
+
return { ...__classPrivateFieldGet(this, _OpenAI_encoder, "f").call(this, { body, headers }), isStreamingBody: false };
|
|
7467
7645
|
}
|
|
7468
7646
|
}
|
|
7469
7647
|
}
|
|
@@ -10346,6 +10524,11 @@ const openAiModelCosts = {
|
|
|
10346
10524
|
cacheHitCost: 0.025 / 1_000_000,
|
|
10347
10525
|
outputCost: 2 / 1_000_000,
|
|
10348
10526
|
},
|
|
10527
|
+
'gpt-5.4-mini': {
|
|
10528
|
+
inputCost: 0.25 / 1_000_000,
|
|
10529
|
+
cacheHitCost: 0.025 / 1_000_000,
|
|
10530
|
+
outputCost: 2 / 1_000_000,
|
|
10531
|
+
},
|
|
10349
10532
|
'gpt-5-nano': {
|
|
10350
10533
|
inputCost: 0.05 / 1_000_000,
|
|
10351
10534
|
cacheHitCost: 0.005 / 1_000_000,
|
|
@@ -10856,6 +11039,7 @@ const isSupportedModel = (model) => {
|
|
|
10856
11039
|
'gpt-4.1-nano',
|
|
10857
11040
|
'gpt-5',
|
|
10858
11041
|
'gpt-5-mini',
|
|
11042
|
+
'gpt-5.4-mini',
|
|
10859
11043
|
'gpt-5-nano',
|
|
10860
11044
|
'gpt-5.1',
|
|
10861
11045
|
'gpt-5.4',
|
|
@@ -10884,6 +11068,7 @@ function supportsTemperature(model) {
|
|
|
10884
11068
|
'o3',
|
|
10885
11069
|
'gpt-5',
|
|
10886
11070
|
'gpt-5-mini',
|
|
11071
|
+
'gpt-5.4-mini',
|
|
10887
11072
|
'gpt-5-nano',
|
|
10888
11073
|
'gpt-5.1',
|
|
10889
11074
|
'gpt-5.4',
|
|
@@ -10913,6 +11098,7 @@ function isGPT5Model(model) {
|
|
|
10913
11098
|
const gpt5Models = [
|
|
10914
11099
|
'gpt-5',
|
|
10915
11100
|
'gpt-5-mini',
|
|
11101
|
+
'gpt-5.4-mini',
|
|
10916
11102
|
'gpt-5-nano',
|
|
10917
11103
|
'gpt-5.1',
|
|
10918
11104
|
'gpt-5.4',
|
|
@@ -11222,6 +11408,7 @@ const MULTIMODAL_VISION_MODELS = new Set([
|
|
|
11222
11408
|
'gpt-4o',
|
|
11223
11409
|
'gpt-5',
|
|
11224
11410
|
'gpt-5-mini',
|
|
11411
|
+
'gpt-5.4-mini',
|
|
11225
11412
|
'gpt-5-nano',
|
|
11226
11413
|
'gpt-5.1',
|
|
11227
11414
|
'gpt-5.4',
|