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