@discomedia/utils 1.0.61 → 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',
@@ -7472,78 +7474,107 @@ OpenAI.Videos = Videos;
7472
7474
 
7473
7475
  // llm-openai-config.ts
7474
7476
  const DEFAULT_MODEL = 'gpt-4.1-mini';
7475
- /** 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. */
7476
7481
  const openAiModelCosts = {
7477
7482
  'gpt-4o': {
7478
7483
  inputCost: 2.5 / 1_000_000,
7484
+ cacheHitCost: 1.25 / 1_000_000,
7479
7485
  outputCost: 10 / 1_000_000,
7480
7486
  },
7481
7487
  'gpt-4o-mini': {
7482
7488
  inputCost: 0.15 / 1_000_000,
7489
+ cacheHitCost: 0.075 / 1_000_000,
7483
7490
  outputCost: 0.6 / 1_000_000,
7484
7491
  },
7485
7492
  'o1-mini': {
7486
7493
  inputCost: 1.1 / 1_000_000,
7494
+ cacheHitCost: 0.55 / 1_000_000,
7487
7495
  outputCost: 4.4 / 1_000_000,
7488
7496
  },
7489
7497
  'o1': {
7490
7498
  inputCost: 15 / 1_000_000,
7499
+ cacheHitCost: 7.5 / 1_000_000,
7491
7500
  outputCost: 60 / 1_000_000,
7492
7501
  },
7493
7502
  'o3-mini': {
7494
7503
  inputCost: 1.1 / 1_000_000,
7504
+ cacheHitCost: 0.55 / 1_000_000,
7495
7505
  outputCost: 4.4 / 1_000_000,
7496
7506
  },
7497
7507
  'o3': {
7498
7508
  inputCost: 2 / 1_000_000,
7509
+ cacheHitCost: 0.5 / 1_000_000,
7499
7510
  outputCost: 8 / 1_000_000,
7500
7511
  },
7501
7512
  'gpt-4.1': {
7502
7513
  inputCost: 2 / 1_000_000,
7514
+ cacheHitCost: 0.5 / 1_000_000,
7503
7515
  outputCost: 8 / 1_000_000,
7504
7516
  },
7505
7517
  'gpt-4.1-mini': {
7506
7518
  inputCost: 0.4 / 1_000_000,
7519
+ cacheHitCost: 0.1 / 1_000_000,
7507
7520
  outputCost: 1.6 / 1_000_000,
7508
7521
  },
7509
7522
  'gpt-4.1-nano': {
7510
7523
  inputCost: 0.1 / 1_000_000,
7524
+ cacheHitCost: 0.025 / 1_000_000,
7511
7525
  outputCost: 0.4 / 1_000_000,
7512
7526
  },
7513
7527
  'gpt-5': {
7514
7528
  inputCost: 1.25 / 1_000_000,
7529
+ cacheHitCost: 0.125 / 1_000_000,
7515
7530
  outputCost: 10 / 1_000_000,
7516
7531
  },
7517
7532
  'gpt-5-mini': {
7518
7533
  inputCost: 0.25 / 1_000_000,
7534
+ cacheHitCost: 0.025 / 1_000_000,
7519
7535
  outputCost: 2 / 1_000_000,
7520
7536
  },
7521
7537
  'gpt-5-nano': {
7522
7538
  inputCost: 0.05 / 1_000_000,
7539
+ cacheHitCost: 0.005 / 1_000_000,
7523
7540
  outputCost: 0.4 / 1_000_000,
7524
7541
  },
7525
7542
  'gpt-5.1': {
7526
7543
  inputCost: 1.25 / 1_000_000,
7544
+ cacheHitCost: 0.125 / 1_000_000,
7527
7545
  outputCost: 10 / 1_000_000,
7528
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
+ },
7529
7556
  'gpt-5.2': {
7530
- inputCost: 1.5 / 1_000_000,
7531
- 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,
7532
7560
  },
7533
7561
  'gpt-5.2-pro': {
7534
- inputCost: 3 / 1_000_000,
7535
- outputCost: 24 / 1_000_000,
7562
+ inputCost: 21 / 1_000_000,
7563
+ outputCost: 168 / 1_000_000,
7536
7564
  },
7537
7565
  'gpt-5.1-codex': {
7538
- inputCost: 1.1 / 1_000_000,
7539
- 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,
7540
7569
  },
7541
7570
  'gpt-5.1-codex-max': {
7542
- inputCost: 1.8 / 1_000_000,
7543
- 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,
7544
7574
  },
7545
7575
  'o4-mini': {
7546
7576
  inputCost: 1.1 / 1_000_000,
7577
+ cacheHitCost: 0.275 / 1_000_000,
7547
7578
  outputCost: 4.4 / 1_000_000,
7548
7579
  },
7549
7580
  };
@@ -7559,6 +7590,9 @@ const deepseekModelCosts = {
7559
7590
  outputCost: 2.19 / 1_000_000, // $2.19 per 1M tokens
7560
7591
  },
7561
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
+ }
7562
7596
  /** Image generation costs in USD per image. Based on OpenAI pricing as of Feb 2025. */
7563
7597
  const openAiImageCosts = {
7564
7598
  'gpt-image-1': 0.0075, // $0.0075 per image for gpt-image-1
@@ -7587,8 +7621,8 @@ function calculateImageCost(model, imageCount) {
7587
7621
  * @param model The name of the language model. Supported models are listed in the `openAiModelCosts` and `deepseekModelCosts` objects.
7588
7622
  * @param inputTokens The number of input tokens passed to the language model.
7589
7623
  * @param outputTokens The number of output tokens generated by the language model.
7590
- * @param reasoningTokens The number of output tokens generated by the language model for reasoning. This is only used for Deepseek models.
7591
- * @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.
7592
7626
  * @returns The cost of calling the language model in USD.
7593
7627
  */
7594
7628
  function calculateCost(provider, model, inputTokens, outputTokens, reasoningTokens, cacheHitTokens) {
@@ -7603,12 +7637,18 @@ function calculateCost(provider, model, inputTokens, outputTokens, reasoningToke
7603
7637
  const modelCosts = provider === 'deepseek' ? deepseekModelCosts[model] : openAiModelCosts[model];
7604
7638
  if (!modelCosts)
7605
7639
  return 0;
7606
- // Calculate input cost based on cache hit/miss for Deepseek
7607
- const inputCost = provider === 'deepseek' && modelCosts.cacheHitCost
7608
- ? (cacheHitTokens || 0) * modelCosts.cacheHitCost + (inputTokens - (cacheHitTokens || 0)) * modelCosts.inputCost
7609
- : inputTokens * modelCosts.inputCost;
7610
- const outputCost = outputTokens * modelCosts.outputCost;
7611
- 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
+ }
7612
7652
  return inputCost + outputCost + reasoningCost;
7613
7653
  }
7614
7654
 
@@ -8006,6 +8046,8 @@ const isSupportedModel = (model) => {
8006
8046
  'gpt-5-mini',
8007
8047
  'gpt-5-nano',
8008
8048
  'gpt-5.1',
8049
+ 'gpt-5.4',
8050
+ 'gpt-5.4-pro',
8009
8051
  'gpt-5.2',
8010
8052
  'gpt-5.2-pro',
8011
8053
  'gpt-5.1-codex',
@@ -8032,6 +8074,8 @@ function supportsTemperature(model) {
8032
8074
  'gpt-5-mini',
8033
8075
  'gpt-5-nano',
8034
8076
  'gpt-5.1',
8077
+ 'gpt-5.4',
8078
+ 'gpt-5.4-pro',
8035
8079
  'gpt-5.2',
8036
8080
  'gpt-5.2-pro',
8037
8081
  'gpt-5.1-codex',
@@ -8059,6 +8103,8 @@ function isGPT5Model(model) {
8059
8103
  'gpt-5-mini',
8060
8104
  'gpt-5-nano',
8061
8105
  'gpt-5.1',
8106
+ 'gpt-5.4',
8107
+ 'gpt-5.4-pro',
8062
8108
  'gpt-5.2',
8063
8109
  'gpt-5.2-pro',
8064
8110
  'gpt-5.1-codex',
@@ -8066,6 +8112,12 @@ function isGPT5Model(model) {
8066
8112
  ];
8067
8113
  return gpt5Models.includes(model);
8068
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
+ }
8069
8121
  /**
8070
8122
  * Makes a call to OpenAI's Responses API for more advanced use cases with built-in tools.
8071
8123
  *
@@ -8108,8 +8160,15 @@ const makeResponsesAPICall = async (input, options = {}) => {
8108
8160
  input,
8109
8161
  ...cleanOptions,
8110
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
+ }
8111
8169
  // Make the API call to the Responses endpoint
8112
8170
  const response = await openai.responses.create(requestBody);
8171
+ const cacheHitTokens = response.usage?.input_tokens_details?.cached_tokens || 0;
8113
8172
  // Extract tool calls from the output
8114
8173
  const toolCalls = response.output
8115
8174
  ?.filter((item) => item.type === 'function_call')
@@ -8149,7 +8208,8 @@ const makeResponsesAPICall = async (input, options = {}) => {
8149
8208
  reasoning_tokens: response.usage?.output_tokens_details?.reasoning_tokens || 0,
8150
8209
  provider: 'openai',
8151
8210
  model: normalizedModel,
8152
- 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),
8153
8213
  },
8154
8214
  tool_calls: toolCalls,
8155
8215
  ...(codeInterpreterOutputs ? { code_interpreter_outputs: codeInterpreterOutputs } : {}),
@@ -8181,7 +8241,8 @@ const makeResponsesAPICall = async (input, options = {}) => {
8181
8241
  reasoning_tokens: response.usage?.output_tokens_details?.reasoning_tokens || 0,
8182
8242
  provider: 'openai',
8183
8243
  model: normalizedModel,
8184
- 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),
8185
8246
  },
8186
8247
  tool_calls: toolCalls,
8187
8248
  ...(codeInterpreterOutputs ? { code_interpreter_outputs: codeInterpreterOutputs } : {}),
@@ -8313,6 +8374,8 @@ const MULTIMODAL_VISION_MODELS = new Set([
8313
8374
  'gpt-5-mini',
8314
8375
  'gpt-5-nano',
8315
8376
  'gpt-5.1',
8377
+ 'gpt-5.4',
8378
+ 'gpt-5.4-pro',
8316
8379
  'gpt-5.2',
8317
8380
  'gpt-5.2-pro',
8318
8381
  'gpt-5.1-codex',