@discomedia/utils 1.0.60 → 1.0.62

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.
@@ -9,6 +9,8 @@ function isOpenRouterModel(model) {
9
9
  'openai/gpt-5-mini',
10
10
  'openai/gpt-5-nano',
11
11
  'openai/gpt-5.1',
12
+ 'openai/gpt-5.4',
13
+ 'openai/gpt-5.4-pro',
12
14
  'openai/gpt-5.2',
13
15
  'openai/gpt-5.2-pro',
14
16
  'openai/gpt-5.1-codex',
@@ -260,7 +262,7 @@ const safeJSON = (text) => {
260
262
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
261
263
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
262
264
 
263
- const VERSION = '6.22.0'; // x-release-please-version
265
+ const VERSION = '6.27.0'; // x-release-please-version
264
266
 
265
267
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
266
268
  const isRunningInBrowser = () => {
@@ -880,6 +882,11 @@ function stringify(object, opts = {}) {
880
882
  return joined.length > 0 ? prefix + joined : '';
881
883
  }
882
884
 
885
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
886
+ function stringifyQuery(query) {
887
+ return stringify(query, { arrayFormat: 'brackets' });
888
+ }
889
+
883
890
  function concatBytes(buffers) {
884
891
  let length = 0;
885
892
  for (const buffer of buffers) {
@@ -1098,7 +1105,7 @@ class Stream {
1098
1105
  this.controller = controller;
1099
1106
  __classPrivateFieldSet(this, _Stream_client, client);
1100
1107
  }
1101
- static fromSSEResponse(response, controller, client) {
1108
+ static fromSSEResponse(response, controller, client, synthesizeEventData) {
1102
1109
  let consumed = false;
1103
1110
  const logger = client ? loggerFor(client) : console;
1104
1111
  async function* iterator() {
@@ -1128,7 +1135,7 @@ class Stream {
1128
1135
  if (data && data.error) {
1129
1136
  throw new APIError(undefined, data.error, undefined, response.headers);
1130
1137
  }
1131
- yield data;
1138
+ yield synthesizeEventData ? { event: sse.event, data } : data;
1132
1139
  }
1133
1140
  else {
1134
1141
  let data;
@@ -1378,9 +1385,9 @@ async function defaultParseResponse(client, props) {
1378
1385
  // Note: there is an invariant here that isn't represented in the type system
1379
1386
  // that if you set `stream: true` the response type must also be `Stream<T>`
1380
1387
  if (props.options.__streamClass) {
1381
- return props.options.__streamClass.fromSSEResponse(response, props.controller, client);
1388
+ return props.options.__streamClass.fromSSEResponse(response, props.controller, client, props.options.__synthesizeEventData);
1382
1389
  }
1383
- return Stream.fromSSEResponse(response, props.controller, client);
1390
+ return Stream.fromSSEResponse(response, props.controller, client, props.options.__synthesizeEventData);
1384
1391
  }
1385
1392
  // fetch refuses to read the body when the status code is 204.
1386
1393
  if (response.status === 204) {
@@ -1933,6 +1940,9 @@ const createPathTagFunction = (pathEncoder = encodeURIPath) => function path(sta
1933
1940
  const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
1934
1941
 
1935
1942
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
1943
+ /**
1944
+ * Given a list of messages comprising a conversation, the model will return a response.
1945
+ */
1936
1946
  let Messages$1 = class Messages extends APIResource {
1937
1947
  /**
1938
1948
  * Get the messages in a stored chat completion. Only Chat Completions that have
@@ -3295,6 +3305,9 @@ class ChatCompletionStreamingRunner extends ChatCompletionStream {
3295
3305
  }
3296
3306
 
3297
3307
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3308
+ /**
3309
+ * Given a list of messages comprising a conversation, the model will return a response.
3310
+ */
3298
3311
  let Completions$1 = class Completions extends APIResource {
3299
3312
  constructor() {
3300
3313
  super(...arguments);
@@ -3465,10 +3478,15 @@ const buildHeaders = (newHeaders) => {
3465
3478
  };
3466
3479
 
3467
3480
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3481
+ /**
3482
+ * Turn audio into text or text into audio.
3483
+ */
3468
3484
  class Speech extends APIResource {
3469
3485
  /**
3470
3486
  * Generates audio from the input text.
3471
3487
  *
3488
+ * Returns the audio file content, or a stream of audio events.
3489
+ *
3472
3490
  * @example
3473
3491
  * ```ts
3474
3492
  * const speech = await client.audio.speech.create({
@@ -3492,6 +3510,9 @@ class Speech extends APIResource {
3492
3510
  }
3493
3511
 
3494
3512
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3513
+ /**
3514
+ * Turn audio into text or text into audio.
3515
+ */
3495
3516
  class Transcriptions extends APIResource {
3496
3517
  create(body, options) {
3497
3518
  return this._client.post('/audio/transcriptions', multipartFormRequestOptions({
@@ -3504,6 +3525,9 @@ class Transcriptions extends APIResource {
3504
3525
  }
3505
3526
 
3506
3527
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3528
+ /**
3529
+ * Turn audio into text or text into audio.
3530
+ */
3507
3531
  class Translations extends APIResource {
3508
3532
  create(body, options) {
3509
3533
  return this._client.post('/audio/translations', multipartFormRequestOptions({ body, ...options, __metadata: { model: body.model } }, this._client));
@@ -3524,6 +3548,9 @@ Audio.Translations = Translations;
3524
3548
  Audio.Speech = Speech;
3525
3549
 
3526
3550
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3551
+ /**
3552
+ * Create large batches of API requests to run asynchronously.
3553
+ */
3527
3554
  class Batches extends APIResource {
3528
3555
  /**
3529
3556
  * Creates and executes a batch from an uploaded file of requests
@@ -3554,6 +3581,9 @@ class Batches extends APIResource {
3554
3581
  }
3555
3582
 
3556
3583
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3584
+ /**
3585
+ * Build Assistants that can call models and use tools.
3586
+ */
3557
3587
  class Assistants extends APIResource {
3558
3588
  /**
3559
3589
  * Create an assistant with a model and instructions.
@@ -3684,7 +3714,7 @@ Realtime$1.TranscriptionSessions = TranscriptionSessions;
3684
3714
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3685
3715
  class Sessions extends APIResource {
3686
3716
  /**
3687
- * Create a ChatKit session
3717
+ * Create a ChatKit session.
3688
3718
  *
3689
3719
  * @example
3690
3720
  * ```ts
@@ -3703,7 +3733,9 @@ class Sessions extends APIResource {
3703
3733
  });
3704
3734
  }
3705
3735
  /**
3706
- * Cancel a ChatKit session
3736
+ * Cancel an active ChatKit session and return its most recent metadata.
3737
+ *
3738
+ * Cancelling prevents new requests from using the issued client secret.
3707
3739
  *
3708
3740
  * @example
3709
3741
  * ```ts
@@ -3722,7 +3754,7 @@ class Sessions extends APIResource {
3722
3754
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3723
3755
  let Threads$1 = class Threads extends APIResource {
3724
3756
  /**
3725
- * Retrieve a ChatKit thread
3757
+ * Retrieve a ChatKit thread by its identifier.
3726
3758
  *
3727
3759
  * @example
3728
3760
  * ```ts
@@ -3737,7 +3769,7 @@ let Threads$1 = class Threads extends APIResource {
3737
3769
  });
3738
3770
  }
3739
3771
  /**
3740
- * List ChatKit threads
3772
+ * List ChatKit threads with optional pagination and user filters.
3741
3773
  *
3742
3774
  * @example
3743
3775
  * ```ts
@@ -3755,7 +3787,7 @@ let Threads$1 = class Threads extends APIResource {
3755
3787
  });
3756
3788
  }
3757
3789
  /**
3758
- * Delete a ChatKit thread
3790
+ * Delete a ChatKit thread along with its items and stored attachments.
3759
3791
  *
3760
3792
  * @example
3761
3793
  * ```ts
@@ -3771,7 +3803,7 @@ let Threads$1 = class Threads extends APIResource {
3771
3803
  });
3772
3804
  }
3773
3805
  /**
3774
- * List ChatKit thread items
3806
+ * List items that belong to a ChatKit thread.
3775
3807
  *
3776
3808
  * @example
3777
3809
  * ```ts
@@ -3801,6 +3833,8 @@ ChatKit.Threads = Threads$1;
3801
3833
 
3802
3834
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3803
3835
  /**
3836
+ * Build Assistants that can call models and use tools.
3837
+ *
3804
3838
  * @deprecated The Assistants API is deprecated in favor of the Responses API
3805
3839
  */
3806
3840
  class Messages extends APIResource {
@@ -3869,6 +3903,8 @@ class Messages extends APIResource {
3869
3903
 
3870
3904
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3871
3905
  /**
3906
+ * Build Assistants that can call models and use tools.
3907
+ *
3872
3908
  * @deprecated The Assistants API is deprecated in favor of the Responses API
3873
3909
  */
3874
3910
  class Steps extends APIResource {
@@ -4481,6 +4517,8 @@ _a$1 = AssistantStream, _AssistantStream_addEvent = function _AssistantStream_ad
4481
4517
 
4482
4518
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4483
4519
  /**
4520
+ * Build Assistants that can call models and use tools.
4521
+ *
4484
4522
  * @deprecated The Assistants API is deprecated in favor of the Responses API
4485
4523
  */
4486
4524
  let Runs$1 = class Runs extends APIResource {
@@ -4496,6 +4534,7 @@ let Runs$1 = class Runs extends APIResource {
4496
4534
  ...options,
4497
4535
  headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
4498
4536
  stream: params.stream ?? false,
4537
+ __synthesizeEventData: true,
4499
4538
  });
4500
4539
  }
4501
4540
  /**
@@ -4626,6 +4665,7 @@ let Runs$1 = class Runs extends APIResource {
4626
4665
  ...options,
4627
4666
  headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
4628
4667
  stream: params.stream ?? false,
4668
+ __synthesizeEventData: true,
4629
4669
  });
4630
4670
  }
4631
4671
  /**
@@ -4650,6 +4690,8 @@ Runs$1.Steps = Steps;
4650
4690
 
4651
4691
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4652
4692
  /**
4693
+ * Build Assistants that can call models and use tools.
4694
+ *
4653
4695
  * @deprecated The Assistants API is deprecated in favor of the Responses API
4654
4696
  */
4655
4697
  class Threads extends APIResource {
@@ -4710,6 +4752,7 @@ class Threads extends APIResource {
4710
4752
  ...options,
4711
4753
  headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
4712
4754
  stream: body.stream ?? false,
4755
+ __synthesizeEventData: true,
4713
4756
  });
4714
4757
  }
4715
4758
  /**
@@ -4747,6 +4790,9 @@ Beta.Assistants = Assistants;
4747
4790
  Beta.Threads = Threads;
4748
4791
 
4749
4792
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4793
+ /**
4794
+ * Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.
4795
+ */
4750
4796
  class Completions extends APIResource {
4751
4797
  create(body, options) {
4752
4798
  return this._client.post('/completions', { body, ...options, stream: body.stream ?? false });
@@ -4849,6 +4895,9 @@ class Containers extends APIResource {
4849
4895
  Containers.Files = Files$2;
4850
4896
 
4851
4897
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4898
+ /**
4899
+ * Manage conversations and conversation items.
4900
+ */
4852
4901
  class Items extends APIResource {
4853
4902
  /**
4854
4903
  * Create items in a conversation with the given ID.
@@ -4884,6 +4933,9 @@ class Items extends APIResource {
4884
4933
  }
4885
4934
 
4886
4935
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4936
+ /**
4937
+ * Manage conversations and conversation items.
4938
+ */
4887
4939
  class Conversations extends APIResource {
4888
4940
  constructor() {
4889
4941
  super(...arguments);
@@ -4917,6 +4969,9 @@ class Conversations extends APIResource {
4917
4969
  Conversations.Items = Items;
4918
4970
 
4919
4971
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4972
+ /**
4973
+ * Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms.
4974
+ */
4920
4975
  class Embeddings extends APIResource {
4921
4976
  /**
4922
4977
  * Creates an embedding vector representing the input text.
@@ -4967,6 +5022,9 @@ class Embeddings extends APIResource {
4967
5022
  }
4968
5023
 
4969
5024
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5025
+ /**
5026
+ * Manage and run evals in the OpenAI platform.
5027
+ */
4970
5028
  class OutputItems extends APIResource {
4971
5029
  /**
4972
5030
  * Get an evaluation run output item by ID.
@@ -4985,6 +5043,9 @@ class OutputItems extends APIResource {
4985
5043
  }
4986
5044
 
4987
5045
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5046
+ /**
5047
+ * Manage and run evals in the OpenAI platform.
5048
+ */
4988
5049
  class Runs extends APIResource {
4989
5050
  constructor() {
4990
5051
  super(...arguments);
@@ -5032,6 +5093,9 @@ class Runs extends APIResource {
5032
5093
  Runs.OutputItems = OutputItems;
5033
5094
 
5034
5095
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5096
+ /**
5097
+ * Manage and run evals in the OpenAI platform.
5098
+ */
5035
5099
  class Evals extends APIResource {
5036
5100
  constructor() {
5037
5101
  super(...arguments);
@@ -5076,6 +5140,9 @@ class Evals extends APIResource {
5076
5140
  Evals.Runs = Runs;
5077
5141
 
5078
5142
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5143
+ /**
5144
+ * Files are used to upload documents that can be used with features like Assistants and Fine-tuning.
5145
+ */
5079
5146
  let Files$1 = class Files extends APIResource {
5080
5147
  /**
5081
5148
  * Upload a file that can be used across various endpoints. Individual files can be
@@ -5155,6 +5222,9 @@ class Methods extends APIResource {
5155
5222
  }
5156
5223
 
5157
5224
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5225
+ /**
5226
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
5227
+ */
5158
5228
  let Graders$1 = class Graders extends APIResource {
5159
5229
  /**
5160
5230
  * Run a grader.
@@ -5208,6 +5278,9 @@ class Alpha extends APIResource {
5208
5278
  Alpha.Graders = Graders$1;
5209
5279
 
5210
5280
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5281
+ /**
5282
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
5283
+ */
5211
5284
  class Permissions extends APIResource {
5212
5285
  /**
5213
5286
  * **NOTE:** Calling this endpoint requires an [admin API key](../admin-api-keys).
@@ -5235,13 +5308,7 @@ class Permissions extends APIResource {
5235
5308
  * Organization owners can use this endpoint to view all permissions for a
5236
5309
  * fine-tuned model checkpoint.
5237
5310
  *
5238
- * @example
5239
- * ```ts
5240
- * const permission =
5241
- * await client.fineTuning.checkpoints.permissions.retrieve(
5242
- * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F',
5243
- * );
5244
- * ```
5311
+ * @deprecated Retrieve is deprecated. Please swap to the paginated list method instead.
5245
5312
  */
5246
5313
  retrieve(fineTunedModelCheckpoint, query = {}, options) {
5247
5314
  return this._client.get(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, {
@@ -5249,6 +5316,25 @@ class Permissions extends APIResource {
5249
5316
  ...options,
5250
5317
  });
5251
5318
  }
5319
+ /**
5320
+ * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys).
5321
+ *
5322
+ * Organization owners can use this endpoint to view all permissions for a
5323
+ * fine-tuned model checkpoint.
5324
+ *
5325
+ * @example
5326
+ * ```ts
5327
+ * // Automatically fetches more pages as needed.
5328
+ * for await (const permissionListResponse of client.fineTuning.checkpoints.permissions.list(
5329
+ * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F',
5330
+ * )) {
5331
+ * // ...
5332
+ * }
5333
+ * ```
5334
+ */
5335
+ list(fineTunedModelCheckpoint, query = {}, options) {
5336
+ return this._client.getAPIList(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, (ConversationCursorPage), { query, ...options });
5337
+ }
5252
5338
  /**
5253
5339
  * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys).
5254
5340
  *
@@ -5283,6 +5369,9 @@ let Checkpoints$1 = class Checkpoints extends APIResource {
5283
5369
  Checkpoints$1.Permissions = Permissions;
5284
5370
 
5285
5371
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5372
+ /**
5373
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
5374
+ */
5286
5375
  class Checkpoints extends APIResource {
5287
5376
  /**
5288
5377
  * List checkpoints for a fine-tuning job.
@@ -5303,6 +5392,9 @@ class Checkpoints extends APIResource {
5303
5392
  }
5304
5393
 
5305
5394
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5395
+ /**
5396
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
5397
+ */
5306
5398
  class Jobs extends APIResource {
5307
5399
  constructor() {
5308
5400
  super(...arguments);
@@ -5444,6 +5536,9 @@ class Graders extends APIResource {
5444
5536
  Graders.GraderModels = GraderModels;
5445
5537
 
5446
5538
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5539
+ /**
5540
+ * Given a prompt and/or an input image, the model will generate a new image.
5541
+ */
5447
5542
  class Images extends APIResource {
5448
5543
  /**
5449
5544
  * Creates a variation of a given image. This endpoint only supports `dall-e-2`.
@@ -5467,6 +5562,9 @@ class Images extends APIResource {
5467
5562
  }
5468
5563
 
5469
5564
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5565
+ /**
5566
+ * List and describe the various models available in the API.
5567
+ */
5470
5568
  class Models extends APIResource {
5471
5569
  /**
5472
5570
  * Retrieves a model instance, providing basic information about the model such as
@@ -5492,6 +5590,9 @@ class Models extends APIResource {
5492
5590
  }
5493
5591
 
5494
5592
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5593
+ /**
5594
+ * Given text and/or image inputs, classifies if those inputs are potentially harmful.
5595
+ */
5495
5596
  class Moderations extends APIResource {
5496
5597
  /**
5497
5598
  * Classifies if text and/or image inputs are potentially harmful. Learn more in
@@ -5575,6 +5676,20 @@ class ClientSecrets extends APIResource {
5575
5676
  /**
5576
5677
  * Create a Realtime client secret with an associated session configuration.
5577
5678
  *
5679
+ * Client secrets are short-lived tokens that can be passed to a client app, such
5680
+ * as a web frontend or mobile client, which grants access to the Realtime API
5681
+ * without leaking your main API key. You can configure a custom TTL for each
5682
+ * client secret.
5683
+ *
5684
+ * You can also attach session configuration options to the client secret, which
5685
+ * will be applied to any sessions created using that client secret, but these can
5686
+ * also be overridden by the client connection.
5687
+ *
5688
+ * [Learn more about authentication with client secrets over WebRTC](https://platform.openai.com/docs/guides/realtime-webrtc).
5689
+ *
5690
+ * Returns the created client secret and the effective session object. The client
5691
+ * secret is a string that looks like `ek_1234`.
5692
+ *
5578
5693
  * @example
5579
5694
  * ```ts
5580
5695
  * const clientSecret =
@@ -6000,7 +6115,10 @@ class InputItems extends APIResource {
6000
6115
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6001
6116
  class InputTokens extends APIResource {
6002
6117
  /**
6003
- * Get input token counts
6118
+ * Returns input token counts of the request.
6119
+ *
6120
+ * Returns an object with `object` set to `response.input_tokens` and an
6121
+ * `input_tokens` count.
6004
6122
  *
6005
6123
  * @example
6006
6124
  * ```ts
@@ -6082,12 +6200,17 @@ class Responses extends APIResource {
6082
6200
  return this._client.post(path `/responses/${responseID}/cancel`, options);
6083
6201
  }
6084
6202
  /**
6085
- * Compact conversation
6203
+ * Compact a conversation. Returns a compacted response object.
6204
+ *
6205
+ * Learn when and how to compact long-running conversations in the
6206
+ * [conversation state guide](https://platform.openai.com/docs/guides/conversation-state#managing-the-context-window).
6207
+ * For ZDR-compatible compaction details, see
6208
+ * [Compaction (advanced)](https://platform.openai.com/docs/guides/conversation-state#compaction-advanced).
6086
6209
  *
6087
6210
  * @example
6088
6211
  * ```ts
6089
6212
  * const compactedResponse = await client.responses.compact({
6090
- * model: 'gpt-5.2',
6213
+ * model: 'gpt-5.4',
6091
6214
  * });
6092
6215
  * ```
6093
6216
  */
@@ -6101,7 +6224,7 @@ Responses.InputTokens = InputTokens;
6101
6224
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6102
6225
  let Content$1 = class Content extends APIResource {
6103
6226
  /**
6104
- * Get Skill Content
6227
+ * Download a skill zip bundle by its ID.
6105
6228
  */
6106
6229
  retrieve(skillID, options) {
6107
6230
  return this._client.get(path `/skills/${skillID}/content`, {
@@ -6115,7 +6238,7 @@ let Content$1 = class Content extends APIResource {
6115
6238
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6116
6239
  class Content extends APIResource {
6117
6240
  /**
6118
- * Get Skill Version Content
6241
+ * Download a skill version zip bundle.
6119
6242
  */
6120
6243
  retrieve(version, params, options) {
6121
6244
  const { skill_id } = params;
@@ -6134,20 +6257,20 @@ class Versions extends APIResource {
6134
6257
  this.content = new Content(this._client);
6135
6258
  }
6136
6259
  /**
6137
- * Create Skill Version
6260
+ * Create a new immutable skill version.
6138
6261
  */
6139
6262
  create(skillID, body = {}, options) {
6140
6263
  return this._client.post(path `/skills/${skillID}/versions`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
6141
6264
  }
6142
6265
  /**
6143
- * Get Skill Version
6266
+ * Get a specific skill version.
6144
6267
  */
6145
6268
  retrieve(version, params, options) {
6146
6269
  const { skill_id } = params;
6147
6270
  return this._client.get(path `/skills/${skill_id}/versions/${version}`, options);
6148
6271
  }
6149
6272
  /**
6150
- * List Skill Versions
6273
+ * List skill versions for a skill.
6151
6274
  */
6152
6275
  list(skillID, query = {}, options) {
6153
6276
  return this._client.getAPIList(path `/skills/${skillID}/versions`, (CursorPage), {
@@ -6156,7 +6279,7 @@ class Versions extends APIResource {
6156
6279
  });
6157
6280
  }
6158
6281
  /**
6159
- * Delete Skill Version
6282
+ * Delete a skill version.
6160
6283
  */
6161
6284
  delete(version, params, options) {
6162
6285
  const { skill_id } = params;
@@ -6173,31 +6296,31 @@ class Skills extends APIResource {
6173
6296
  this.versions = new Versions(this._client);
6174
6297
  }
6175
6298
  /**
6176
- * Create Skill
6299
+ * Create a new skill.
6177
6300
  */
6178
6301
  create(body = {}, options) {
6179
6302
  return this._client.post('/skills', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
6180
6303
  }
6181
6304
  /**
6182
- * Get Skill
6305
+ * Get a skill by its ID.
6183
6306
  */
6184
6307
  retrieve(skillID, options) {
6185
6308
  return this._client.get(path `/skills/${skillID}`, options);
6186
6309
  }
6187
6310
  /**
6188
- * Update Skill Default Version
6311
+ * Update the default version pointer for a skill.
6189
6312
  */
6190
6313
  update(skillID, body, options) {
6191
6314
  return this._client.post(path `/skills/${skillID}`, { body, ...options });
6192
6315
  }
6193
6316
  /**
6194
- * List Skills
6317
+ * List all skills for the current project.
6195
6318
  */
6196
6319
  list(query = {}, options) {
6197
6320
  return this._client.getAPIList('/skills', (CursorPage), { query, ...options });
6198
6321
  }
6199
6322
  /**
6200
- * Delete Skill
6323
+ * Delete a skill by its ID.
6201
6324
  */
6202
6325
  delete(skillID, options) {
6203
6326
  return this._client.delete(path `/skills/${skillID}`, options);
@@ -6207,6 +6330,9 @@ Skills.Content = Content$1;
6207
6330
  Skills.Versions = Versions;
6208
6331
 
6209
6332
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6333
+ /**
6334
+ * Use Uploads to upload large files in multiple parts.
6335
+ */
6210
6336
  class Parts extends APIResource {
6211
6337
  /**
6212
6338
  * Adds a
@@ -6227,6 +6353,9 @@ class Parts extends APIResource {
6227
6353
  }
6228
6354
 
6229
6355
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6356
+ /**
6357
+ * Use Uploads to upload large files in multiple parts.
6358
+ */
6230
6359
  class Uploads extends APIResource {
6231
6360
  constructor() {
6232
6361
  super(...arguments);
@@ -6252,12 +6381,16 @@ class Uploads extends APIResource {
6252
6381
  * For guidance on the proper filename extensions for each purpose, please follow
6253
6382
  * the documentation on
6254
6383
  * [creating a File](https://platform.openai.com/docs/api-reference/files/create).
6384
+ *
6385
+ * Returns the Upload object with status `pending`.
6255
6386
  */
6256
6387
  create(body, options) {
6257
6388
  return this._client.post('/uploads', { body, ...options });
6258
6389
  }
6259
6390
  /**
6260
6391
  * Cancels the Upload. No Parts may be added after an Upload is cancelled.
6392
+ *
6393
+ * Returns the Upload object with status `cancelled`.
6261
6394
  */
6262
6395
  cancel(uploadID, options) {
6263
6396
  return this._client.post(path `/uploads/${uploadID}/cancel`, options);
@@ -6275,7 +6408,9 @@ class Uploads extends APIResource {
6275
6408
  *
6276
6409
  * The number of bytes uploaded upon completion must match the number of bytes
6277
6410
  * initially specified when creating the Upload object. No Parts may be added after
6278
- * an Upload is completed.
6411
+ * an Upload is completed. Returns the Upload object with status `completed`,
6412
+ * including an additional `file` property containing the created usable File
6413
+ * object.
6279
6414
  */
6280
6415
  complete(uploadID, body, options) {
6281
6416
  return this._client.post(path `/uploads/${uploadID}/complete`, { body, ...options });
@@ -6635,31 +6770,33 @@ VectorStores.FileBatches = FileBatches;
6635
6770
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6636
6771
  class Videos extends APIResource {
6637
6772
  /**
6638
- * Create a video
6773
+ * Create a new video generation job from a prompt and optional reference assets.
6639
6774
  */
6640
6775
  create(body, options) {
6641
6776
  return this._client.post('/videos', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
6642
6777
  }
6643
6778
  /**
6644
- * Retrieve a video
6779
+ * Fetch the latest metadata for a generated video.
6645
6780
  */
6646
6781
  retrieve(videoID, options) {
6647
6782
  return this._client.get(path `/videos/${videoID}`, options);
6648
6783
  }
6649
6784
  /**
6650
- * List videos
6785
+ * List recently generated videos for the current project.
6651
6786
  */
6652
6787
  list(query = {}, options) {
6653
6788
  return this._client.getAPIList('/videos', (ConversationCursorPage), { query, ...options });
6654
6789
  }
6655
6790
  /**
6656
- * Delete a video
6791
+ * Permanently delete a completed or failed video and its stored assets.
6657
6792
  */
6658
6793
  delete(videoID, options) {
6659
6794
  return this._client.delete(path `/videos/${videoID}`, options);
6660
6795
  }
6661
6796
  /**
6662
- * Download video content
6797
+ * Download the generated video bytes or a derived preview asset.
6798
+ *
6799
+ * Streams the rendered video content for the specified video job.
6663
6800
  */
6664
6801
  downloadContent(videoID, query = {}, options) {
6665
6802
  return this._client.get(path `/videos/${videoID}/content`, {
@@ -6670,7 +6807,7 @@ class Videos extends APIResource {
6670
6807
  });
6671
6808
  }
6672
6809
  /**
6673
- * Create a video remix
6810
+ * Create a remix of a completed video using a refreshed prompt.
6674
6811
  */
6675
6812
  remix(videoID, body, options) {
6676
6813
  return this._client.post(path `/videos/${videoID}/remix`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
@@ -6795,24 +6932,54 @@ class OpenAI {
6795
6932
  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 } = {}) {
6796
6933
  _OpenAI_instances.add(this);
6797
6934
  _OpenAI_encoder.set(this, void 0);
6935
+ /**
6936
+ * Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.
6937
+ */
6798
6938
  this.completions = new Completions(this);
6799
6939
  this.chat = new Chat(this);
6940
+ /**
6941
+ * Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms.
6942
+ */
6800
6943
  this.embeddings = new Embeddings(this);
6944
+ /**
6945
+ * Files are used to upload documents that can be used with features like Assistants and Fine-tuning.
6946
+ */
6801
6947
  this.files = new Files$1(this);
6948
+ /**
6949
+ * Given a prompt and/or an input image, the model will generate a new image.
6950
+ */
6802
6951
  this.images = new Images(this);
6803
6952
  this.audio = new Audio(this);
6953
+ /**
6954
+ * Given text and/or image inputs, classifies if those inputs are potentially harmful.
6955
+ */
6804
6956
  this.moderations = new Moderations(this);
6957
+ /**
6958
+ * List and describe the various models available in the API.
6959
+ */
6805
6960
  this.models = new Models(this);
6806
6961
  this.fineTuning = new FineTuning(this);
6807
6962
  this.graders = new Graders(this);
6808
6963
  this.vectorStores = new VectorStores(this);
6809
6964
  this.webhooks = new Webhooks(this);
6810
6965
  this.beta = new Beta(this);
6966
+ /**
6967
+ * Create large batches of API requests to run asynchronously.
6968
+ */
6811
6969
  this.batches = new Batches(this);
6970
+ /**
6971
+ * Use Uploads to upload large files in multiple parts.
6972
+ */
6812
6973
  this.uploads = new Uploads(this);
6813
6974
  this.responses = new Responses(this);
6814
6975
  this.realtime = new Realtime(this);
6976
+ /**
6977
+ * Manage conversations and conversation items.
6978
+ */
6815
6979
  this.conversations = new Conversations(this);
6980
+ /**
6981
+ * Manage and run evals in the OpenAI platform.
6982
+ */
6816
6983
  this.evals = new Evals(this);
6817
6984
  this.containers = new Containers(this);
6818
6985
  this.skills = new Skills(this);
@@ -6882,7 +7049,7 @@ class OpenAI {
6882
7049
  return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
6883
7050
  }
6884
7051
  stringifyQuery(query) {
6885
- return stringify(query, { arrayFormat: 'brackets' });
7052
+ return stringifyQuery(query);
6886
7053
  }
6887
7054
  getUserAgent() {
6888
7055
  return `${this.constructor.name}/JS ${VERSION}`;
@@ -7151,9 +7318,9 @@ class OpenAI {
7151
7318
  timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
7152
7319
  }
7153
7320
  }
7154
- // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
7155
- // just do what it says, but otherwise calculate a default
7156
- if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
7321
+ // If the API asks us to wait a certain amount of time, just do what it
7322
+ // says, but otherwise calculate a default
7323
+ if (timeoutMillis === undefined) {
7157
7324
  const maxRetries = options.maxRetries ?? this.maxRetries;
7158
7325
  timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
7159
7326
  }
@@ -7250,6 +7417,13 @@ class OpenAI {
7250
7417
  (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
7251
7418
  return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
7252
7419
  }
7420
+ else if (typeof body === 'object' &&
7421
+ headers.values.get('content-type') === 'application/x-www-form-urlencoded') {
7422
+ return {
7423
+ bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
7424
+ body: this.stringifyQuery(body),
7425
+ };
7426
+ }
7253
7427
  else {
7254
7428
  return __classPrivateFieldGet(this, _OpenAI_encoder, "f").call(this, { body, headers });
7255
7429
  }
@@ -7300,78 +7474,107 @@ OpenAI.Videos = Videos;
7300
7474
 
7301
7475
  // llm-openai-config.ts
7302
7476
  const DEFAULT_MODEL = 'gpt-4.1-mini';
7303
- /** Token costs in USD per 1M tokens. Last updated Feb 2025. */
7477
+ const GPT_5_4_HIGH_CONTEXT_THRESHOLD_TOKENS = 272_000;
7478
+ const GPT_5_4_HIGH_CONTEXT_INPUT_MULTIPLIER = 2;
7479
+ const GPT_5_4_HIGH_CONTEXT_OUTPUT_MULTIPLIER = 1.5;
7480
+ /** Token costs in USD per 1M tokens. Last updated Mar 2026. */
7304
7481
  const openAiModelCosts = {
7305
7482
  'gpt-4o': {
7306
7483
  inputCost: 2.5 / 1_000_000,
7484
+ cacheHitCost: 1.25 / 1_000_000,
7307
7485
  outputCost: 10 / 1_000_000,
7308
7486
  },
7309
7487
  'gpt-4o-mini': {
7310
7488
  inputCost: 0.15 / 1_000_000,
7489
+ cacheHitCost: 0.075 / 1_000_000,
7311
7490
  outputCost: 0.6 / 1_000_000,
7312
7491
  },
7313
7492
  'o1-mini': {
7314
7493
  inputCost: 1.1 / 1_000_000,
7494
+ cacheHitCost: 0.55 / 1_000_000,
7315
7495
  outputCost: 4.4 / 1_000_000,
7316
7496
  },
7317
7497
  'o1': {
7318
7498
  inputCost: 15 / 1_000_000,
7499
+ cacheHitCost: 7.5 / 1_000_000,
7319
7500
  outputCost: 60 / 1_000_000,
7320
7501
  },
7321
7502
  'o3-mini': {
7322
7503
  inputCost: 1.1 / 1_000_000,
7504
+ cacheHitCost: 0.55 / 1_000_000,
7323
7505
  outputCost: 4.4 / 1_000_000,
7324
7506
  },
7325
7507
  'o3': {
7326
7508
  inputCost: 2 / 1_000_000,
7509
+ cacheHitCost: 0.5 / 1_000_000,
7327
7510
  outputCost: 8 / 1_000_000,
7328
7511
  },
7329
7512
  'gpt-4.1': {
7330
7513
  inputCost: 2 / 1_000_000,
7514
+ cacheHitCost: 0.5 / 1_000_000,
7331
7515
  outputCost: 8 / 1_000_000,
7332
7516
  },
7333
7517
  'gpt-4.1-mini': {
7334
7518
  inputCost: 0.4 / 1_000_000,
7519
+ cacheHitCost: 0.1 / 1_000_000,
7335
7520
  outputCost: 1.6 / 1_000_000,
7336
7521
  },
7337
7522
  'gpt-4.1-nano': {
7338
7523
  inputCost: 0.1 / 1_000_000,
7524
+ cacheHitCost: 0.025 / 1_000_000,
7339
7525
  outputCost: 0.4 / 1_000_000,
7340
7526
  },
7341
7527
  'gpt-5': {
7342
7528
  inputCost: 1.25 / 1_000_000,
7529
+ cacheHitCost: 0.125 / 1_000_000,
7343
7530
  outputCost: 10 / 1_000_000,
7344
7531
  },
7345
7532
  'gpt-5-mini': {
7346
7533
  inputCost: 0.25 / 1_000_000,
7534
+ cacheHitCost: 0.025 / 1_000_000,
7347
7535
  outputCost: 2 / 1_000_000,
7348
7536
  },
7349
7537
  'gpt-5-nano': {
7350
7538
  inputCost: 0.05 / 1_000_000,
7539
+ cacheHitCost: 0.005 / 1_000_000,
7351
7540
  outputCost: 0.4 / 1_000_000,
7352
7541
  },
7353
7542
  'gpt-5.1': {
7354
7543
  inputCost: 1.25 / 1_000_000,
7544
+ cacheHitCost: 0.125 / 1_000_000,
7355
7545
  outputCost: 10 / 1_000_000,
7356
7546
  },
7547
+ 'gpt-5.4': {
7548
+ inputCost: 2.5 / 1_000_000,
7549
+ cacheHitCost: 0.25 / 1_000_000,
7550
+ outputCost: 15 / 1_000_000,
7551
+ },
7552
+ 'gpt-5.4-pro': {
7553
+ inputCost: 30 / 1_000_000,
7554
+ outputCost: 180 / 1_000_000,
7555
+ },
7357
7556
  'gpt-5.2': {
7358
- inputCost: 1.5 / 1_000_000,
7359
- outputCost: 12 / 1_000_000,
7557
+ inputCost: 1.75 / 1_000_000,
7558
+ cacheHitCost: 0.175 / 1_000_000,
7559
+ outputCost: 14 / 1_000_000,
7360
7560
  },
7361
7561
  'gpt-5.2-pro': {
7362
- inputCost: 3 / 1_000_000,
7363
- outputCost: 24 / 1_000_000,
7562
+ inputCost: 21 / 1_000_000,
7563
+ outputCost: 168 / 1_000_000,
7364
7564
  },
7365
7565
  'gpt-5.1-codex': {
7366
- inputCost: 1.1 / 1_000_000,
7367
- outputCost: 8.8 / 1_000_000,
7566
+ inputCost: 1.25 / 1_000_000,
7567
+ cacheHitCost: 0.125 / 1_000_000,
7568
+ outputCost: 10 / 1_000_000,
7368
7569
  },
7369
7570
  'gpt-5.1-codex-max': {
7370
- inputCost: 1.8 / 1_000_000,
7371
- outputCost: 14.4 / 1_000_000,
7571
+ inputCost: 1.25 / 1_000_000,
7572
+ cacheHitCost: 0.125 / 1_000_000,
7573
+ outputCost: 10 / 1_000_000,
7372
7574
  },
7373
7575
  'o4-mini': {
7374
7576
  inputCost: 1.1 / 1_000_000,
7577
+ cacheHitCost: 0.275 / 1_000_000,
7375
7578
  outputCost: 4.4 / 1_000_000,
7376
7579
  },
7377
7580
  };
@@ -7387,6 +7590,9 @@ const deepseekModelCosts = {
7387
7590
  outputCost: 2.19 / 1_000_000, // $2.19 per 1M tokens
7388
7591
  },
7389
7592
  };
7593
+ function shouldUseGPT54HighContextPricing(model, inputTokens) {
7594
+ return (model === 'gpt-5.4' || model === 'gpt-5.4-pro') && inputTokens > GPT_5_4_HIGH_CONTEXT_THRESHOLD_TOKENS;
7595
+ }
7390
7596
  /** Image generation costs in USD per image. Based on OpenAI pricing as of Feb 2025. */
7391
7597
  const openAiImageCosts = {
7392
7598
  'gpt-image-1': 0.0075, // $0.0075 per image for gpt-image-1
@@ -7415,8 +7621,8 @@ function calculateImageCost(model, imageCount) {
7415
7621
  * @param model The name of the language model. Supported models are listed in the `openAiModelCosts` and `deepseekModelCosts` objects.
7416
7622
  * @param inputTokens The number of input tokens passed to the language model.
7417
7623
  * @param outputTokens The number of output tokens generated by the language model.
7418
- * @param reasoningTokens The number of output tokens generated by the language model for reasoning. This is only used for Deepseek models.
7419
- * @param cacheHitTokens The number of input tokens that were cache hits for Deepseek models.
7624
+ * @param reasoningTokens The number of output tokens generated by the language model for reasoning.
7625
+ * @param cacheHitTokens The number of input tokens billed at cached-input rates.
7420
7626
  * @returns The cost of calling the language model in USD.
7421
7627
  */
7422
7628
  function calculateCost(provider, model, inputTokens, outputTokens, reasoningTokens, cacheHitTokens) {
@@ -7431,12 +7637,18 @@ function calculateCost(provider, model, inputTokens, outputTokens, reasoningToke
7431
7637
  const modelCosts = provider === 'deepseek' ? deepseekModelCosts[model] : openAiModelCosts[model];
7432
7638
  if (!modelCosts)
7433
7639
  return 0;
7434
- // Calculate input cost based on cache hit/miss for Deepseek
7435
- const inputCost = provider === 'deepseek' && modelCosts.cacheHitCost
7436
- ? (cacheHitTokens || 0) * modelCosts.cacheHitCost + (inputTokens - (cacheHitTokens || 0)) * modelCosts.inputCost
7437
- : inputTokens * modelCosts.inputCost;
7438
- const outputCost = outputTokens * modelCosts.outputCost;
7439
- const reasoningCost = (reasoningTokens || 0) * modelCosts.outputCost;
7640
+ const boundedCacheHitTokens = Math.min(Math.max(cacheHitTokens || 0, 0), inputTokens);
7641
+ let inputCost = inputTokens * modelCosts.inputCost;
7642
+ if (typeof modelCosts.cacheHitCost === 'number' && boundedCacheHitTokens > 0) {
7643
+ inputCost = boundedCacheHitTokens * modelCosts.cacheHitCost + (inputTokens - boundedCacheHitTokens) * modelCosts.inputCost;
7644
+ }
7645
+ let outputCost = outputTokens * modelCosts.outputCost;
7646
+ let reasoningCost = (reasoningTokens || 0) * modelCosts.outputCost;
7647
+ if (provider === 'openai' && shouldUseGPT54HighContextPricing(model, inputTokens)) {
7648
+ inputCost *= GPT_5_4_HIGH_CONTEXT_INPUT_MULTIPLIER;
7649
+ outputCost *= GPT_5_4_HIGH_CONTEXT_OUTPUT_MULTIPLIER;
7650
+ reasoningCost *= GPT_5_4_HIGH_CONTEXT_OUTPUT_MULTIPLIER;
7651
+ }
7440
7652
  return inputCost + outputCost + reasoningCost;
7441
7653
  }
7442
7654
 
@@ -7834,6 +8046,8 @@ const isSupportedModel = (model) => {
7834
8046
  'gpt-5-mini',
7835
8047
  'gpt-5-nano',
7836
8048
  'gpt-5.1',
8049
+ 'gpt-5.4',
8050
+ 'gpt-5.4-pro',
7837
8051
  'gpt-5.2',
7838
8052
  'gpt-5.2-pro',
7839
8053
  'gpt-5.1-codex',
@@ -7860,6 +8074,8 @@ function supportsTemperature(model) {
7860
8074
  'gpt-5-mini',
7861
8075
  'gpt-5-nano',
7862
8076
  'gpt-5.1',
8077
+ 'gpt-5.4',
8078
+ 'gpt-5.4-pro',
7863
8079
  'gpt-5.2',
7864
8080
  'gpt-5.2-pro',
7865
8081
  'gpt-5.1-codex',
@@ -7887,6 +8103,8 @@ function isGPT5Model(model) {
7887
8103
  'gpt-5-mini',
7888
8104
  'gpt-5-nano',
7889
8105
  'gpt-5.1',
8106
+ 'gpt-5.4',
8107
+ 'gpt-5.4-pro',
7890
8108
  'gpt-5.2',
7891
8109
  'gpt-5.2-pro',
7892
8110
  'gpt-5.1-codex',
@@ -7894,6 +8112,12 @@ function isGPT5Model(model) {
7894
8112
  ];
7895
8113
  return gpt5Models.includes(model);
7896
8114
  }
8115
+ function supportsStructuredOutputs(model) {
8116
+ return normalizeModelName(model) !== 'gpt-5.4-pro';
8117
+ }
8118
+ function supportsDistillation(model) {
8119
+ return normalizeModelName(model) !== 'gpt-5.4-pro';
8120
+ }
7897
8121
  /**
7898
8122
  * Makes a call to OpenAI's Responses API for more advanced use cases with built-in tools.
7899
8123
  *
@@ -7936,8 +8160,15 @@ const makeResponsesAPICall = async (input, options = {}) => {
7936
8160
  input,
7937
8161
  ...cleanOptions,
7938
8162
  };
8163
+ if (requestBody.text?.format?.type === 'json_schema' && !supportsStructuredOutputs(normalizedModel)) {
8164
+ throw new Error(`Model ${normalizedModel} does not support structured outputs`);
8165
+ }
8166
+ if (requestBody.store && !supportsDistillation(normalizedModel)) {
8167
+ throw new Error(`Model ${normalizedModel} does not support distillation`);
8168
+ }
7939
8169
  // Make the API call to the Responses endpoint
7940
8170
  const response = await openai.responses.create(requestBody);
8171
+ const cacheHitTokens = response.usage?.input_tokens_details?.cached_tokens || 0;
7941
8172
  // Extract tool calls from the output
7942
8173
  const toolCalls = response.output
7943
8174
  ?.filter((item) => item.type === 'function_call')
@@ -7977,7 +8208,8 @@ const makeResponsesAPICall = async (input, options = {}) => {
7977
8208
  reasoning_tokens: response.usage?.output_tokens_details?.reasoning_tokens || 0,
7978
8209
  provider: 'openai',
7979
8210
  model: normalizedModel,
7980
- cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0),
8211
+ cache_hit_tokens: cacheHitTokens,
8212
+ cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0, cacheHitTokens),
7981
8213
  },
7982
8214
  tool_calls: toolCalls,
7983
8215
  ...(codeInterpreterOutputs ? { code_interpreter_outputs: codeInterpreterOutputs } : {}),
@@ -8009,7 +8241,8 @@ const makeResponsesAPICall = async (input, options = {}) => {
8009
8241
  reasoning_tokens: response.usage?.output_tokens_details?.reasoning_tokens || 0,
8010
8242
  provider: 'openai',
8011
8243
  model: normalizedModel,
8012
- cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0),
8244
+ cache_hit_tokens: cacheHitTokens,
8245
+ cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0, cacheHitTokens),
8013
8246
  },
8014
8247
  tool_calls: toolCalls,
8015
8248
  ...(codeInterpreterOutputs ? { code_interpreter_outputs: codeInterpreterOutputs } : {}),
@@ -8141,6 +8374,8 @@ const MULTIMODAL_VISION_MODELS = new Set([
8141
8374
  'gpt-5-mini',
8142
8375
  'gpt-5-nano',
8143
8376
  'gpt-5.1',
8377
+ 'gpt-5.4',
8378
+ 'gpt-5.4-pro',
8144
8379
  'gpt-5.2',
8145
8380
  'gpt-5.2-pro',
8146
8381
  'gpt-5.1-codex',