@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.
package/dist/index.mjs CHANGED
@@ -1148,6 +1148,8 @@ function isOpenRouterModel(model) {
1148
1148
  'openai/gpt-5-mini',
1149
1149
  'openai/gpt-5-nano',
1150
1150
  'openai/gpt-5.1',
1151
+ 'openai/gpt-5.4',
1152
+ 'openai/gpt-5.4-pro',
1151
1153
  'openai/gpt-5.2',
1152
1154
  'openai/gpt-5.2-pro',
1153
1155
  'openai/gpt-5.1-codex',
@@ -1612,7 +1614,7 @@ const safeJSON = (text) => {
1612
1614
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
1613
1615
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1614
1616
 
1615
- const VERSION = '6.22.0'; // x-release-please-version
1617
+ const VERSION = '6.27.0'; // x-release-please-version
1616
1618
 
1617
1619
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
1618
1620
  const isRunningInBrowser = () => {
@@ -2232,6 +2234,11 @@ function stringify(object, opts = {}) {
2232
2234
  return joined.length > 0 ? prefix + joined : '';
2233
2235
  }
2234
2236
 
2237
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2238
+ function stringifyQuery(query) {
2239
+ return stringify(query, { arrayFormat: 'brackets' });
2240
+ }
2241
+
2235
2242
  function concatBytes(buffers) {
2236
2243
  let length = 0;
2237
2244
  for (const buffer of buffers) {
@@ -2450,7 +2457,7 @@ class Stream {
2450
2457
  this.controller = controller;
2451
2458
  __classPrivateFieldSet(this, _Stream_client, client);
2452
2459
  }
2453
- static fromSSEResponse(response, controller, client) {
2460
+ static fromSSEResponse(response, controller, client, synthesizeEventData) {
2454
2461
  let consumed = false;
2455
2462
  const logger = client ? loggerFor(client) : console;
2456
2463
  async function* iterator() {
@@ -2480,7 +2487,7 @@ class Stream {
2480
2487
  if (data && data.error) {
2481
2488
  throw new APIError(undefined, data.error, undefined, response.headers);
2482
2489
  }
2483
- yield data;
2490
+ yield synthesizeEventData ? { event: sse.event, data } : data;
2484
2491
  }
2485
2492
  else {
2486
2493
  let data;
@@ -2730,9 +2737,9 @@ async function defaultParseResponse(client, props) {
2730
2737
  // Note: there is an invariant here that isn't represented in the type system
2731
2738
  // that if you set `stream: true` the response type must also be `Stream<T>`
2732
2739
  if (props.options.__streamClass) {
2733
- return props.options.__streamClass.fromSSEResponse(response, props.controller, client);
2740
+ return props.options.__streamClass.fromSSEResponse(response, props.controller, client, props.options.__synthesizeEventData);
2734
2741
  }
2735
- return Stream.fromSSEResponse(response, props.controller, client);
2742
+ return Stream.fromSSEResponse(response, props.controller, client, props.options.__synthesizeEventData);
2736
2743
  }
2737
2744
  // fetch refuses to read the body when the status code is 204.
2738
2745
  if (response.status === 204) {
@@ -3285,6 +3292,9 @@ const createPathTagFunction = (pathEncoder = encodeURIPath) => function path(sta
3285
3292
  const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
3286
3293
 
3287
3294
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3295
+ /**
3296
+ * Given a list of messages comprising a conversation, the model will return a response.
3297
+ */
3288
3298
  let Messages$1 = class Messages extends APIResource {
3289
3299
  /**
3290
3300
  * Get the messages in a stored chat completion. Only Chat Completions that have
@@ -4647,6 +4657,9 @@ class ChatCompletionStreamingRunner extends ChatCompletionStream {
4647
4657
  }
4648
4658
 
4649
4659
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4660
+ /**
4661
+ * Given a list of messages comprising a conversation, the model will return a response.
4662
+ */
4650
4663
  let Completions$1 = class Completions extends APIResource {
4651
4664
  constructor() {
4652
4665
  super(...arguments);
@@ -4817,10 +4830,15 @@ const buildHeaders = (newHeaders) => {
4817
4830
  };
4818
4831
 
4819
4832
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4833
+ /**
4834
+ * Turn audio into text or text into audio.
4835
+ */
4820
4836
  class Speech extends APIResource {
4821
4837
  /**
4822
4838
  * Generates audio from the input text.
4823
4839
  *
4840
+ * Returns the audio file content, or a stream of audio events.
4841
+ *
4824
4842
  * @example
4825
4843
  * ```ts
4826
4844
  * const speech = await client.audio.speech.create({
@@ -4844,6 +4862,9 @@ class Speech extends APIResource {
4844
4862
  }
4845
4863
 
4846
4864
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4865
+ /**
4866
+ * Turn audio into text or text into audio.
4867
+ */
4847
4868
  class Transcriptions extends APIResource {
4848
4869
  create(body, options) {
4849
4870
  return this._client.post('/audio/transcriptions', multipartFormRequestOptions({
@@ -4856,6 +4877,9 @@ class Transcriptions extends APIResource {
4856
4877
  }
4857
4878
 
4858
4879
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4880
+ /**
4881
+ * Turn audio into text or text into audio.
4882
+ */
4859
4883
  class Translations extends APIResource {
4860
4884
  create(body, options) {
4861
4885
  return this._client.post('/audio/translations', multipartFormRequestOptions({ body, ...options, __metadata: { model: body.model } }, this._client));
@@ -4876,6 +4900,9 @@ Audio.Translations = Translations;
4876
4900
  Audio.Speech = Speech;
4877
4901
 
4878
4902
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4903
+ /**
4904
+ * Create large batches of API requests to run asynchronously.
4905
+ */
4879
4906
  class Batches extends APIResource {
4880
4907
  /**
4881
4908
  * Creates and executes a batch from an uploaded file of requests
@@ -4906,6 +4933,9 @@ class Batches extends APIResource {
4906
4933
  }
4907
4934
 
4908
4935
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4936
+ /**
4937
+ * Build Assistants that can call models and use tools.
4938
+ */
4909
4939
  class Assistants extends APIResource {
4910
4940
  /**
4911
4941
  * Create an assistant with a model and instructions.
@@ -5036,7 +5066,7 @@ Realtime$1.TranscriptionSessions = TranscriptionSessions;
5036
5066
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5037
5067
  class Sessions extends APIResource {
5038
5068
  /**
5039
- * Create a ChatKit session
5069
+ * Create a ChatKit session.
5040
5070
  *
5041
5071
  * @example
5042
5072
  * ```ts
@@ -5055,7 +5085,9 @@ class Sessions extends APIResource {
5055
5085
  });
5056
5086
  }
5057
5087
  /**
5058
- * Cancel a ChatKit session
5088
+ * Cancel an active ChatKit session and return its most recent metadata.
5089
+ *
5090
+ * Cancelling prevents new requests from using the issued client secret.
5059
5091
  *
5060
5092
  * @example
5061
5093
  * ```ts
@@ -5074,7 +5106,7 @@ class Sessions extends APIResource {
5074
5106
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5075
5107
  let Threads$1 = class Threads extends APIResource {
5076
5108
  /**
5077
- * Retrieve a ChatKit thread
5109
+ * Retrieve a ChatKit thread by its identifier.
5078
5110
  *
5079
5111
  * @example
5080
5112
  * ```ts
@@ -5089,7 +5121,7 @@ let Threads$1 = class Threads extends APIResource {
5089
5121
  });
5090
5122
  }
5091
5123
  /**
5092
- * List ChatKit threads
5124
+ * List ChatKit threads with optional pagination and user filters.
5093
5125
  *
5094
5126
  * @example
5095
5127
  * ```ts
@@ -5107,7 +5139,7 @@ let Threads$1 = class Threads extends APIResource {
5107
5139
  });
5108
5140
  }
5109
5141
  /**
5110
- * Delete a ChatKit thread
5142
+ * Delete a ChatKit thread along with its items and stored attachments.
5111
5143
  *
5112
5144
  * @example
5113
5145
  * ```ts
@@ -5123,7 +5155,7 @@ let Threads$1 = class Threads extends APIResource {
5123
5155
  });
5124
5156
  }
5125
5157
  /**
5126
- * List ChatKit thread items
5158
+ * List items that belong to a ChatKit thread.
5127
5159
  *
5128
5160
  * @example
5129
5161
  * ```ts
@@ -5153,6 +5185,8 @@ ChatKit.Threads = Threads$1;
5153
5185
 
5154
5186
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5155
5187
  /**
5188
+ * Build Assistants that can call models and use tools.
5189
+ *
5156
5190
  * @deprecated The Assistants API is deprecated in favor of the Responses API
5157
5191
  */
5158
5192
  class Messages extends APIResource {
@@ -5221,6 +5255,8 @@ class Messages extends APIResource {
5221
5255
 
5222
5256
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5223
5257
  /**
5258
+ * Build Assistants that can call models and use tools.
5259
+ *
5224
5260
  * @deprecated The Assistants API is deprecated in favor of the Responses API
5225
5261
  */
5226
5262
  class Steps extends APIResource {
@@ -5833,6 +5869,8 @@ _a$1 = AssistantStream, _AssistantStream_addEvent = function _AssistantStream_ad
5833
5869
 
5834
5870
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5835
5871
  /**
5872
+ * Build Assistants that can call models and use tools.
5873
+ *
5836
5874
  * @deprecated The Assistants API is deprecated in favor of the Responses API
5837
5875
  */
5838
5876
  let Runs$1 = class Runs extends APIResource {
@@ -5848,6 +5886,7 @@ let Runs$1 = class Runs extends APIResource {
5848
5886
  ...options,
5849
5887
  headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
5850
5888
  stream: params.stream ?? false,
5889
+ __synthesizeEventData: true,
5851
5890
  });
5852
5891
  }
5853
5892
  /**
@@ -5978,6 +6017,7 @@ let Runs$1 = class Runs extends APIResource {
5978
6017
  ...options,
5979
6018
  headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
5980
6019
  stream: params.stream ?? false,
6020
+ __synthesizeEventData: true,
5981
6021
  });
5982
6022
  }
5983
6023
  /**
@@ -6002,6 +6042,8 @@ Runs$1.Steps = Steps;
6002
6042
 
6003
6043
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6004
6044
  /**
6045
+ * Build Assistants that can call models and use tools.
6046
+ *
6005
6047
  * @deprecated The Assistants API is deprecated in favor of the Responses API
6006
6048
  */
6007
6049
  class Threads extends APIResource {
@@ -6062,6 +6104,7 @@ class Threads extends APIResource {
6062
6104
  ...options,
6063
6105
  headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
6064
6106
  stream: body.stream ?? false,
6107
+ __synthesizeEventData: true,
6065
6108
  });
6066
6109
  }
6067
6110
  /**
@@ -6099,6 +6142,9 @@ Beta.Assistants = Assistants;
6099
6142
  Beta.Threads = Threads;
6100
6143
 
6101
6144
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6145
+ /**
6146
+ * Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.
6147
+ */
6102
6148
  class Completions extends APIResource {
6103
6149
  create(body, options) {
6104
6150
  return this._client.post('/completions', { body, ...options, stream: body.stream ?? false });
@@ -6201,6 +6247,9 @@ class Containers extends APIResource {
6201
6247
  Containers.Files = Files$2;
6202
6248
 
6203
6249
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6250
+ /**
6251
+ * Manage conversations and conversation items.
6252
+ */
6204
6253
  class Items extends APIResource {
6205
6254
  /**
6206
6255
  * Create items in a conversation with the given ID.
@@ -6236,6 +6285,9 @@ class Items extends APIResource {
6236
6285
  }
6237
6286
 
6238
6287
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6288
+ /**
6289
+ * Manage conversations and conversation items.
6290
+ */
6239
6291
  class Conversations extends APIResource {
6240
6292
  constructor() {
6241
6293
  super(...arguments);
@@ -6269,6 +6321,9 @@ class Conversations extends APIResource {
6269
6321
  Conversations.Items = Items;
6270
6322
 
6271
6323
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6324
+ /**
6325
+ * Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms.
6326
+ */
6272
6327
  class Embeddings extends APIResource {
6273
6328
  /**
6274
6329
  * Creates an embedding vector representing the input text.
@@ -6319,6 +6374,9 @@ class Embeddings extends APIResource {
6319
6374
  }
6320
6375
 
6321
6376
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6377
+ /**
6378
+ * Manage and run evals in the OpenAI platform.
6379
+ */
6322
6380
  class OutputItems extends APIResource {
6323
6381
  /**
6324
6382
  * Get an evaluation run output item by ID.
@@ -6337,6 +6395,9 @@ class OutputItems extends APIResource {
6337
6395
  }
6338
6396
 
6339
6397
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6398
+ /**
6399
+ * Manage and run evals in the OpenAI platform.
6400
+ */
6340
6401
  class Runs extends APIResource {
6341
6402
  constructor() {
6342
6403
  super(...arguments);
@@ -6384,6 +6445,9 @@ class Runs extends APIResource {
6384
6445
  Runs.OutputItems = OutputItems;
6385
6446
 
6386
6447
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6448
+ /**
6449
+ * Manage and run evals in the OpenAI platform.
6450
+ */
6387
6451
  class Evals extends APIResource {
6388
6452
  constructor() {
6389
6453
  super(...arguments);
@@ -6428,6 +6492,9 @@ class Evals extends APIResource {
6428
6492
  Evals.Runs = Runs;
6429
6493
 
6430
6494
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6495
+ /**
6496
+ * Files are used to upload documents that can be used with features like Assistants and Fine-tuning.
6497
+ */
6431
6498
  let Files$1 = class Files extends APIResource {
6432
6499
  /**
6433
6500
  * Upload a file that can be used across various endpoints. Individual files can be
@@ -6507,6 +6574,9 @@ class Methods extends APIResource {
6507
6574
  }
6508
6575
 
6509
6576
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6577
+ /**
6578
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
6579
+ */
6510
6580
  let Graders$1 = class Graders extends APIResource {
6511
6581
  /**
6512
6582
  * Run a grader.
@@ -6560,6 +6630,9 @@ class Alpha extends APIResource {
6560
6630
  Alpha.Graders = Graders$1;
6561
6631
 
6562
6632
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6633
+ /**
6634
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
6635
+ */
6563
6636
  class Permissions extends APIResource {
6564
6637
  /**
6565
6638
  * **NOTE:** Calling this endpoint requires an [admin API key](../admin-api-keys).
@@ -6587,13 +6660,7 @@ class Permissions extends APIResource {
6587
6660
  * Organization owners can use this endpoint to view all permissions for a
6588
6661
  * fine-tuned model checkpoint.
6589
6662
  *
6590
- * @example
6591
- * ```ts
6592
- * const permission =
6593
- * await client.fineTuning.checkpoints.permissions.retrieve(
6594
- * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F',
6595
- * );
6596
- * ```
6663
+ * @deprecated Retrieve is deprecated. Please swap to the paginated list method instead.
6597
6664
  */
6598
6665
  retrieve(fineTunedModelCheckpoint, query = {}, options) {
6599
6666
  return this._client.get(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, {
@@ -6601,6 +6668,25 @@ class Permissions extends APIResource {
6601
6668
  ...options,
6602
6669
  });
6603
6670
  }
6671
+ /**
6672
+ * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys).
6673
+ *
6674
+ * Organization owners can use this endpoint to view all permissions for a
6675
+ * fine-tuned model checkpoint.
6676
+ *
6677
+ * @example
6678
+ * ```ts
6679
+ * // Automatically fetches more pages as needed.
6680
+ * for await (const permissionListResponse of client.fineTuning.checkpoints.permissions.list(
6681
+ * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F',
6682
+ * )) {
6683
+ * // ...
6684
+ * }
6685
+ * ```
6686
+ */
6687
+ list(fineTunedModelCheckpoint, query = {}, options) {
6688
+ return this._client.getAPIList(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, (ConversationCursorPage), { query, ...options });
6689
+ }
6604
6690
  /**
6605
6691
  * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys).
6606
6692
  *
@@ -6635,6 +6721,9 @@ let Checkpoints$1 = class Checkpoints extends APIResource {
6635
6721
  Checkpoints$1.Permissions = Permissions;
6636
6722
 
6637
6723
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6724
+ /**
6725
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
6726
+ */
6638
6727
  class Checkpoints extends APIResource {
6639
6728
  /**
6640
6729
  * List checkpoints for a fine-tuning job.
@@ -6655,6 +6744,9 @@ class Checkpoints extends APIResource {
6655
6744
  }
6656
6745
 
6657
6746
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6747
+ /**
6748
+ * Manage fine-tuning jobs to tailor a model to your specific training data.
6749
+ */
6658
6750
  class Jobs extends APIResource {
6659
6751
  constructor() {
6660
6752
  super(...arguments);
@@ -6796,6 +6888,9 @@ class Graders extends APIResource {
6796
6888
  Graders.GraderModels = GraderModels;
6797
6889
 
6798
6890
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6891
+ /**
6892
+ * Given a prompt and/or an input image, the model will generate a new image.
6893
+ */
6799
6894
  class Images extends APIResource {
6800
6895
  /**
6801
6896
  * Creates a variation of a given image. This endpoint only supports `dall-e-2`.
@@ -6819,6 +6914,9 @@ class Images extends APIResource {
6819
6914
  }
6820
6915
 
6821
6916
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6917
+ /**
6918
+ * List and describe the various models available in the API.
6919
+ */
6822
6920
  class Models extends APIResource {
6823
6921
  /**
6824
6922
  * Retrieves a model instance, providing basic information about the model such as
@@ -6844,6 +6942,9 @@ class Models extends APIResource {
6844
6942
  }
6845
6943
 
6846
6944
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6945
+ /**
6946
+ * Given text and/or image inputs, classifies if those inputs are potentially harmful.
6947
+ */
6847
6948
  class Moderations extends APIResource {
6848
6949
  /**
6849
6950
  * Classifies if text and/or image inputs are potentially harmful. Learn more in
@@ -6927,6 +7028,20 @@ class ClientSecrets extends APIResource {
6927
7028
  /**
6928
7029
  * Create a Realtime client secret with an associated session configuration.
6929
7030
  *
7031
+ * Client secrets are short-lived tokens that can be passed to a client app, such
7032
+ * as a web frontend or mobile client, which grants access to the Realtime API
7033
+ * without leaking your main API key. You can configure a custom TTL for each
7034
+ * client secret.
7035
+ *
7036
+ * You can also attach session configuration options to the client secret, which
7037
+ * will be applied to any sessions created using that client secret, but these can
7038
+ * also be overridden by the client connection.
7039
+ *
7040
+ * [Learn more about authentication with client secrets over WebRTC](https://platform.openai.com/docs/guides/realtime-webrtc).
7041
+ *
7042
+ * Returns the created client secret and the effective session object. The client
7043
+ * secret is a string that looks like `ek_1234`.
7044
+ *
6930
7045
  * @example
6931
7046
  * ```ts
6932
7047
  * const clientSecret =
@@ -7352,7 +7467,10 @@ class InputItems extends APIResource {
7352
7467
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
7353
7468
  class InputTokens extends APIResource {
7354
7469
  /**
7355
- * Get input token counts
7470
+ * Returns input token counts of the request.
7471
+ *
7472
+ * Returns an object with `object` set to `response.input_tokens` and an
7473
+ * `input_tokens` count.
7356
7474
  *
7357
7475
  * @example
7358
7476
  * ```ts
@@ -7434,12 +7552,17 @@ class Responses extends APIResource {
7434
7552
  return this._client.post(path `/responses/${responseID}/cancel`, options);
7435
7553
  }
7436
7554
  /**
7437
- * Compact conversation
7555
+ * Compact a conversation. Returns a compacted response object.
7556
+ *
7557
+ * Learn when and how to compact long-running conversations in the
7558
+ * [conversation state guide](https://platform.openai.com/docs/guides/conversation-state#managing-the-context-window).
7559
+ * For ZDR-compatible compaction details, see
7560
+ * [Compaction (advanced)](https://platform.openai.com/docs/guides/conversation-state#compaction-advanced).
7438
7561
  *
7439
7562
  * @example
7440
7563
  * ```ts
7441
7564
  * const compactedResponse = await client.responses.compact({
7442
- * model: 'gpt-5.2',
7565
+ * model: 'gpt-5.4',
7443
7566
  * });
7444
7567
  * ```
7445
7568
  */
@@ -7453,7 +7576,7 @@ Responses.InputTokens = InputTokens;
7453
7576
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
7454
7577
  let Content$1 = class Content extends APIResource {
7455
7578
  /**
7456
- * Get Skill Content
7579
+ * Download a skill zip bundle by its ID.
7457
7580
  */
7458
7581
  retrieve(skillID, options) {
7459
7582
  return this._client.get(path `/skills/${skillID}/content`, {
@@ -7467,7 +7590,7 @@ let Content$1 = class Content extends APIResource {
7467
7590
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
7468
7591
  class Content extends APIResource {
7469
7592
  /**
7470
- * Get Skill Version Content
7593
+ * Download a skill version zip bundle.
7471
7594
  */
7472
7595
  retrieve(version, params, options) {
7473
7596
  const { skill_id } = params;
@@ -7486,20 +7609,20 @@ class Versions extends APIResource {
7486
7609
  this.content = new Content(this._client);
7487
7610
  }
7488
7611
  /**
7489
- * Create Skill Version
7612
+ * Create a new immutable skill version.
7490
7613
  */
7491
7614
  create(skillID, body = {}, options) {
7492
7615
  return this._client.post(path `/skills/${skillID}/versions`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
7493
7616
  }
7494
7617
  /**
7495
- * Get Skill Version
7618
+ * Get a specific skill version.
7496
7619
  */
7497
7620
  retrieve(version, params, options) {
7498
7621
  const { skill_id } = params;
7499
7622
  return this._client.get(path `/skills/${skill_id}/versions/${version}`, options);
7500
7623
  }
7501
7624
  /**
7502
- * List Skill Versions
7625
+ * List skill versions for a skill.
7503
7626
  */
7504
7627
  list(skillID, query = {}, options) {
7505
7628
  return this._client.getAPIList(path `/skills/${skillID}/versions`, (CursorPage), {
@@ -7508,7 +7631,7 @@ class Versions extends APIResource {
7508
7631
  });
7509
7632
  }
7510
7633
  /**
7511
- * Delete Skill Version
7634
+ * Delete a skill version.
7512
7635
  */
7513
7636
  delete(version, params, options) {
7514
7637
  const { skill_id } = params;
@@ -7525,31 +7648,31 @@ class Skills extends APIResource {
7525
7648
  this.versions = new Versions(this._client);
7526
7649
  }
7527
7650
  /**
7528
- * Create Skill
7651
+ * Create a new skill.
7529
7652
  */
7530
7653
  create(body = {}, options) {
7531
7654
  return this._client.post('/skills', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
7532
7655
  }
7533
7656
  /**
7534
- * Get Skill
7657
+ * Get a skill by its ID.
7535
7658
  */
7536
7659
  retrieve(skillID, options) {
7537
7660
  return this._client.get(path `/skills/${skillID}`, options);
7538
7661
  }
7539
7662
  /**
7540
- * Update Skill Default Version
7663
+ * Update the default version pointer for a skill.
7541
7664
  */
7542
7665
  update(skillID, body, options) {
7543
7666
  return this._client.post(path `/skills/${skillID}`, { body, ...options });
7544
7667
  }
7545
7668
  /**
7546
- * List Skills
7669
+ * List all skills for the current project.
7547
7670
  */
7548
7671
  list(query = {}, options) {
7549
7672
  return this._client.getAPIList('/skills', (CursorPage), { query, ...options });
7550
7673
  }
7551
7674
  /**
7552
- * Delete Skill
7675
+ * Delete a skill by its ID.
7553
7676
  */
7554
7677
  delete(skillID, options) {
7555
7678
  return this._client.delete(path `/skills/${skillID}`, options);
@@ -7559,6 +7682,9 @@ Skills.Content = Content$1;
7559
7682
  Skills.Versions = Versions;
7560
7683
 
7561
7684
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
7685
+ /**
7686
+ * Use Uploads to upload large files in multiple parts.
7687
+ */
7562
7688
  class Parts extends APIResource {
7563
7689
  /**
7564
7690
  * Adds a
@@ -7579,6 +7705,9 @@ class Parts extends APIResource {
7579
7705
  }
7580
7706
 
7581
7707
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
7708
+ /**
7709
+ * Use Uploads to upload large files in multiple parts.
7710
+ */
7582
7711
  class Uploads extends APIResource {
7583
7712
  constructor() {
7584
7713
  super(...arguments);
@@ -7604,12 +7733,16 @@ class Uploads extends APIResource {
7604
7733
  * For guidance on the proper filename extensions for each purpose, please follow
7605
7734
  * the documentation on
7606
7735
  * [creating a File](https://platform.openai.com/docs/api-reference/files/create).
7736
+ *
7737
+ * Returns the Upload object with status `pending`.
7607
7738
  */
7608
7739
  create(body, options) {
7609
7740
  return this._client.post('/uploads', { body, ...options });
7610
7741
  }
7611
7742
  /**
7612
7743
  * Cancels the Upload. No Parts may be added after an Upload is cancelled.
7744
+ *
7745
+ * Returns the Upload object with status `cancelled`.
7613
7746
  */
7614
7747
  cancel(uploadID, options) {
7615
7748
  return this._client.post(path `/uploads/${uploadID}/cancel`, options);
@@ -7627,7 +7760,9 @@ class Uploads extends APIResource {
7627
7760
  *
7628
7761
  * The number of bytes uploaded upon completion must match the number of bytes
7629
7762
  * initially specified when creating the Upload object. No Parts may be added after
7630
- * an Upload is completed.
7763
+ * an Upload is completed. Returns the Upload object with status `completed`,
7764
+ * including an additional `file` property containing the created usable File
7765
+ * object.
7631
7766
  */
7632
7767
  complete(uploadID, body, options) {
7633
7768
  return this._client.post(path `/uploads/${uploadID}/complete`, { body, ...options });
@@ -7987,31 +8122,33 @@ VectorStores.FileBatches = FileBatches;
7987
8122
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
7988
8123
  class Videos extends APIResource {
7989
8124
  /**
7990
- * Create a video
8125
+ * Create a new video generation job from a prompt and optional reference assets.
7991
8126
  */
7992
8127
  create(body, options) {
7993
8128
  return this._client.post('/videos', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
7994
8129
  }
7995
8130
  /**
7996
- * Retrieve a video
8131
+ * Fetch the latest metadata for a generated video.
7997
8132
  */
7998
8133
  retrieve(videoID, options) {
7999
8134
  return this._client.get(path `/videos/${videoID}`, options);
8000
8135
  }
8001
8136
  /**
8002
- * List videos
8137
+ * List recently generated videos for the current project.
8003
8138
  */
8004
8139
  list(query = {}, options) {
8005
8140
  return this._client.getAPIList('/videos', (ConversationCursorPage), { query, ...options });
8006
8141
  }
8007
8142
  /**
8008
- * Delete a video
8143
+ * Permanently delete a completed or failed video and its stored assets.
8009
8144
  */
8010
8145
  delete(videoID, options) {
8011
8146
  return this._client.delete(path `/videos/${videoID}`, options);
8012
8147
  }
8013
8148
  /**
8014
- * Download video content
8149
+ * Download the generated video bytes or a derived preview asset.
8150
+ *
8151
+ * Streams the rendered video content for the specified video job.
8015
8152
  */
8016
8153
  downloadContent(videoID, query = {}, options) {
8017
8154
  return this._client.get(path `/videos/${videoID}/content`, {
@@ -8022,7 +8159,7 @@ class Videos extends APIResource {
8022
8159
  });
8023
8160
  }
8024
8161
  /**
8025
- * Create a video remix
8162
+ * Create a remix of a completed video using a refreshed prompt.
8026
8163
  */
8027
8164
  remix(videoID, body, options) {
8028
8165
  return this._client.post(path `/videos/${videoID}/remix`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
@@ -8147,24 +8284,54 @@ class OpenAI {
8147
8284
  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 } = {}) {
8148
8285
  _OpenAI_instances.add(this);
8149
8286
  _OpenAI_encoder.set(this, void 0);
8287
+ /**
8288
+ * Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.
8289
+ */
8150
8290
  this.completions = new Completions(this);
8151
8291
  this.chat = new Chat(this);
8292
+ /**
8293
+ * Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms.
8294
+ */
8152
8295
  this.embeddings = new Embeddings(this);
8296
+ /**
8297
+ * Files are used to upload documents that can be used with features like Assistants and Fine-tuning.
8298
+ */
8153
8299
  this.files = new Files$1(this);
8300
+ /**
8301
+ * Given a prompt and/or an input image, the model will generate a new image.
8302
+ */
8154
8303
  this.images = new Images(this);
8155
8304
  this.audio = new Audio(this);
8305
+ /**
8306
+ * Given text and/or image inputs, classifies if those inputs are potentially harmful.
8307
+ */
8156
8308
  this.moderations = new Moderations(this);
8309
+ /**
8310
+ * List and describe the various models available in the API.
8311
+ */
8157
8312
  this.models = new Models(this);
8158
8313
  this.fineTuning = new FineTuning(this);
8159
8314
  this.graders = new Graders(this);
8160
8315
  this.vectorStores = new VectorStores(this);
8161
8316
  this.webhooks = new Webhooks(this);
8162
8317
  this.beta = new Beta(this);
8318
+ /**
8319
+ * Create large batches of API requests to run asynchronously.
8320
+ */
8163
8321
  this.batches = new Batches(this);
8322
+ /**
8323
+ * Use Uploads to upload large files in multiple parts.
8324
+ */
8164
8325
  this.uploads = new Uploads(this);
8165
8326
  this.responses = new Responses(this);
8166
8327
  this.realtime = new Realtime(this);
8328
+ /**
8329
+ * Manage conversations and conversation items.
8330
+ */
8167
8331
  this.conversations = new Conversations(this);
8332
+ /**
8333
+ * Manage and run evals in the OpenAI platform.
8334
+ */
8168
8335
  this.evals = new Evals(this);
8169
8336
  this.containers = new Containers(this);
8170
8337
  this.skills = new Skills(this);
@@ -8234,7 +8401,7 @@ class OpenAI {
8234
8401
  return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
8235
8402
  }
8236
8403
  stringifyQuery(query) {
8237
- return stringify(query, { arrayFormat: 'brackets' });
8404
+ return stringifyQuery(query);
8238
8405
  }
8239
8406
  getUserAgent() {
8240
8407
  return `${this.constructor.name}/JS ${VERSION}`;
@@ -8503,9 +8670,9 @@ class OpenAI {
8503
8670
  timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
8504
8671
  }
8505
8672
  }
8506
- // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
8507
- // just do what it says, but otherwise calculate a default
8508
- if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
8673
+ // If the API asks us to wait a certain amount of time, just do what it
8674
+ // says, but otherwise calculate a default
8675
+ if (timeoutMillis === undefined) {
8509
8676
  const maxRetries = options.maxRetries ?? this.maxRetries;
8510
8677
  timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
8511
8678
  }
@@ -8602,6 +8769,13 @@ class OpenAI {
8602
8769
  (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
8603
8770
  return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
8604
8771
  }
8772
+ else if (typeof body === 'object' &&
8773
+ headers.values.get('content-type') === 'application/x-www-form-urlencoded') {
8774
+ return {
8775
+ bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
8776
+ body: this.stringifyQuery(body),
8777
+ };
8778
+ }
8605
8779
  else {
8606
8780
  return __classPrivateFieldGet(this, _OpenAI_encoder, "f").call(this, { body, headers });
8607
8781
  }
@@ -8652,78 +8826,107 @@ OpenAI.Videos = Videos;
8652
8826
 
8653
8827
  // llm-openai-config.ts
8654
8828
  const DEFAULT_MODEL = 'gpt-4.1-mini';
8655
- /** Token costs in USD per 1M tokens. Last updated Feb 2025. */
8829
+ const GPT_5_4_HIGH_CONTEXT_THRESHOLD_TOKENS = 272_000;
8830
+ const GPT_5_4_HIGH_CONTEXT_INPUT_MULTIPLIER = 2;
8831
+ const GPT_5_4_HIGH_CONTEXT_OUTPUT_MULTIPLIER = 1.5;
8832
+ /** Token costs in USD per 1M tokens. Last updated Mar 2026. */
8656
8833
  const openAiModelCosts = {
8657
8834
  'gpt-4o': {
8658
8835
  inputCost: 2.5 / 1_000_000,
8836
+ cacheHitCost: 1.25 / 1_000_000,
8659
8837
  outputCost: 10 / 1_000_000,
8660
8838
  },
8661
8839
  'gpt-4o-mini': {
8662
8840
  inputCost: 0.15 / 1_000_000,
8841
+ cacheHitCost: 0.075 / 1_000_000,
8663
8842
  outputCost: 0.6 / 1_000_000,
8664
8843
  },
8665
8844
  'o1-mini': {
8666
8845
  inputCost: 1.1 / 1_000_000,
8846
+ cacheHitCost: 0.55 / 1_000_000,
8667
8847
  outputCost: 4.4 / 1_000_000,
8668
8848
  },
8669
8849
  'o1': {
8670
8850
  inputCost: 15 / 1_000_000,
8851
+ cacheHitCost: 7.5 / 1_000_000,
8671
8852
  outputCost: 60 / 1_000_000,
8672
8853
  },
8673
8854
  'o3-mini': {
8674
8855
  inputCost: 1.1 / 1_000_000,
8856
+ cacheHitCost: 0.55 / 1_000_000,
8675
8857
  outputCost: 4.4 / 1_000_000,
8676
8858
  },
8677
8859
  'o3': {
8678
8860
  inputCost: 2 / 1_000_000,
8861
+ cacheHitCost: 0.5 / 1_000_000,
8679
8862
  outputCost: 8 / 1_000_000,
8680
8863
  },
8681
8864
  'gpt-4.1': {
8682
8865
  inputCost: 2 / 1_000_000,
8866
+ cacheHitCost: 0.5 / 1_000_000,
8683
8867
  outputCost: 8 / 1_000_000,
8684
8868
  },
8685
8869
  'gpt-4.1-mini': {
8686
8870
  inputCost: 0.4 / 1_000_000,
8871
+ cacheHitCost: 0.1 / 1_000_000,
8687
8872
  outputCost: 1.6 / 1_000_000,
8688
8873
  },
8689
8874
  'gpt-4.1-nano': {
8690
8875
  inputCost: 0.1 / 1_000_000,
8876
+ cacheHitCost: 0.025 / 1_000_000,
8691
8877
  outputCost: 0.4 / 1_000_000,
8692
8878
  },
8693
8879
  'gpt-5': {
8694
8880
  inputCost: 1.25 / 1_000_000,
8881
+ cacheHitCost: 0.125 / 1_000_000,
8695
8882
  outputCost: 10 / 1_000_000,
8696
8883
  },
8697
8884
  'gpt-5-mini': {
8698
8885
  inputCost: 0.25 / 1_000_000,
8886
+ cacheHitCost: 0.025 / 1_000_000,
8699
8887
  outputCost: 2 / 1_000_000,
8700
8888
  },
8701
8889
  'gpt-5-nano': {
8702
8890
  inputCost: 0.05 / 1_000_000,
8891
+ cacheHitCost: 0.005 / 1_000_000,
8703
8892
  outputCost: 0.4 / 1_000_000,
8704
8893
  },
8705
8894
  'gpt-5.1': {
8706
8895
  inputCost: 1.25 / 1_000_000,
8896
+ cacheHitCost: 0.125 / 1_000_000,
8707
8897
  outputCost: 10 / 1_000_000,
8708
8898
  },
8899
+ 'gpt-5.4': {
8900
+ inputCost: 2.5 / 1_000_000,
8901
+ cacheHitCost: 0.25 / 1_000_000,
8902
+ outputCost: 15 / 1_000_000,
8903
+ },
8904
+ 'gpt-5.4-pro': {
8905
+ inputCost: 30 / 1_000_000,
8906
+ outputCost: 180 / 1_000_000,
8907
+ },
8709
8908
  'gpt-5.2': {
8710
- inputCost: 1.5 / 1_000_000,
8711
- outputCost: 12 / 1_000_000,
8909
+ inputCost: 1.75 / 1_000_000,
8910
+ cacheHitCost: 0.175 / 1_000_000,
8911
+ outputCost: 14 / 1_000_000,
8712
8912
  },
8713
8913
  'gpt-5.2-pro': {
8714
- inputCost: 3 / 1_000_000,
8715
- outputCost: 24 / 1_000_000,
8914
+ inputCost: 21 / 1_000_000,
8915
+ outputCost: 168 / 1_000_000,
8716
8916
  },
8717
8917
  'gpt-5.1-codex': {
8718
- inputCost: 1.1 / 1_000_000,
8719
- outputCost: 8.8 / 1_000_000,
8918
+ inputCost: 1.25 / 1_000_000,
8919
+ cacheHitCost: 0.125 / 1_000_000,
8920
+ outputCost: 10 / 1_000_000,
8720
8921
  },
8721
8922
  'gpt-5.1-codex-max': {
8722
- inputCost: 1.8 / 1_000_000,
8723
- outputCost: 14.4 / 1_000_000,
8923
+ inputCost: 1.25 / 1_000_000,
8924
+ cacheHitCost: 0.125 / 1_000_000,
8925
+ outputCost: 10 / 1_000_000,
8724
8926
  },
8725
8927
  'o4-mini': {
8726
8928
  inputCost: 1.1 / 1_000_000,
8929
+ cacheHitCost: 0.275 / 1_000_000,
8727
8930
  outputCost: 4.4 / 1_000_000,
8728
8931
  },
8729
8932
  };
@@ -8739,6 +8942,9 @@ const deepseekModelCosts = {
8739
8942
  outputCost: 2.19 / 1_000_000, // $2.19 per 1M tokens
8740
8943
  },
8741
8944
  };
8945
+ function shouldUseGPT54HighContextPricing(model, inputTokens) {
8946
+ return (model === 'gpt-5.4' || model === 'gpt-5.4-pro') && inputTokens > GPT_5_4_HIGH_CONTEXT_THRESHOLD_TOKENS;
8947
+ }
8742
8948
  /** Image generation costs in USD per image. Based on OpenAI pricing as of Feb 2025. */
8743
8949
  const openAiImageCosts = {
8744
8950
  'gpt-image-1': 0.0075, // $0.0075 per image for gpt-image-1
@@ -8767,8 +8973,8 @@ function calculateImageCost(model, imageCount) {
8767
8973
  * @param model The name of the language model. Supported models are listed in the `openAiModelCosts` and `deepseekModelCosts` objects.
8768
8974
  * @param inputTokens The number of input tokens passed to the language model.
8769
8975
  * @param outputTokens The number of output tokens generated by the language model.
8770
- * @param reasoningTokens The number of output tokens generated by the language model for reasoning. This is only used for Deepseek models.
8771
- * @param cacheHitTokens The number of input tokens that were cache hits for Deepseek models.
8976
+ * @param reasoningTokens The number of output tokens generated by the language model for reasoning.
8977
+ * @param cacheHitTokens The number of input tokens billed at cached-input rates.
8772
8978
  * @returns The cost of calling the language model in USD.
8773
8979
  */
8774
8980
  function calculateCost(provider, model, inputTokens, outputTokens, reasoningTokens, cacheHitTokens) {
@@ -8783,12 +8989,18 @@ function calculateCost(provider, model, inputTokens, outputTokens, reasoningToke
8783
8989
  const modelCosts = provider === 'deepseek' ? deepseekModelCosts[model] : openAiModelCosts[model];
8784
8990
  if (!modelCosts)
8785
8991
  return 0;
8786
- // Calculate input cost based on cache hit/miss for Deepseek
8787
- const inputCost = provider === 'deepseek' && modelCosts.cacheHitCost
8788
- ? (cacheHitTokens || 0) * modelCosts.cacheHitCost + (inputTokens - (cacheHitTokens || 0)) * modelCosts.inputCost
8789
- : inputTokens * modelCosts.inputCost;
8790
- const outputCost = outputTokens * modelCosts.outputCost;
8791
- const reasoningCost = (reasoningTokens || 0) * modelCosts.outputCost;
8992
+ const boundedCacheHitTokens = Math.min(Math.max(cacheHitTokens || 0, 0), inputTokens);
8993
+ let inputCost = inputTokens * modelCosts.inputCost;
8994
+ if (typeof modelCosts.cacheHitCost === 'number' && boundedCacheHitTokens > 0) {
8995
+ inputCost = boundedCacheHitTokens * modelCosts.cacheHitCost + (inputTokens - boundedCacheHitTokens) * modelCosts.inputCost;
8996
+ }
8997
+ let outputCost = outputTokens * modelCosts.outputCost;
8998
+ let reasoningCost = (reasoningTokens || 0) * modelCosts.outputCost;
8999
+ if (provider === 'openai' && shouldUseGPT54HighContextPricing(model, inputTokens)) {
9000
+ inputCost *= GPT_5_4_HIGH_CONTEXT_INPUT_MULTIPLIER;
9001
+ outputCost *= GPT_5_4_HIGH_CONTEXT_OUTPUT_MULTIPLIER;
9002
+ reasoningCost *= GPT_5_4_HIGH_CONTEXT_OUTPUT_MULTIPLIER;
9003
+ }
8792
9004
  return inputCost + outputCost + reasoningCost;
8793
9005
  }
8794
9006
 
@@ -9186,6 +9398,8 @@ const isSupportedModel = (model) => {
9186
9398
  'gpt-5-mini',
9187
9399
  'gpt-5-nano',
9188
9400
  'gpt-5.1',
9401
+ 'gpt-5.4',
9402
+ 'gpt-5.4-pro',
9189
9403
  'gpt-5.2',
9190
9404
  'gpt-5.2-pro',
9191
9405
  'gpt-5.1-codex',
@@ -9212,6 +9426,8 @@ function supportsTemperature(model) {
9212
9426
  'gpt-5-mini',
9213
9427
  'gpt-5-nano',
9214
9428
  'gpt-5.1',
9429
+ 'gpt-5.4',
9430
+ 'gpt-5.4-pro',
9215
9431
  'gpt-5.2',
9216
9432
  'gpt-5.2-pro',
9217
9433
  'gpt-5.1-codex',
@@ -9239,6 +9455,8 @@ function isGPT5Model(model) {
9239
9455
  'gpt-5-mini',
9240
9456
  'gpt-5-nano',
9241
9457
  'gpt-5.1',
9458
+ 'gpt-5.4',
9459
+ 'gpt-5.4-pro',
9242
9460
  'gpt-5.2',
9243
9461
  'gpt-5.2-pro',
9244
9462
  'gpt-5.1-codex',
@@ -9246,6 +9464,12 @@ function isGPT5Model(model) {
9246
9464
  ];
9247
9465
  return gpt5Models.includes(model);
9248
9466
  }
9467
+ function supportsStructuredOutputs(model) {
9468
+ return normalizeModelName(model) !== 'gpt-5.4-pro';
9469
+ }
9470
+ function supportsDistillation(model) {
9471
+ return normalizeModelName(model) !== 'gpt-5.4-pro';
9472
+ }
9249
9473
  /**
9250
9474
  * Makes a call to OpenAI's Responses API for more advanced use cases with built-in tools.
9251
9475
  *
@@ -9288,8 +9512,15 @@ const makeResponsesAPICall = async (input, options = {}) => {
9288
9512
  input,
9289
9513
  ...cleanOptions,
9290
9514
  };
9515
+ if (requestBody.text?.format?.type === 'json_schema' && !supportsStructuredOutputs(normalizedModel)) {
9516
+ throw new Error(`Model ${normalizedModel} does not support structured outputs`);
9517
+ }
9518
+ if (requestBody.store && !supportsDistillation(normalizedModel)) {
9519
+ throw new Error(`Model ${normalizedModel} does not support distillation`);
9520
+ }
9291
9521
  // Make the API call to the Responses endpoint
9292
9522
  const response = await openai.responses.create(requestBody);
9523
+ const cacheHitTokens = response.usage?.input_tokens_details?.cached_tokens || 0;
9293
9524
  // Extract tool calls from the output
9294
9525
  const toolCalls = response.output
9295
9526
  ?.filter((item) => item.type === 'function_call')
@@ -9329,7 +9560,8 @@ const makeResponsesAPICall = async (input, options = {}) => {
9329
9560
  reasoning_tokens: response.usage?.output_tokens_details?.reasoning_tokens || 0,
9330
9561
  provider: 'openai',
9331
9562
  model: normalizedModel,
9332
- cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0),
9563
+ cache_hit_tokens: cacheHitTokens,
9564
+ cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0, cacheHitTokens),
9333
9565
  },
9334
9566
  tool_calls: toolCalls,
9335
9567
  ...(codeInterpreterOutputs ? { code_interpreter_outputs: codeInterpreterOutputs } : {}),
@@ -9361,7 +9593,8 @@ const makeResponsesAPICall = async (input, options = {}) => {
9361
9593
  reasoning_tokens: response.usage?.output_tokens_details?.reasoning_tokens || 0,
9362
9594
  provider: 'openai',
9363
9595
  model: normalizedModel,
9364
- cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0),
9596
+ cache_hit_tokens: cacheHitTokens,
9597
+ cost: calculateCost('openai', normalizedModel, response.usage?.input_tokens || 0, response.usage?.output_tokens || 0, response.usage?.output_tokens_details?.reasoning_tokens || 0, cacheHitTokens),
9365
9598
  },
9366
9599
  tool_calls: toolCalls,
9367
9600
  ...(codeInterpreterOutputs ? { code_interpreter_outputs: codeInterpreterOutputs } : {}),
@@ -9493,6 +9726,8 @@ const MULTIMODAL_VISION_MODELS = new Set([
9493
9726
  'gpt-5-mini',
9494
9727
  'gpt-5-nano',
9495
9728
  'gpt-5.1',
9729
+ 'gpt-5.4',
9730
+ 'gpt-5.4-pro',
9496
9731
  'gpt-5.2',
9497
9732
  'gpt-5.2-pro',
9498
9733
  'gpt-5.1-codex',