@discomedia/utils 1.0.68 → 1.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index-frontend.cjs +68 -208
- package/dist/index-frontend.cjs.map +1 -1
- package/dist/index-frontend.mjs +65 -209
- package/dist/index-frontend.mjs.map +1 -1
- package/dist/index.cjs +68 -208
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +65 -209
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +1 -1
- package/dist/test.js +119 -217
- package/dist/test.js.map +1 -1
- package/dist/types/index-frontend.d.ts +2 -0
- package/dist/types/index-frontend.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/llm-config.d.ts +1 -1
- package/dist/types/llm-config.d.ts.map +1 -1
- package/dist/types/llm-images.d.ts.map +1 -1
- package/dist/types/llm-openai.d.ts +4 -16
- package/dist/types/llm-openai.d.ts.map +1 -1
- package/dist/types/types/llm-types.d.ts +8 -2
- package/dist/types/types/llm-types.d.ts.map +1 -1
- package/dist/types-frontend/index-frontend.d.ts +2 -0
- package/dist/types-frontend/index-frontend.d.ts.map +1 -1
- package/dist/types-frontend/index.d.ts +2 -0
- package/dist/types-frontend/index.d.ts.map +1 -1
- package/dist/types-frontend/llm-config.d.ts +1 -1
- package/dist/types-frontend/llm-config.d.ts.map +1 -1
- package/dist/types-frontend/llm-images.d.ts.map +1 -1
- package/dist/types-frontend/llm-openai.d.ts +4 -16
- package/dist/types-frontend/llm-openai.d.ts.map +1 -1
- package/dist/types-frontend/types/llm-types.d.ts +8 -2
- package/dist/types-frontend/types/llm-types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/package.json
CHANGED
package/dist/test.js
CHANGED
|
@@ -366,33 +366,59 @@ function getLastFullTradingDate(currentDate = new Date()) {
|
|
|
366
366
|
return getLastFullTradingDateImpl(currentDate);
|
|
367
367
|
}
|
|
368
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Represents OpenAI models
|
|
371
|
+
*/
|
|
372
|
+
const OPENAI_MODELS = [
|
|
373
|
+
'gpt-5',
|
|
374
|
+
'gpt-5-mini',
|
|
375
|
+
'gpt-5.4-mini',
|
|
376
|
+
'gpt-5-nano',
|
|
377
|
+
'gpt-5.1',
|
|
378
|
+
'gpt-5.4',
|
|
379
|
+
'gpt-5.5',
|
|
380
|
+
'gpt-5.5-pro',
|
|
381
|
+
'gpt-5.2',
|
|
382
|
+
'gpt-5.2-pro',
|
|
383
|
+
'gpt-5.1-codex',
|
|
384
|
+
'gpt-5.1-codex-max',
|
|
385
|
+
];
|
|
386
|
+
/**
|
|
387
|
+
* Type guard to check if a model is a supported direct OpenAI model.
|
|
388
|
+
*/
|
|
389
|
+
function isOpenAIModel(model) {
|
|
390
|
+
return OPENAI_MODELS.includes(model);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Represents OpenRouter models
|
|
394
|
+
*/
|
|
395
|
+
const OPENROUTER_MODELS = [
|
|
396
|
+
'openai/gpt-5',
|
|
397
|
+
'openai/gpt-5-mini',
|
|
398
|
+
'openai/gpt-5.4-mini',
|
|
399
|
+
'openai/gpt-5-nano',
|
|
400
|
+
'openai/gpt-5.1',
|
|
401
|
+
'openai/gpt-5.4',
|
|
402
|
+
'openai/gpt-5.4-pro',
|
|
403
|
+
'openai/gpt-5.5',
|
|
404
|
+
'openai/gpt-5.5-pro',
|
|
405
|
+
'openai/gpt-5.2',
|
|
406
|
+
'openai/gpt-5.2-pro',
|
|
407
|
+
'openai/gpt-5.1-codex',
|
|
408
|
+
'openai/gpt-5.1-codex-max',
|
|
409
|
+
'openai/gpt-oss-120b',
|
|
410
|
+
'z.ai/glm-4.5',
|
|
411
|
+
'z.ai/glm-4.5-air',
|
|
412
|
+
'google/gemini-2.5-flash',
|
|
413
|
+
'google/gemini-2.5-flash-lite',
|
|
414
|
+
'deepseek/deepseek-r1-0528',
|
|
415
|
+
'deepseek/deepseek-chat-v3-0324',
|
|
416
|
+
];
|
|
369
417
|
/**
|
|
370
418
|
* Type guard to check if a model is an OpenRouter model
|
|
371
419
|
*/
|
|
372
420
|
function isOpenRouterModel(model) {
|
|
373
|
-
|
|
374
|
-
'openai/gpt-5',
|
|
375
|
-
'openai/gpt-5-mini',
|
|
376
|
-
'openai/gpt-5.4-mini',
|
|
377
|
-
'openai/gpt-5-nano',
|
|
378
|
-
'openai/gpt-5.1',
|
|
379
|
-
'openai/gpt-5.4',
|
|
380
|
-
'openai/gpt-5.4-pro',
|
|
381
|
-
'openai/gpt-5.5',
|
|
382
|
-
'openai/gpt-5.5-pro',
|
|
383
|
-
'openai/gpt-5.2',
|
|
384
|
-
'openai/gpt-5.2-pro',
|
|
385
|
-
'openai/gpt-5.1-codex',
|
|
386
|
-
'openai/gpt-5.1-codex-max',
|
|
387
|
-
'openai/gpt-oss-120b',
|
|
388
|
-
'z.ai/glm-4.5',
|
|
389
|
-
'z.ai/glm-4.5-air',
|
|
390
|
-
'google/gemini-2.5-flash',
|
|
391
|
-
'google/gemini-2.5-flash-lite',
|
|
392
|
-
'deepseek/deepseek-r1-0528',
|
|
393
|
-
'deepseek/deepseek-chat-v3-0324',
|
|
394
|
-
];
|
|
395
|
-
return openRouterModels.includes(model);
|
|
421
|
+
return OPENROUTER_MODELS.includes(model);
|
|
396
422
|
}
|
|
397
423
|
|
|
398
424
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
@@ -14143,57 +14169,12 @@ function zodTextFormat(zodObject, name, props) {
|
|
|
14143
14169
|
}
|
|
14144
14170
|
|
|
14145
14171
|
// llm-openai-config.ts
|
|
14146
|
-
const DEFAULT_MODEL = 'gpt-
|
|
14172
|
+
const DEFAULT_MODEL = 'gpt-5-mini';
|
|
14147
14173
|
const GPT_5_HIGH_CONTEXT_THRESHOLD_TOKENS = 272_000;
|
|
14148
14174
|
const GPT_5_HIGH_CONTEXT_INPUT_MULTIPLIER = 2;
|
|
14149
14175
|
const GPT_5_HIGH_CONTEXT_OUTPUT_MULTIPLIER = 1.5;
|
|
14150
14176
|
/** Token costs in USD per 1M tokens. Last updated May 2026. */
|
|
14151
14177
|
const openAiModelCosts = {
|
|
14152
|
-
'gpt-4o': {
|
|
14153
|
-
inputCost: 2.5 / 1_000_000,
|
|
14154
|
-
cacheHitCost: 1.25 / 1_000_000,
|
|
14155
|
-
outputCost: 10 / 1_000_000,
|
|
14156
|
-
},
|
|
14157
|
-
'gpt-4o-mini': {
|
|
14158
|
-
inputCost: 0.15 / 1_000_000,
|
|
14159
|
-
cacheHitCost: 0.075 / 1_000_000,
|
|
14160
|
-
outputCost: 0.6 / 1_000_000,
|
|
14161
|
-
},
|
|
14162
|
-
'o1-mini': {
|
|
14163
|
-
inputCost: 1.1 / 1_000_000,
|
|
14164
|
-
cacheHitCost: 0.55 / 1_000_000,
|
|
14165
|
-
outputCost: 4.4 / 1_000_000,
|
|
14166
|
-
},
|
|
14167
|
-
'o1': {
|
|
14168
|
-
inputCost: 15 / 1_000_000,
|
|
14169
|
-
cacheHitCost: 7.5 / 1_000_000,
|
|
14170
|
-
outputCost: 60 / 1_000_000,
|
|
14171
|
-
},
|
|
14172
|
-
'o3-mini': {
|
|
14173
|
-
inputCost: 1.1 / 1_000_000,
|
|
14174
|
-
cacheHitCost: 0.55 / 1_000_000,
|
|
14175
|
-
outputCost: 4.4 / 1_000_000,
|
|
14176
|
-
},
|
|
14177
|
-
'o3': {
|
|
14178
|
-
inputCost: 2 / 1_000_000,
|
|
14179
|
-
cacheHitCost: 0.5 / 1_000_000,
|
|
14180
|
-
outputCost: 8 / 1_000_000,
|
|
14181
|
-
},
|
|
14182
|
-
'gpt-4.1': {
|
|
14183
|
-
inputCost: 2 / 1_000_000,
|
|
14184
|
-
cacheHitCost: 0.5 / 1_000_000,
|
|
14185
|
-
outputCost: 8 / 1_000_000,
|
|
14186
|
-
},
|
|
14187
|
-
'gpt-4.1-mini': {
|
|
14188
|
-
inputCost: 0.4 / 1_000_000,
|
|
14189
|
-
cacheHitCost: 0.1 / 1_000_000,
|
|
14190
|
-
outputCost: 1.6 / 1_000_000,
|
|
14191
|
-
},
|
|
14192
|
-
'gpt-4.1-nano': {
|
|
14193
|
-
inputCost: 0.1 / 1_000_000,
|
|
14194
|
-
cacheHitCost: 0.025 / 1_000_000,
|
|
14195
|
-
outputCost: 0.4 / 1_000_000,
|
|
14196
|
-
},
|
|
14197
14178
|
'gpt-5': {
|
|
14198
14179
|
inputCost: 1.25 / 1_000_000,
|
|
14199
14180
|
cacheHitCost: 0.125 / 1_000_000,
|
|
@@ -14224,10 +14205,6 @@ const openAiModelCosts = {
|
|
|
14224
14205
|
cacheHitCost: 0.25 / 1_000_000,
|
|
14225
14206
|
outputCost: 15 / 1_000_000,
|
|
14226
14207
|
},
|
|
14227
|
-
'gpt-5.4-pro': {
|
|
14228
|
-
inputCost: 30 / 1_000_000,
|
|
14229
|
-
outputCost: 180 / 1_000_000,
|
|
14230
|
-
},
|
|
14231
14208
|
'gpt-5.5': {
|
|
14232
14209
|
inputCost: 5 / 1_000_000,
|
|
14233
14210
|
cacheHitCost: 0.5 / 1_000_000,
|
|
@@ -14256,11 +14233,6 @@ const openAiModelCosts = {
|
|
|
14256
14233
|
cacheHitCost: 0.125 / 1_000_000,
|
|
14257
14234
|
outputCost: 10 / 1_000_000,
|
|
14258
14235
|
},
|
|
14259
|
-
'o4-mini': {
|
|
14260
|
-
inputCost: 1.1 / 1_000_000,
|
|
14261
|
-
cacheHitCost: 0.275 / 1_000_000,
|
|
14262
|
-
outputCost: 4.4 / 1_000_000,
|
|
14263
|
-
},
|
|
14264
14236
|
};
|
|
14265
14237
|
const deepseekModelCosts = {
|
|
14266
14238
|
'deepseek-chat': {
|
|
@@ -14275,8 +14247,7 @@ const deepseekModelCosts = {
|
|
|
14275
14247
|
},
|
|
14276
14248
|
};
|
|
14277
14249
|
function shouldUseGPT5HighContextPricing(model, inputTokens) {
|
|
14278
|
-
return (
|
|
14279
|
-
inputTokens > GPT_5_HIGH_CONTEXT_THRESHOLD_TOKENS);
|
|
14250
|
+
return (model === 'gpt-5.4' || model === 'gpt-5.5') && inputTokens > GPT_5_HIGH_CONTEXT_THRESHOLD_TOKENS;
|
|
14280
14251
|
}
|
|
14281
14252
|
/** Image generation costs in USD per image. Based on OpenAI pricing as of Feb 2025. */
|
|
14282
14253
|
const openAiImageCosts = {
|
|
@@ -14717,101 +14688,6 @@ async function parseResponse(content, responseFormat) {
|
|
|
14717
14688
|
}
|
|
14718
14689
|
|
|
14719
14690
|
// llm-openai.ts
|
|
14720
|
-
const isSupportedModel = (model) => {
|
|
14721
|
-
return [
|
|
14722
|
-
'gpt-4o-mini',
|
|
14723
|
-
'gpt-4o',
|
|
14724
|
-
'o1-mini',
|
|
14725
|
-
'o1',
|
|
14726
|
-
'o3-mini',
|
|
14727
|
-
'gpt-4.1',
|
|
14728
|
-
'gpt-4.1-mini',
|
|
14729
|
-
'gpt-4.1-nano',
|
|
14730
|
-
'gpt-5',
|
|
14731
|
-
'gpt-5-mini',
|
|
14732
|
-
'gpt-5.4-mini',
|
|
14733
|
-
'gpt-5-nano',
|
|
14734
|
-
'gpt-5.1',
|
|
14735
|
-
'gpt-5.4',
|
|
14736
|
-
'gpt-5.4-pro',
|
|
14737
|
-
'gpt-5.5',
|
|
14738
|
-
'gpt-5.5-pro',
|
|
14739
|
-
'gpt-5.2',
|
|
14740
|
-
'gpt-5.2-pro',
|
|
14741
|
-
'gpt-5.1-codex',
|
|
14742
|
-
'gpt-5.1-codex-max',
|
|
14743
|
-
'o4-mini',
|
|
14744
|
-
'o3',
|
|
14745
|
-
].includes(model);
|
|
14746
|
-
};
|
|
14747
|
-
/**
|
|
14748
|
-
* Checks if the given model supports the temperature parameter. Reasoning models (o1*, o3*, o4*) do not support temperature.
|
|
14749
|
-
* @param model The model to check.
|
|
14750
|
-
* @returns True if the model supports the temperature parameter, false otherwise.
|
|
14751
|
-
*/
|
|
14752
|
-
function supportsTemperature(model) {
|
|
14753
|
-
// Reasoning models don't support temperature
|
|
14754
|
-
// GPT-5 models also do not support temperature
|
|
14755
|
-
const reasoningAndGPT5Models = [
|
|
14756
|
-
'o1',
|
|
14757
|
-
'o1-mini',
|
|
14758
|
-
'o3-mini',
|
|
14759
|
-
'o4-mini',
|
|
14760
|
-
'o3',
|
|
14761
|
-
'gpt-5',
|
|
14762
|
-
'gpt-5-mini',
|
|
14763
|
-
'gpt-5.4-mini',
|
|
14764
|
-
'gpt-5-nano',
|
|
14765
|
-
'gpt-5.1',
|
|
14766
|
-
'gpt-5.4',
|
|
14767
|
-
'gpt-5.4-pro',
|
|
14768
|
-
'gpt-5.5',
|
|
14769
|
-
'gpt-5.5-pro',
|
|
14770
|
-
'gpt-5.2',
|
|
14771
|
-
'gpt-5.2-pro',
|
|
14772
|
-
'gpt-5.1-codex',
|
|
14773
|
-
'gpt-5.1-codex-max',
|
|
14774
|
-
];
|
|
14775
|
-
return !reasoningAndGPT5Models.includes(model);
|
|
14776
|
-
}
|
|
14777
|
-
/**
|
|
14778
|
-
* Checks if the given model is a reasoning model. Reasoning models have different tool choice constraints.
|
|
14779
|
-
* @param model The model to check.
|
|
14780
|
-
* @returns True if the model is a reasoning model, false otherwise.
|
|
14781
|
-
*/
|
|
14782
|
-
function isReasoningModel(model) {
|
|
14783
|
-
const reasoningModels = ['o1', 'o1-mini', 'o3-mini', 'o4-mini', 'o3'];
|
|
14784
|
-
return reasoningModels.includes(model);
|
|
14785
|
-
}
|
|
14786
|
-
/**
|
|
14787
|
-
* Checks if the given model is a GPT-5 model. GPT-5 models don't support tool_choice other than 'auto'.
|
|
14788
|
-
* @param model The model to check.
|
|
14789
|
-
* @returns True if the model is a GPT-5 model, false otherwise.
|
|
14790
|
-
*/
|
|
14791
|
-
function isGPT5Model(model) {
|
|
14792
|
-
const gpt5Models = [
|
|
14793
|
-
'gpt-5',
|
|
14794
|
-
'gpt-5-mini',
|
|
14795
|
-
'gpt-5.4-mini',
|
|
14796
|
-
'gpt-5-nano',
|
|
14797
|
-
'gpt-5.1',
|
|
14798
|
-
'gpt-5.4',
|
|
14799
|
-
'gpt-5.4-pro',
|
|
14800
|
-
'gpt-5.5',
|
|
14801
|
-
'gpt-5.5-pro',
|
|
14802
|
-
'gpt-5.2',
|
|
14803
|
-
'gpt-5.2-pro',
|
|
14804
|
-
'gpt-5.1-codex',
|
|
14805
|
-
'gpt-5.1-codex-max',
|
|
14806
|
-
];
|
|
14807
|
-
return gpt5Models.includes(model);
|
|
14808
|
-
}
|
|
14809
|
-
function supportsStructuredOutputs(model) {
|
|
14810
|
-
return normalizeModelName(model) !== 'gpt-5.4-pro';
|
|
14811
|
-
}
|
|
14812
|
-
function supportsDistillation(model) {
|
|
14813
|
-
return normalizeModelName(model) !== 'gpt-5.4-pro';
|
|
14814
|
-
}
|
|
14815
14691
|
function isZodSchema(schema) {
|
|
14816
14692
|
return typeof schema === 'object' && schema !== null && 'safeParse' in schema;
|
|
14817
14693
|
}
|
|
@@ -14845,7 +14721,7 @@ function buildJsonSchemaFormat(schema, schemaName, schemaDescription, schemaStri
|
|
|
14845
14721
|
* - Built-in tools (web search, file search, computer use, code interpreter, image generation)
|
|
14846
14722
|
* - Background processing
|
|
14847
14723
|
* - Conversation state management
|
|
14848
|
-
* -
|
|
14724
|
+
* - GPT-5 reasoning controls
|
|
14849
14725
|
*
|
|
14850
14726
|
* @example
|
|
14851
14727
|
* // Basic text response
|
|
@@ -14866,6 +14742,9 @@ function buildJsonSchemaFormat(schema, schemaName, schemaDescription, schemaStri
|
|
|
14866
14742
|
*/
|
|
14867
14743
|
const makeResponsesAPICall = async (input, options = {}) => {
|
|
14868
14744
|
const normalizedModel = normalizeModelName(options.model || DEFAULT_MODEL);
|
|
14745
|
+
if (!isOpenAIModel(normalizedModel)) {
|
|
14746
|
+
throw new Error(`Unsupported OpenAI model: ${normalizedModel}. Please use a supported GPT-5 model.`);
|
|
14747
|
+
}
|
|
14869
14748
|
const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
|
|
14870
14749
|
if (!apiKey) {
|
|
14871
14750
|
throw new Error('OpenAI API key is not provided and OPENAI_API_KEY environment variable is not set');
|
|
@@ -14880,12 +14759,6 @@ const makeResponsesAPICall = async (input, options = {}) => {
|
|
|
14880
14759
|
input,
|
|
14881
14760
|
...cleanOptions,
|
|
14882
14761
|
};
|
|
14883
|
-
if (requestBody.text?.format?.type === 'json_schema' && !supportsStructuredOutputs(normalizedModel)) {
|
|
14884
|
-
throw new Error(`Model ${normalizedModel} does not support structured outputs`);
|
|
14885
|
-
}
|
|
14886
|
-
if (requestBody.store && !supportsDistillation(normalizedModel)) {
|
|
14887
|
-
throw new Error(`Model ${normalizedModel} does not support distillation`);
|
|
14888
|
-
}
|
|
14889
14762
|
// Make the API call to the Responses endpoint
|
|
14890
14763
|
const response = await openai.responses.create(requestBody);
|
|
14891
14764
|
const cacheHitTokens = response.usage?.input_tokens_details?.cached_tokens || 0;
|
|
@@ -14992,8 +14865,8 @@ async function makeLLMCall(input, options = {}) {
|
|
|
14992
14865
|
const { apiKey, model = DEFAULT_MODEL, responseFormat = 'text', schema, schemaName = 'response', schemaDescription, schemaStrict, tools, useCodeInterpreter = false, useWebSearch = false, imageBase64, imageDetail = 'high', context, } = options;
|
|
14993
14866
|
// Validate model
|
|
14994
14867
|
const normalizedModel = normalizeModelName(model);
|
|
14995
|
-
if (!
|
|
14996
|
-
throw new Error(`Unsupported model: ${normalizedModel}. Please use
|
|
14868
|
+
if (!isOpenAIModel(normalizedModel)) {
|
|
14869
|
+
throw new Error(`Unsupported OpenAI model: ${normalizedModel}. Please use a supported GPT-5 model.`);
|
|
14997
14870
|
}
|
|
14998
14871
|
// Process input for conversation context and image analysis
|
|
14999
14872
|
let processedInput;
|
|
@@ -15062,10 +14935,6 @@ async function makeLLMCall(input, options = {}) {
|
|
|
15062
14935
|
parallel_tool_calls: false,
|
|
15063
14936
|
tools,
|
|
15064
14937
|
};
|
|
15065
|
-
// Only include temperature if the model supports it
|
|
15066
|
-
if (supportsTemperature(normalizedModel)) {
|
|
15067
|
-
responsesOptions.temperature = 0.2;
|
|
15068
|
-
}
|
|
15069
14938
|
// Configure response format
|
|
15070
14939
|
if (schema) {
|
|
15071
14940
|
responsesOptions.text = {
|
|
@@ -15081,41 +14950,17 @@ async function makeLLMCall(input, options = {}) {
|
|
|
15081
14950
|
// Configure built-in tools
|
|
15082
14951
|
if (useCodeInterpreter) {
|
|
15083
14952
|
responsesOptions.tools = [{ type: 'code_interpreter', container: { type: 'auto' } }];
|
|
15084
|
-
// For reasoning models, we can't force tool choice - they only support 'auto'
|
|
15085
|
-
if (!isReasoningModel(normalizedModel)) {
|
|
15086
|
-
responsesOptions.tool_choice = { type: 'code_interpreter' };
|
|
15087
|
-
}
|
|
15088
14953
|
responsesOptions.include = ['code_interpreter_call.outputs'];
|
|
15089
14954
|
}
|
|
15090
14955
|
if (useWebSearch) {
|
|
15091
14956
|
responsesOptions.tools = [{ type: 'web_search_preview' }];
|
|
15092
|
-
// For reasoning models and GPT-5 models, we can't force tool choice - they only support 'auto'
|
|
15093
|
-
if (!isReasoningModel(normalizedModel) && !isGPT5Model(normalizedModel)) {
|
|
15094
|
-
responsesOptions.tool_choice = { type: 'web_search_preview' };
|
|
15095
|
-
}
|
|
15096
14957
|
}
|
|
15097
14958
|
return await makeResponsesAPICall(processedInput, responsesOptions);
|
|
15098
14959
|
}
|
|
15099
14960
|
|
|
15100
14961
|
const DEFAULT_IMAGE_MODEL = 'gpt-image-1.5';
|
|
15101
14962
|
const resolveImageModel = (model) => model ?? DEFAULT_IMAGE_MODEL;
|
|
15102
|
-
const MULTIMODAL_VISION_MODELS = new Set(
|
|
15103
|
-
'gpt-4o-mini',
|
|
15104
|
-
'gpt-4o',
|
|
15105
|
-
'gpt-5',
|
|
15106
|
-
'gpt-5-mini',
|
|
15107
|
-
'gpt-5.4-mini',
|
|
15108
|
-
'gpt-5-nano',
|
|
15109
|
-
'gpt-5.1',
|
|
15110
|
-
'gpt-5.4',
|
|
15111
|
-
'gpt-5.4-pro',
|
|
15112
|
-
'gpt-5.5',
|
|
15113
|
-
'gpt-5.5-pro',
|
|
15114
|
-
'gpt-5.2',
|
|
15115
|
-
'gpt-5.2-pro',
|
|
15116
|
-
'gpt-5.1-codex',
|
|
15117
|
-
'gpt-5.1-codex-max',
|
|
15118
|
-
]);
|
|
14963
|
+
const MULTIMODAL_VISION_MODELS = new Set(OPENAI_MODELS);
|
|
15119
14964
|
/**
|
|
15120
14965
|
* Makes a call to the OpenAI Images API to generate images based on a text prompt.
|
|
15121
14966
|
*
|
|
@@ -22399,7 +22244,7 @@ async function testLLM() {
|
|
|
22399
22244
|
console.log('Skipping OpenAI LLM tests: OPENAI_API_KEY not set');
|
|
22400
22245
|
return;
|
|
22401
22246
|
}
|
|
22402
|
-
const models = ['gpt-5
|
|
22247
|
+
const models = ['gpt-5-mini'];
|
|
22403
22248
|
for (const model of models) {
|
|
22404
22249
|
console.log(`\nTesting model: ${model}`);
|
|
22405
22250
|
// 1. Basic call
|
|
@@ -22415,14 +22260,70 @@ async function testLLM() {
|
|
|
22415
22260
|
}
|
|
22416
22261
|
console.log(`Response: ${JSON.stringify(json.response)}`);
|
|
22417
22262
|
// 3. Web search
|
|
22418
|
-
const searchPrompt =
|
|
22263
|
+
const searchPrompt = `Use web search to identify the official OpenAI model ID for ${model}. Respond with the model ID only.`;
|
|
22419
22264
|
const tool = await disco.llm.call(searchPrompt, { model, useWebSearch: true });
|
|
22420
|
-
if (!tool.response || !tool.response.includes(
|
|
22421
|
-
throw new Error(`Expected web search response to include
|
|
22265
|
+
if (!tool.response || !tool.response.includes(model)) {
|
|
22266
|
+
throw new Error(`Expected web search response to include ${model}, received: ${tool.response}`);
|
|
22422
22267
|
}
|
|
22423
22268
|
console.log(`Response: ${tool.response}`);
|
|
22424
22269
|
}
|
|
22425
22270
|
}
|
|
22271
|
+
function testOpenAIModelDeprecation() {
|
|
22272
|
+
const supportedModels = [
|
|
22273
|
+
'gpt-5',
|
|
22274
|
+
'gpt-5-mini',
|
|
22275
|
+
'gpt-5.4-mini',
|
|
22276
|
+
'gpt-5-nano',
|
|
22277
|
+
'gpt-5.1',
|
|
22278
|
+
'gpt-5.4',
|
|
22279
|
+
'gpt-5.5',
|
|
22280
|
+
'gpt-5.5-pro',
|
|
22281
|
+
'gpt-5.2',
|
|
22282
|
+
'gpt-5.2-pro',
|
|
22283
|
+
'gpt-5.1-codex',
|
|
22284
|
+
'gpt-5.1-codex-max',
|
|
22285
|
+
];
|
|
22286
|
+
for (const model of supportedModels) {
|
|
22287
|
+
if (!isOpenAIModel(model)) {
|
|
22288
|
+
throw new Error(`Expected ${model} to be accepted as a direct OpenAI model`);
|
|
22289
|
+
}
|
|
22290
|
+
}
|
|
22291
|
+
const deprecatedModels = [
|
|
22292
|
+
'gpt-4o-mini',
|
|
22293
|
+
'gpt-4o',
|
|
22294
|
+
'o1-mini',
|
|
22295
|
+
'o1',
|
|
22296
|
+
'o3-mini',
|
|
22297
|
+
'gpt-4.1',
|
|
22298
|
+
'gpt-4.1-mini',
|
|
22299
|
+
'o4-mini',
|
|
22300
|
+
'gpt-4.1-nano',
|
|
22301
|
+
'o3',
|
|
22302
|
+
'gpt-5.4-pro',
|
|
22303
|
+
];
|
|
22304
|
+
for (const model of deprecatedModels) {
|
|
22305
|
+
if (isOpenAIModel(model)) {
|
|
22306
|
+
throw new Error(`Expected ${model} to be deprecated from direct OpenAI support`);
|
|
22307
|
+
}
|
|
22308
|
+
}
|
|
22309
|
+
if (OPENAI_MODELS.length !== supportedModels.length) {
|
|
22310
|
+
throw new Error(`Expected ${supportedModels.length} direct OpenAI models, received ${OPENAI_MODELS.length}`);
|
|
22311
|
+
}
|
|
22312
|
+
const expectedOpenRouterModel = 'openai/gpt-5-mini';
|
|
22313
|
+
if (!OPENROUTER_MODELS.includes(expectedOpenRouterModel)) {
|
|
22314
|
+
throw new Error(`Expected OPENROUTER_MODELS to include ${expectedOpenRouterModel}`);
|
|
22315
|
+
}
|
|
22316
|
+
if (!isOpenRouterModel(expectedOpenRouterModel)) {
|
|
22317
|
+
throw new Error(`Expected ${expectedOpenRouterModel} to be accepted as an OpenRouter model`);
|
|
22318
|
+
}
|
|
22319
|
+
if (isOpenRouterModel('openai/gpt-4o-mini')) {
|
|
22320
|
+
throw new Error('Expected openai/gpt-4o-mini to be excluded from OpenRouter runtime models');
|
|
22321
|
+
}
|
|
22322
|
+
console.log('\n[OpenAI] Model deprecation test');
|
|
22323
|
+
console.log(` Default model: ${DEFAULT_MODEL}`);
|
|
22324
|
+
console.log(` Supported direct OpenAI models: ${OPENAI_MODELS.join(', ')}`);
|
|
22325
|
+
console.log(` Supported OpenRouter models: ${OPENROUTER_MODELS.join(', ')}`);
|
|
22326
|
+
}
|
|
22426
22327
|
async function testLLMStructuredOutputWithZod() {
|
|
22427
22328
|
if (!process.env.OPENAI_API_KEY) {
|
|
22428
22329
|
console.log('Skipping OpenAI structured output Zod test: OPENAI_API_KEY not set');
|
|
@@ -22461,6 +22362,7 @@ async function testLLMStructuredOutputWithZod() {
|
|
|
22461
22362
|
console.log(' Usage:', result.usage);
|
|
22462
22363
|
}
|
|
22463
22364
|
async function runActiveTests() {
|
|
22365
|
+
testOpenAIModelDeprecation();
|
|
22464
22366
|
await testLLM();
|
|
22465
22367
|
await testLLMStructuredOutputWithZod();
|
|
22466
22368
|
}
|