@discomedia/utils 1.0.46 → 1.0.51

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.0.46",
6
+ "version": "1.0.51",
7
7
  "author": "Disco Media",
8
8
  "description": "Utility functions used in Disco Media apps",
9
9
  "always-build-npm": true,
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "dotenv": "^17.2.3",
36
- "openai": "^6.9.1",
36
+ "openai": "^6.15.0",
37
37
  "p-limit": "^7.2.0",
38
38
  "tslib": "^2.8.1",
39
39
  "ws": "^8.18.3"
@@ -45,8 +45,8 @@
45
45
  "@rollup/plugin-node-resolve": "^16.0.3",
46
46
  "@rollup/plugin-typescript": "^12.3.0",
47
47
  "@types/ws": "^8.18.1",
48
- "lightweight-charts": "^5.0.9",
49
- "rollup": "^4.53.2",
48
+ "lightweight-charts": "^5.1.0",
49
+ "rollup": "^4.53.5",
50
50
  "typescript": "^5.9.3"
51
51
  }
52
52
  }
package/dist/test.js CHANGED
@@ -447,9 +447,10 @@ function getLastFullTradingDateImpl(currentDate = new Date()) {
447
447
  if (calendar.isEarlyCloseDay(prevMarketDay)) {
448
448
  prevCloseMinutes = MARKET_CONFIG.TIMES.EARLY_CLOSE.hour * 60 + MARKET_CONFIG.TIMES.EARLY_CLOSE.minute;
449
449
  }
450
- const year = prevMarketDay.getUTCFullYear();
451
- const month = prevMarketDay.getUTCMonth();
452
- const day = prevMarketDay.getUTCDate();
450
+ const prevNYDate = toNYTime(prevMarketDay);
451
+ const year = prevNYDate.getUTCFullYear();
452
+ const month = prevNYDate.getUTCMonth();
453
+ const day = prevNYDate.getUTCDate();
453
454
  const closeHour = Math.floor(prevCloseMinutes / 60);
454
455
  const closeMinute = prevCloseMinutes % 60;
455
456
  return fromNYTime(new Date(Date.UTC(year, month, day, closeHour, closeMinute, 0, 0)));
@@ -963,6 +964,61 @@ function countTradingDays(startDate, endDate = new Date()) {
963
964
  minutes: Math.round(minutes),
964
965
  };
965
966
  }
967
+ /**
968
+ * Returns the trading day N days back from a reference date, along with its market open time.
969
+ * Trading days are counted as full or half trading days (days that end count as 1 full trading day).
970
+ *
971
+ * @param options - Object with:
972
+ * - referenceDate: Date to count back from (default: now)
973
+ * - days: Number of trading days to go back (must be >= 1)
974
+ * @returns Object containing:
975
+ * - date: Trading date in YYYY-MM-DD format
976
+ * - marketOpenISO: Market open time as ISO string (e.g., "2025-11-15T13:30:00.000Z")
977
+ * - unixTimestamp: Market open time as Unix timestamp in seconds
978
+ * @example
979
+ * ```typescript
980
+ * // Get the trading day 1 day back (most recent full trading day)
981
+ * const result = getTradingDaysBack({ days: 1 });
982
+ * console.log(result.date); // "2025-11-01"
983
+ * console.log(result.marketOpenISO); // "2025-11-01T13:30:00.000Z"
984
+ * console.log(result.unixTimestamp); // 1730466600
985
+ *
986
+ * // Get the trading day 5 days back from a specific date
987
+ * const result2 = getTradingDaysBack({
988
+ * referenceDate: new Date('2025-11-15T12:00:00-05:00'),
989
+ * days: 5
990
+ * });
991
+ * ```
992
+ */
993
+ function getTradingDaysBack(options) {
994
+ const calendar = new MarketCalendar();
995
+ const refDate = options.referenceDate || new Date();
996
+ const daysBack = options.days;
997
+ if (daysBack < 1) {
998
+ throw new Error('days must be at least 1');
999
+ }
1000
+ // Start from the last full trading date relative to reference
1001
+ let targetDate = getLastFullTradingDateImpl(refDate);
1002
+ // Go back the specified number of days (we're already at day 1, so go back days-1 more)
1003
+ for (let i = 1; i < daysBack; i++) {
1004
+ targetDate = calendar.getPreviousMarketDay(targetDate);
1005
+ }
1006
+ // Get market open time for this date
1007
+ const marketTimes = getMarketTimes(targetDate);
1008
+ if (!marketTimes.open) {
1009
+ throw new Error(`No market open time for target date`);
1010
+ }
1011
+ // Format the date string (YYYY-MM-DD) in NY time
1012
+ const nyDate = toNYTime(marketTimes.open);
1013
+ const dateStr = `${nyDate.getUTCFullYear()}-${String(nyDate.getUTCMonth() + 1).padStart(2, '0')}-${String(nyDate.getUTCDate()).padStart(2, '0')}`;
1014
+ const marketOpenISO = marketTimes.open.toISOString();
1015
+ const unixTimestamp = Math.floor(marketTimes.open.getTime() / 1000);
1016
+ return {
1017
+ date: dateStr,
1018
+ marketOpenISO,
1019
+ unixTimestamp,
1020
+ };
1021
+ }
966
1022
  // Export MARKET_TIMES for compatibility
967
1023
  const MARKET_TIMES = {
968
1024
  TIMEZONE: MARKET_CONFIG.TIMEZONE,
@@ -1085,6 +1141,10 @@ function isOpenRouterModel(model) {
1085
1141
  'openai/gpt-5-mini',
1086
1142
  'openai/gpt-5-nano',
1087
1143
  'openai/gpt-5.1',
1144
+ 'openai/gpt-5.2',
1145
+ 'openai/gpt-5.2-pro',
1146
+ 'openai/gpt-5.1-codex',
1147
+ 'openai/gpt-5.1-codex-max',
1088
1148
  'openai/gpt-oss-120b',
1089
1149
  'z.ai/glm-4.5',
1090
1150
  'z.ai/glm-4.5-air',
@@ -2450,7 +2510,7 @@ const safeJSON = (text) => {
2450
2510
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2451
2511
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2452
2512
 
2453
- const VERSION = '6.9.1'; // x-release-please-version
2513
+ const VERSION = '6.15.0'; // x-release-please-version
2454
2514
 
2455
2515
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2456
2516
  const isRunningInBrowser = () => {
@@ -8291,6 +8351,19 @@ class Responses extends APIResource {
8291
8351
  cancel(responseID, options) {
8292
8352
  return this._client.post(path `/responses/${responseID}/cancel`, options);
8293
8353
  }
8354
+ /**
8355
+ * Compact conversation
8356
+ *
8357
+ * @example
8358
+ * ```ts
8359
+ * const compactedResponse = await client.responses.compact({
8360
+ * model: 'gpt-5.2',
8361
+ * });
8362
+ * ```
8363
+ */
8364
+ compact(body, options) {
8365
+ return this._client.post('/responses/compact', { body, ...options });
8366
+ }
8294
8367
  }
8295
8368
  Responses.InputItems = InputItems;
8296
8369
  Responses.InputTokens = InputTokens;
@@ -9433,6 +9506,22 @@ const openAiModelCosts = {
9433
9506
  inputCost: 1.25 / 1_000_000,
9434
9507
  outputCost: 10 / 1_000_000,
9435
9508
  },
9509
+ 'gpt-5.2': {
9510
+ inputCost: 1.5 / 1_000_000,
9511
+ outputCost: 12 / 1_000_000,
9512
+ },
9513
+ 'gpt-5.2-pro': {
9514
+ inputCost: 3 / 1_000_000,
9515
+ outputCost: 24 / 1_000_000,
9516
+ },
9517
+ 'gpt-5.1-codex': {
9518
+ inputCost: 1.1 / 1_000_000,
9519
+ outputCost: 8.8 / 1_000_000,
9520
+ },
9521
+ 'gpt-5.1-codex-max': {
9522
+ inputCost: 1.8 / 1_000_000,
9523
+ outputCost: 14.4 / 1_000_000,
9524
+ },
9436
9525
  'o4-mini': {
9437
9526
  inputCost: 1.1 / 1_000_000,
9438
9527
  outputCost: 4.4 / 1_000_000,
@@ -9453,6 +9542,7 @@ const deepseekModelCosts = {
9453
9542
  /** Image generation costs in USD per image. Based on OpenAI pricing as of Feb 2025. */
9454
9543
  const openAiImageCosts = {
9455
9544
  'gpt-image-1': 0.0075, // $0.0075 per image for gpt-image-1
9545
+ 'gpt-image-1.5': 0.0075, // Assumes parity pricing with gpt-image-1 until OpenAI publishes updated rates
9456
9546
  };
9457
9547
  /**
9458
9548
  * Calculates the cost of generating images using OpenAI's Images API.
@@ -9462,10 +9552,12 @@ const openAiImageCosts = {
9462
9552
  * @returns The cost of generating the images in USD.
9463
9553
  */
9464
9554
  function calculateImageCost(model, imageCount) {
9465
- if (typeof imageCount !== 'number' || imageCount <= 0) {
9555
+ if (typeof model !== 'string' || typeof imageCount !== 'number' || imageCount <= 0) {
9466
9556
  return 0;
9467
9557
  }
9468
9558
  const costPerImage = openAiImageCosts[model];
9559
+ if (!costPerImage)
9560
+ return 0;
9469
9561
  return imageCount * costPerImage;
9470
9562
  }
9471
9563
  /**
@@ -9894,6 +9986,10 @@ const isSupportedModel = (model) => {
9894
9986
  'gpt-5-mini',
9895
9987
  'gpt-5-nano',
9896
9988
  'gpt-5.1',
9989
+ 'gpt-5.2',
9990
+ 'gpt-5.2-pro',
9991
+ 'gpt-5.1-codex',
9992
+ 'gpt-5.1-codex-max',
9897
9993
  'o4-mini',
9898
9994
  'o3',
9899
9995
  ].includes(model);
@@ -9906,7 +10002,21 @@ const isSupportedModel = (model) => {
9906
10002
  function supportsTemperature(model) {
9907
10003
  // Reasoning models don't support temperature
9908
10004
  // GPT-5 models also do not support temperature
9909
- const reasoningAndGPT5Models = ['o1', 'o1-mini', 'o3-mini', 'o4-mini', 'o3', 'gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5.1'];
10005
+ const reasoningAndGPT5Models = [
10006
+ 'o1',
10007
+ 'o1-mini',
10008
+ 'o3-mini',
10009
+ 'o4-mini',
10010
+ 'o3',
10011
+ 'gpt-5',
10012
+ 'gpt-5-mini',
10013
+ 'gpt-5-nano',
10014
+ 'gpt-5.1',
10015
+ 'gpt-5.2',
10016
+ 'gpt-5.2-pro',
10017
+ 'gpt-5.1-codex',
10018
+ 'gpt-5.1-codex-max',
10019
+ ];
9910
10020
  return !reasoningAndGPT5Models.includes(model);
9911
10021
  }
9912
10022
  /**
@@ -9924,7 +10034,16 @@ function isReasoningModel(model) {
9924
10034
  * @returns True if the model is a GPT-5 model, false otherwise.
9925
10035
  */
9926
10036
  function isGPT5Model(model) {
9927
- const gpt5Models = ['gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5.1'];
10037
+ const gpt5Models = [
10038
+ 'gpt-5',
10039
+ 'gpt-5-mini',
10040
+ 'gpt-5-nano',
10041
+ 'gpt-5.1',
10042
+ 'gpt-5.2',
10043
+ 'gpt-5.2-pro',
10044
+ 'gpt-5.1-codex',
10045
+ 'gpt-5.1-codex-max',
10046
+ ];
9928
10047
  return gpt5Models.includes(model);
9929
10048
  }
9930
10049
  /**
@@ -10165,6 +10284,20 @@ async function makeLLMCall(input, options = {}) {
10165
10284
  return await makeResponsesAPICall(processedInput, responsesOptions);
10166
10285
  }
10167
10286
 
10287
+ const DEFAULT_IMAGE_MODEL = 'gpt-image-1.5';
10288
+ const resolveImageModel = (model) => model ?? DEFAULT_IMAGE_MODEL;
10289
+ const MULTIMODAL_VISION_MODELS = new Set([
10290
+ 'gpt-4o-mini',
10291
+ 'gpt-4o',
10292
+ 'gpt-5',
10293
+ 'gpt-5-mini',
10294
+ 'gpt-5-nano',
10295
+ 'gpt-5.1',
10296
+ 'gpt-5.2',
10297
+ 'gpt-5.2-pro',
10298
+ 'gpt-5.1-codex',
10299
+ 'gpt-5.1-codex-max',
10300
+ ]);
10168
10301
  /**
10169
10302
  * Makes a call to the OpenAI Images API to generate images based on a text prompt.
10170
10303
  *
@@ -10201,7 +10334,12 @@ async function makeLLMCall(input, options = {}) {
10201
10334
  * @throws Error if the API call fails or invalid parameters are provided
10202
10335
  */
10203
10336
  async function makeImagesCall(prompt, options = {}) {
10204
- const { size = 'auto', outputFormat = 'webp', compression = 50, quality = 'high', count = 1, background = 'auto', moderation = 'auto', apiKey } = options;
10337
+ const { model, size = 'auto', outputFormat = 'webp', compression = 50, quality = 'high', count = 1, background = 'auto', moderation = 'auto', apiKey, visionModel, } = options;
10338
+ const imageModel = resolveImageModel(model);
10339
+ const supportedVisionModel = visionModel && MULTIMODAL_VISION_MODELS.has(visionModel) ? visionModel : undefined;
10340
+ if (visionModel && !supportedVisionModel) {
10341
+ console.warn(`Vision model ${visionModel} is not recognized as a multimodal OpenAI model. Ignoring for image usage metadata.`);
10342
+ }
10205
10343
  // Get API key
10206
10344
  const effectiveApiKey = apiKey || process.env.OPENAI_API_KEY;
10207
10345
  if (!effectiveApiKey) {
@@ -10222,7 +10360,7 @@ async function makeImagesCall(prompt, options = {}) {
10222
10360
  });
10223
10361
  // Build the request parameters using OpenAI's type
10224
10362
  const requestParams = {
10225
- model: 'gpt-image-1',
10363
+ model: imageModel,
10226
10364
  prompt,
10227
10365
  n: count || 1,
10228
10366
  size: size || 'auto',
@@ -10246,7 +10384,7 @@ async function makeImagesCall(prompt, options = {}) {
10246
10384
  throw new Error('No images returned from OpenAI Images API');
10247
10385
  }
10248
10386
  // Calculate cost
10249
- const cost = calculateImageCost('gpt-image-1', count || 1);
10387
+ const cost = calculateImageCost(imageModel, count || 1);
10250
10388
  // Return the response with enhanced usage information
10251
10389
  const enhancedResponse = {
10252
10390
  ...response,
@@ -10259,8 +10397,9 @@ async function makeImagesCall(prompt, options = {}) {
10259
10397
  total_tokens: 0,
10260
10398
  }),
10261
10399
  provider: 'openai',
10262
- model: 'gpt-image-1',
10400
+ model: imageModel,
10263
10401
  cost,
10402
+ ...(supportedVisionModel ? { visionModel: supportedVisionModel } : {}),
10264
10403
  },
10265
10404
  };
10266
10405
  return enhancedResponse;
@@ -19387,6 +19526,7 @@ const disco = {
19387
19526
  getNYTimeZone: getNYTimeZone,
19388
19527
  getTradingDate: getTradingDate,
19389
19528
  getTradingStartAndEndDates: getTradingStartAndEndDates,
19529
+ getTradingDaysBack: getTradingDaysBack,
19390
19530
  isMarketDay: isMarketDay,
19391
19531
  isWithinMarketHours: isWithinMarketHours,
19392
19532
  countTradingDays: countTradingDays,
@@ -19401,47 +19541,151 @@ const disco = {
19401
19541
  };
19402
19542
 
19403
19543
  // Test file for context functionality
19404
- async function testLLM() {
19405
- //const models: LLMModel[] = ['gpt-5', 'gpt-5-mini', 'gpt-5-nano'];
19406
- const models = ['gpt-5.1'];
19407
- for (const model of models) {
19408
- console.log(`\nTesting model: ${model}`);
19409
- // 1. Basic call
19410
- try {
19411
- const basic = await disco.llm.call('What is the capital of France?', { model });
19412
- if (!basic || !basic.response) {
19413
- throw new Error('No response from LLM');
19414
- }
19415
- console.log(`Response: ${basic.response}`);
19416
- }
19417
- catch (e) {
19418
- console.error(` Basic call error:`, e);
19419
- }
19420
- // 2. JSON call
19544
+ function testGetTradingDaysBack() {
19545
+ const testCases = [
19546
+ {
19547
+ label: '1 day back from Friday after close',
19548
+ referenceDate: '2025-07-11T18:00:00-04:00',
19549
+ days: 1,
19550
+ expected: {
19551
+ date: '2025-07-11',
19552
+ marketOpenISO: '2025-07-11T13:30:00.000Z',
19553
+ },
19554
+ },
19555
+ {
19556
+ label: '1 day back from Friday during market',
19557
+ referenceDate: '2025-07-11T10:00:00-04:00',
19558
+ days: 1,
19559
+ expected: {
19560
+ date: '2025-07-10',
19561
+ marketOpenISO: '2025-07-10T13:30:00.000Z',
19562
+ },
19563
+ },
19564
+ {
19565
+ label: '2 days back from Friday after close',
19566
+ referenceDate: '2025-07-11T18:00:00-04:00',
19567
+ days: 2,
19568
+ expected: {
19569
+ date: '2025-07-10',
19570
+ marketOpenISO: '2025-07-10T13:30:00.000Z',
19571
+ },
19572
+ },
19573
+ {
19574
+ label: '5 days back from Friday after close',
19575
+ referenceDate: '2025-07-11T18:00:00-04:00',
19576
+ days: 5,
19577
+ expected: {
19578
+ date: '2025-07-07',
19579
+ marketOpenISO: '2025-07-07T13:30:00.000Z',
19580
+ },
19581
+ },
19582
+ {
19583
+ label: '6 days back from Friday after close (skips weekend and July 4)',
19584
+ referenceDate: '2025-07-11T18:00:00-04:00',
19585
+ days: 6,
19586
+ expected: {
19587
+ date: '2025-07-03',
19588
+ marketOpenISO: '2025-07-03T13:30:00.000Z',
19589
+ },
19590
+ },
19591
+ {
19592
+ label: '1 day back from Monday after close (should be Monday)',
19593
+ referenceDate: '2025-07-14T18:00:00-04:00',
19594
+ days: 1,
19595
+ expected: {
19596
+ date: '2025-07-14',
19597
+ marketOpenISO: '2025-07-14T13:30:00.000Z',
19598
+ },
19599
+ },
19600
+ {
19601
+ label: '1 day back from Saturday (should be Friday)',
19602
+ referenceDate: '2025-07-12T12:00:00-04:00',
19603
+ days: 1,
19604
+ expected: {
19605
+ date: '2025-07-11',
19606
+ marketOpenISO: '2025-07-11T13:30:00.000Z',
19607
+ },
19608
+ },
19609
+ {
19610
+ label: '3 days back from Monday (skips weekend)',
19611
+ referenceDate: '2025-07-14T18:00:00-04:00',
19612
+ days: 3,
19613
+ expected: {
19614
+ date: '2025-07-10',
19615
+ marketOpenISO: '2025-07-10T13:30:00.000Z',
19616
+ },
19617
+ },
19618
+ {
19619
+ label: '1 day back from day after holiday (July 7, after July 4)',
19620
+ referenceDate: '2025-07-07T18:00:00-04:00',
19621
+ days: 1,
19622
+ expected: {
19623
+ date: '2025-07-07',
19624
+ marketOpenISO: '2025-07-07T13:30:00.000Z',
19625
+ },
19626
+ },
19627
+ {
19628
+ label: '2 days back from day after holiday (skips July 4)',
19629
+ referenceDate: '2025-07-07T18:00:00-04:00',
19630
+ days: 2,
19631
+ expected: {
19632
+ date: '2025-07-03',
19633
+ marketOpenISO: '2025-07-03T13:30:00.000Z',
19634
+ },
19635
+ },
19636
+ {
19637
+ label: 'Early close day (July 3) - 1 day back from July 7',
19638
+ referenceDate: '2025-07-07T18:00:00-04:00',
19639
+ days: 2,
19640
+ expected: {
19641
+ date: '2025-07-03',
19642
+ marketOpenISO: '2025-07-03T13:30:00.000Z', // Still opens at normal time
19643
+ },
19644
+ },
19645
+ ];
19646
+ console.log('\n=== Testing getTradingDaysBack ===\n');
19647
+ for (const { label, referenceDate, days, expected } of testCases) {
19421
19648
  try {
19422
- const jsonPrompt = 'Return a JSON object with keys country and capital for France.';
19423
- const json = await disco.llm.call(jsonPrompt, { model, responseFormat: 'json' });
19424
- if (!json || !json.response) {
19425
- throw new Error('No response from LLM');
19649
+ const refDate = new Date(referenceDate);
19650
+ const result = disco.time.getTradingDaysBack({ referenceDate: refDate, days });
19651
+ const dateMatches = result.date === expected.date;
19652
+ const isoMatches = result.marketOpenISO === expected.marketOpenISO;
19653
+ const unixValid = typeof result.unixTimestamp === 'number' && result.unixTimestamp > 0;
19654
+ // Verify unix timestamp matches ISO
19655
+ const dateFromUnix = new Date(result.unixTimestamp * 1000).toISOString();
19656
+ const unixMatches = dateFromUnix === result.marketOpenISO;
19657
+ const allPass = dateMatches && isoMatches && unixValid && unixMatches;
19658
+ console.log(`${allPass ? '✅' : '❌'} ${label}`);
19659
+ if (!allPass) {
19660
+ console.log(` Expected: ${JSON.stringify(expected)}`);
19661
+ console.log(` Got: ${JSON.stringify(result)}`);
19662
+ if (!dateMatches)
19663
+ console.log(` ❌ Date mismatch`);
19664
+ if (!isoMatches)
19665
+ console.log(` ❌ ISO mismatch`);
19666
+ if (!unixValid)
19667
+ console.log(` ❌ Unix timestamp invalid`);
19668
+ if (!unixMatches)
19669
+ console.log(` ❌ Unix timestamp doesn't match ISO`);
19426
19670
  }
19427
- console.log(`Response: ${JSON.stringify(json.response)}`);
19428
19671
  }
19429
- catch (e) {
19430
- console.error(` JSON call error:`, e);
19672
+ catch (error) {
19673
+ console.log(`❌ ${label}`);
19674
+ console.log(` Error: ${error instanceof Error ? error.message : String(error)}`);
19431
19675
  }
19432
- // 3. Web search
19676
+ }
19677
+ const totalTests = testCases.length;
19678
+ const passedTests = testCases.filter((tc) => {
19433
19679
  try {
19434
- const searchPrompt = 'What is the latest news about artificial intelligence? Respond with 3 sentences max.';
19435
- const tool = await disco.llm.call(searchPrompt, { model, useWebSearch: true });
19436
- if (!tool || !tool.response) {
19437
- throw new Error('No response from LLM');
19438
- }
19439
- console.log(`Response: ${tool.response}`);
19680
+ const refDate = new Date(tc.referenceDate);
19681
+ const result = disco.time.getTradingDaysBack({ referenceDate: refDate, days: tc.days });
19682
+ return result.date === tc.expected.date && result.marketOpenISO === tc.expected.marketOpenISO;
19440
19683
  }
19441
- catch (e) {
19442
- console.error(` Web search error:`, e);
19684
+ catch {
19685
+ return false;
19443
19686
  }
19444
- }
19687
+ }).length;
19688
+ console.log(`\n=== Summary: ${passedTests}/${totalTests} tests passed ===\n`);
19445
19689
  }
19446
19690
  // testGetTradingDate();
19447
19691
  // testGetTradingStartAndEndDates();
@@ -19458,5 +19702,7 @@ async function testLLM() {
19458
19702
  // testWebSocketConnectAndDisconnect();
19459
19703
  // testGetAssetsShortableFilter();
19460
19704
  // testMarketDataAPI();
19461
- testLLM();
19705
+ // testLLM();
19706
+ // testImageModelDefaults();
19707
+ testGetTradingDaysBack();
19462
19708
  //# sourceMappingURL=test.js.map