hedgequantx 2.5.25 → 2.5.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.5.25",
3
+ "version": "2.5.26",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -38,7 +38,7 @@ const aiAgentMenu = async () => {
38
38
  const agentCount = agents.length;
39
39
 
40
40
  if (agentCount === 0) {
41
- console.log(makeLine(chalk.gray('STATUS: NO AGENTS CONNECTED'), 'left'));
41
+ console.log(makeLine(chalk.white('STATUS: NO AGENTS CONNECTED'), 'left'));
42
42
  } else {
43
43
  console.log(makeLine(chalk.green(`STATUS: ${agentCount} AGENT${agentCount > 1 ? 'S' : ''} CONNECTED`), 'left'));
44
44
  console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
@@ -48,16 +48,26 @@ const aiAgentMenu = async () => {
48
48
  const agent = agents[i];
49
49
  // Show ACTIVE marker (if single agent, it's always active)
50
50
  const isActive = agent.isActive || agents.length === 1;
51
- const activeMarker = isActive ? chalk.green(' [ACTIVE]') : '';
51
+ const activeMarker = isActive ? ' [ACTIVE]' : '';
52
52
  const providerColor = agent.providerId === 'anthropic' ? chalk.magenta :
53
53
  agent.providerId === 'openai' ? chalk.green :
54
54
  agent.providerId === 'openrouter' ? chalk.yellow : chalk.cyan;
55
55
 
56
+ // Calculate max lengths to fit in box
57
+ const prefix = `[${i + 1}] `;
58
+ const suffix = ` - ${agent.model || 'N/A'}`;
59
+ const maxNameLen = W - prefix.length - activeMarker.length - suffix.length - 2;
60
+
61
+ // Truncate agent name if too long
62
+ const displayName = agent.name.length > maxNameLen
63
+ ? agent.name.substring(0, maxNameLen - 3) + '...'
64
+ : agent.name;
65
+
56
66
  console.log(makeLine(
57
- chalk.white(`[${i + 1}] `) +
58
- providerColor(agent.name) +
59
- activeMarker +
60
- chalk.gray(` - ${agent.model}`)
67
+ chalk.white(prefix) +
68
+ providerColor(displayName) +
69
+ chalk.green(activeMarker) +
70
+ chalk.white(suffix)
61
71
  ));
62
72
  }
63
73
  }
@@ -95,13 +105,13 @@ const aiAgentMenu = async () => {
95
105
  if (agentCount > 1) {
96
106
  menuRow2(menuItem('+', 'ADD AGENT', chalk.green), menuItem('S', 'SET ACTIVE', chalk.cyan));
97
107
  menuRow2(menuItem('M', 'CHANGE MODEL', chalk.yellow), menuItem('R', 'REMOVE AGENT', chalk.red));
98
- menuRow2(menuItem('X', 'REMOVE ALL', chalk.red), menuItem('<', 'BACK', chalk.gray));
108
+ menuRow2(menuItem('X', 'REMOVE ALL', chalk.red), menuItem('<', 'BACK', chalk.white));
99
109
  } else {
100
110
  menuRow2(menuItem('+', 'ADD AGENT', chalk.green), menuItem('M', 'CHANGE MODEL', chalk.yellow));
101
- menuRow2(menuItem('R', 'REMOVE AGENT', chalk.red), menuItem('<', 'BACK', chalk.gray));
111
+ menuRow2(menuItem('R', 'REMOVE AGENT', chalk.red), menuItem('<', 'BACK', chalk.white));
102
112
  }
103
113
  } else {
104
- menuRow2(menuItem('+', 'ADD AGENT', chalk.green), menuItem('<', 'BACK', chalk.gray));
114
+ menuRow2(menuItem('+', 'ADD AGENT', chalk.green), menuItem('<', 'BACK', chalk.white));
105
115
  }
106
116
 
107
117
  drawBoxFooter(boxWidth);
@@ -170,9 +180,9 @@ const showAgentDetails = async (agent) => {
170
180
  agent.providerId === 'openrouter' ? chalk.yellow : chalk.cyan;
171
181
 
172
182
  console.log(makeLine(chalk.white('NAME: ') + providerColor(agent.name)));
173
- console.log(makeLine(chalk.white('PROVIDER: ') + chalk.gray(agent.provider?.name || agent.providerId)));
174
- console.log(makeLine(chalk.white('MODEL: ') + chalk.gray(agent.model)));
175
- console.log(makeLine(chalk.white('STATUS: ') + (agent.isActive ? chalk.green('ACTIVE') : chalk.gray('STANDBY'))));
183
+ console.log(makeLine(chalk.white('PROVIDER: ') + chalk.white(agent.provider?.name || agent.providerId)));
184
+ console.log(makeLine(chalk.white('MODEL: ') + chalk.white(agent.model)));
185
+ console.log(makeLine(chalk.white('STATUS: ') + (agent.isActive ? chalk.green('ACTIVE') : chalk.white('STANDBY'))));
176
186
 
177
187
  console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
178
188
 
@@ -181,7 +191,7 @@ const showAgentDetails = async (agent) => {
181
191
  }
182
192
  console.log(makeLine(chalk.yellow('[M] CHANGE MODEL')));
183
193
  console.log(makeLine(chalk.red('[R] REMOVE')));
184
- console.log(makeLine(chalk.gray('[<] BACK')));
194
+ console.log(makeLine(chalk.white('[<] BACK')));
185
195
 
186
196
  drawBoxFooter(boxWidth);
187
197
 
@@ -241,7 +251,7 @@ const selectActiveAgent = async () => {
241
251
  }
242
252
 
243
253
  console.log(makeLine(''));
244
- console.log(makeLine(chalk.gray('[<] BACK')));
254
+ console.log(makeLine(chalk.white('[<] BACK')));
245
255
 
246
256
  drawBoxFooter(boxWidth);
247
257
 
@@ -288,12 +298,12 @@ const selectAgentForModelChange = async () => {
288
298
  for (let i = 0; i < agents.length; i++) {
289
299
  const agent = agents[i];
290
300
  console.log(makeLine(
291
- chalk.white(`[${i + 1}] `) + chalk.cyan(agent.name) + chalk.gray(` - ${agent.model}`)
301
+ chalk.white(`[${i + 1}] `) + chalk.cyan(agent.name) + chalk.white(` - ${agent.model}`)
292
302
  ));
293
303
  }
294
304
 
295
305
  console.log(makeLine(''));
296
- console.log(makeLine(chalk.gray('[<] BACK')));
306
+ console.log(makeLine(chalk.white('[<] BACK')));
297
307
 
298
308
  drawBoxFooter(boxWidth);
299
309
 
@@ -345,7 +355,7 @@ const selectAgentToRemove = async () => {
345
355
  }
346
356
 
347
357
  console.log(makeLine(''));
348
- console.log(makeLine(chalk.gray('[<] BACK')));
358
+ console.log(makeLine(chalk.white('[<] BACK')));
349
359
 
350
360
  drawBoxFooter(boxWidth);
351
361
 
@@ -400,20 +410,20 @@ const selectCategory = async () => {
400
410
  chalk.cyan('[2] DIRECT PROVIDERS')
401
411
  ));
402
412
  console.log(make2ColRow(
403
- chalk.gray(' 1 API = 100+ models'),
404
- chalk.gray(' Connect to each provider')
413
+ chalk.white(' 1 API = 100+ models'),
414
+ chalk.white(' Connect to each provider')
405
415
  ));
406
416
  console.log(makeLine(''));
407
417
  console.log(make2ColRow(
408
418
  chalk.yellow('[3] LOCAL (FREE)'),
409
- chalk.gray('[4] CUSTOM')
419
+ chalk.white('[4] CUSTOM')
410
420
  ));
411
421
  console.log(make2ColRow(
412
- chalk.gray(' Run on your machine'),
413
- chalk.gray(' Self-hosted solutions')
422
+ chalk.white(' Run on your machine'),
423
+ chalk.white(' Self-hosted solutions')
414
424
  ));
415
425
  console.log(makeLine(''));
416
- console.log(makeLine(chalk.gray('[<] BACK')));
426
+ console.log(makeLine(chalk.white('[<] BACK')));
417
427
 
418
428
  drawBoxFooter(boxWidth);
419
429
 
@@ -464,7 +474,7 @@ const selectProvider = async (categoryId) => {
464
474
  const providers = getProvidersByCategory(categoryId);
465
475
 
466
476
  if (providers.length === 0) {
467
- console.log(makeLine(chalk.gray('NO PROVIDERS IN THIS CATEGORY')));
477
+ console.log(makeLine(chalk.white('NO PROVIDERS IN THIS CATEGORY')));
468
478
  drawBoxFooter(boxWidth);
469
479
  await prompts.waitForEnter();
470
480
  return await selectCategory();
@@ -489,14 +499,14 @@ const selectProvider = async (categoryId) => {
489
499
  const rightDesc = right ? ' ' + right.description : '';
490
500
 
491
501
  console.log(make2ColRow(
492
- chalk.gray(leftDesc.length > col1Width - 3 ? leftDesc.substring(0, col1Width - 6) + '...' : leftDesc),
493
- chalk.gray(rightDesc.length > col1Width - 3 ? rightDesc.substring(0, col1Width - 6) + '...' : rightDesc)
502
+ chalk.white(leftDesc.length > col1Width - 3 ? leftDesc.substring(0, col1Width - 6) + '...' : leftDesc),
503
+ chalk.white(rightDesc.length > col1Width - 3 ? rightDesc.substring(0, col1Width - 6) + '...' : rightDesc)
494
504
  ));
495
505
 
496
506
  console.log(makeLine(''));
497
507
  }
498
508
 
499
- console.log(makeLine(chalk.gray('[<] BACK')));
509
+ console.log(makeLine(chalk.white('[<] BACK')));
500
510
 
501
511
  drawBoxFooter(boxWidth);
502
512
 
@@ -565,8 +575,8 @@ const selectProviderOption = async (provider) => {
565
575
  const leftDesc1 = left.description[0] ? ' ' + left.description[0] : '';
566
576
  const rightDesc1 = right?.description[0] ? ' ' + right.description[0] : '';
567
577
  console.log(make2ColRow(
568
- chalk.gray(leftDesc1.length > col1Width - 2 ? leftDesc1.substring(0, col1Width - 5) + '...' : leftDesc1),
569
- chalk.gray(rightDesc1.length > col1Width - 2 ? rightDesc1.substring(0, col1Width - 5) + '...' : rightDesc1)
578
+ chalk.white(leftDesc1.length > col1Width - 2 ? leftDesc1.substring(0, col1Width - 5) + '...' : leftDesc1),
579
+ chalk.white(rightDesc1.length > col1Width - 2 ? rightDesc1.substring(0, col1Width - 5) + '...' : rightDesc1)
570
580
  ));
571
581
 
572
582
  // Second description line if exists
@@ -574,15 +584,15 @@ const selectProviderOption = async (provider) => {
574
584
  const rightDesc2 = right?.description[1] ? ' ' + right.description[1] : '';
575
585
  if (leftDesc2 || rightDesc2) {
576
586
  console.log(make2ColRow(
577
- chalk.gray(leftDesc2.length > col1Width - 2 ? leftDesc2.substring(0, col1Width - 5) + '...' : leftDesc2),
578
- chalk.gray(rightDesc2.length > col1Width - 2 ? rightDesc2.substring(0, col1Width - 5) + '...' : rightDesc2)
587
+ chalk.white(leftDesc2.length > col1Width - 2 ? leftDesc2.substring(0, col1Width - 5) + '...' : leftDesc2),
588
+ chalk.white(rightDesc2.length > col1Width - 2 ? rightDesc2.substring(0, col1Width - 5) + '...' : rightDesc2)
579
589
  ));
580
590
  }
581
591
 
582
592
  console.log(makeLine(''));
583
593
  }
584
594
 
585
- console.log(makeLine(chalk.gray('[<] BACK')));
595
+ console.log(makeLine(chalk.white('[<] BACK')));
586
596
 
587
597
  drawBoxFooter(boxWidth);
588
598
 
@@ -614,7 +624,7 @@ const openBrowser = (url) => {
614
624
  else cmd = `xdg-open "${url}"`;
615
625
 
616
626
  exec(cmd, (err) => {
617
- if (err) console.log(chalk.gray(' Could not open browser automatically'));
627
+ if (err) console.log(chalk.white(' Could not open browser automatically'));
618
628
  });
619
629
  };
620
630
 
@@ -697,7 +707,7 @@ const setupOAuthConnection = async (provider) => {
697
707
  console.log(makeLine(chalk.white('3. COPY THE AUTHORIZATION CODE')));
698
708
  console.log(makeLine(chalk.white('4. PASTE IT HERE')));
699
709
  console.log(makeLine(''));
700
- console.log(makeLine(chalk.gray('OPENING BROWSER IN 3 SECONDS...')));
710
+ console.log(makeLine(chalk.white('OPENING BROWSER IN 3 SECONDS...')));
701
711
 
702
712
  drawBoxFooter(boxWidth);
703
713
 
@@ -718,9 +728,9 @@ const setupOAuthConnection = async (provider) => {
718
728
  console.log(makeLine(chalk.white('AFTER LOGGING IN, YOU WILL SEE A CODE')));
719
729
  console.log(makeLine(chalk.white('COPY THE ENTIRE CODE AND PASTE IT BELOW')));
720
730
  console.log(makeLine(''));
721
- console.log(makeLine(chalk.gray('THE CODE LOOKS LIKE: abc123...#xyz789...')));
731
+ console.log(makeLine(chalk.white('THE CODE LOOKS LIKE: abc123...#xyz789...')));
722
732
  console.log(makeLine(''));
723
- console.log(makeLine(chalk.gray('TYPE < TO CANCEL')));
733
+ console.log(makeLine(chalk.white('TYPE < TO CANCEL')));
724
734
 
725
735
  drawBoxFooter(boxWidth);
726
736
  console.log();
@@ -766,8 +776,8 @@ const setupOAuthConnection = async (provider) => {
766
776
 
767
777
  if (!models || models.length === 0) {
768
778
  spinner.fail('COULD NOT FETCH MODELS FROM API');
769
- console.log(chalk.gray(' OAuth authentication may not support model listing.'));
770
- console.log(chalk.gray(' Please use API KEY authentication instead.'));
779
+ console.log(chalk.white(' OAuth authentication may not support model listing.'));
780
+ console.log(chalk.white(' Please use API KEY authentication instead.'));
771
781
  await prompts.waitForEnter();
772
782
  return await selectProviderOption(provider);
773
783
  }
@@ -785,8 +795,8 @@ const setupOAuthConnection = async (provider) => {
785
795
  await aiService.addAgent('anthropic', 'oauth_max', credentials, selectedModel, 'Claude Pro/Max');
786
796
 
787
797
  console.log(chalk.green('\n CONNECTED TO CLAUDE PRO/MAX'));
788
- console.log(chalk.gray(` MODEL: ${selectedModel}`));
789
- console.log(chalk.gray(' UNLIMITED USAGE WITH YOUR SUBSCRIPTION'));
798
+ console.log(chalk.white(` MODEL: ${selectedModel}`));
799
+ console.log(chalk.white(' UNLIMITED USAGE WITH YOUR SUBSCRIPTION'));
790
800
  } catch (error) {
791
801
  console.log(chalk.red(`\n FAILED TO SAVE: ${error.message}`));
792
802
  }
@@ -838,17 +848,17 @@ const setupConnection = async (provider, option) => {
838
848
  if (option.url && (field === 'apiKey' || field === 'sessionKey' || field === 'accessToken')) {
839
849
  console.log(makeLine(chalk.cyan('LINK: ') + chalk.green(option.url)));
840
850
  console.log(makeLine(''));
841
- console.log(makeLine(chalk.gray('OPENING BROWSER...')));
851
+ console.log(makeLine(chalk.white('OPENING BROWSER...')));
842
852
  openBrowser(option.url);
843
853
  }
844
854
 
845
855
  // Show default for endpoint
846
856
  if (field === 'endpoint' && option.defaultEndpoint) {
847
- console.log(makeLine(chalk.gray(`DEFAULT: ${option.defaultEndpoint}`)));
857
+ console.log(makeLine(chalk.white(`DEFAULT: ${option.defaultEndpoint}`)));
848
858
  }
849
859
 
850
860
  console.log(makeLine(''));
851
- console.log(makeLine(chalk.gray('TYPE < TO GO BACK')));
861
+ console.log(makeLine(chalk.white('TYPE < TO GO BACK')));
852
862
 
853
863
  drawBoxFooter(boxWidth);
854
864
  console.log();
@@ -858,33 +868,33 @@ const setupConnection = async (provider, option) => {
858
868
  switch (field) {
859
869
  case 'apiKey':
860
870
  value = await prompts.textInput(chalk.cyan('PASTE API KEY:'));
861
- if (!value || value === '<') return await selectProviderOption(provider);
871
+ if (!value || value.trim() === '<' || value.trim() === '') return await selectProviderOption(provider);
862
872
  credentials.apiKey = value.trim();
863
873
  break;
864
874
 
865
875
  case 'sessionKey':
866
876
  value = await prompts.textInput(chalk.cyan('PASTE SESSION KEY:'));
867
- if (!value || value === '<') return await selectProviderOption(provider);
877
+ if (!value || value.trim() === '<' || value.trim() === '') return await selectProviderOption(provider);
868
878
  credentials.sessionKey = value.trim();
869
879
  break;
870
880
 
871
881
  case 'accessToken':
872
882
  value = await prompts.textInput(chalk.cyan('PASTE ACCESS TOKEN:'));
873
- if (!value || value === '<') return await selectProviderOption(provider);
883
+ if (!value || value.trim() === '<' || value.trim() === '') return await selectProviderOption(provider);
874
884
  credentials.accessToken = value.trim();
875
885
  break;
876
886
 
877
887
  case 'endpoint':
878
888
  const defaultEndpoint = option.defaultEndpoint || '';
879
889
  value = await prompts.textInput(chalk.cyan(`ENDPOINT [${defaultEndpoint || 'required'}]:`));
880
- if (value === '<') return await selectProviderOption(provider);
890
+ if (value && value.trim() === '<') return await selectProviderOption(provider);
881
891
  credentials.endpoint = (value || defaultEndpoint).trim();
882
892
  if (!credentials.endpoint) return await selectProviderOption(provider);
883
893
  break;
884
894
 
885
895
  case 'model':
886
896
  value = await prompts.textInput(chalk.cyan('MODEL NAME:'));
887
- if (!value || value === '<') return await selectProviderOption(provider);
897
+ if (!value || value.trim() === '<' || value.trim() === '') return await selectProviderOption(provider);
888
898
  credentials.model = value.trim();
889
899
  break;
890
900
  }
@@ -910,10 +920,10 @@ const setupConnection = async (provider, option) => {
910
920
 
911
921
  // Show available models for local providers
912
922
  if (validation.models && validation.models.length > 0) {
913
- console.log(chalk.gray(` AVAILABLE MODELS: ${validation.models.slice(0, 5).join(', ')}`));
923
+ console.log(chalk.white(` AVAILABLE MODELS: ${validation.models.slice(0, 5).join(', ')}`));
914
924
  }
915
925
 
916
- console.log(chalk.gray(` USING MODEL: ${model}`));
926
+ console.log(chalk.white(` USING MODEL: ${model}`));
917
927
  } catch (error) {
918
928
  spinner.fail(`FAILED TO SAVE: ${error.message}`);
919
929
  }
@@ -946,7 +956,7 @@ const selectModelFromList = async (models, providerName) => {
946
956
 
947
957
  if (!models || models.length === 0) {
948
958
  console.log(makeLine(chalk.red('NO MODELS AVAILABLE')));
949
- console.log(makeLine(chalk.gray('[<] BACK')));
959
+ console.log(makeLine(chalk.white('[<] BACK')));
950
960
  drawBoxFooter(boxWidth);
951
961
  await prompts.waitForEnter();
952
962
  return null;
@@ -955,14 +965,44 @@ const selectModelFromList = async (models, providerName) => {
955
965
  // Sort models (newest first)
956
966
  const sortedModels = [...models].sort((a, b) => b.localeCompare(a));
957
967
 
958
- // Display models from API
959
- sortedModels.forEach((model, index) => {
960
- const displayModel = model.length > W - 10 ? model.substring(0, W - 13) + '...' : model;
961
- console.log(makeLine(chalk.cyan(`[${index + 1}] ${displayModel}`)));
962
- });
968
+ // Display models in 2 columns
969
+ const rows = Math.ceil(sortedModels.length / 2);
970
+ const colWidth = Math.floor((W - 4) / 2);
971
+
972
+ for (let i = 0; i < rows; i++) {
973
+ const leftIndex = i;
974
+ const rightIndex = i + rows;
975
+
976
+ // Left column
977
+ const leftModel = sortedModels[leftIndex];
978
+ const leftNum = chalk.cyan(`[${leftIndex + 1}]`);
979
+ const leftName = leftModel.length > colWidth - 6
980
+ ? leftModel.substring(0, colWidth - 9) + '...'
981
+ : leftModel;
982
+ const leftText = `${leftNum} ${chalk.yellow(leftName)}`;
983
+ const leftPlain = `[${leftIndex + 1}] ${leftName}`;
984
+
985
+ // Right column (if exists)
986
+ let rightText = '';
987
+ let rightPlain = '';
988
+ if (rightIndex < sortedModels.length) {
989
+ const rightModel = sortedModels[rightIndex];
990
+ const rightNum = chalk.cyan(`[${rightIndex + 1}]`);
991
+ const rightName = rightModel.length > colWidth - 6
992
+ ? rightModel.substring(0, colWidth - 9) + '...'
993
+ : rightModel;
994
+ rightText = `${rightNum} ${chalk.yellow(rightName)}`;
995
+ rightPlain = `[${rightIndex + 1}] ${rightName}`;
996
+ }
997
+
998
+ // Pad left column and combine
999
+ const leftPadding = colWidth - leftPlain.length;
1000
+ const line = leftText + ' '.repeat(Math.max(2, leftPadding)) + rightText;
1001
+ console.log(makeLine(line));
1002
+ }
963
1003
 
964
1004
  console.log(makeLine(''));
965
- console.log(makeLine(chalk.gray('[<] BACK')));
1005
+ console.log(makeLine(chalk.white('[<] BACK')));
966
1006
 
967
1007
  drawBoxFooter(boxWidth);
968
1008
 
@@ -998,7 +1038,7 @@ const selectModel = async (agent) => {
998
1038
  displayBanner();
999
1039
  drawBoxHeaderContinue(`SELECT MODEL - ${agent.name}`, boxWidth);
1000
1040
 
1001
- console.log(makeLine(chalk.gray('FETCHING AVAILABLE MODELS FROM API...')));
1041
+ console.log(makeLine(chalk.white('FETCHING AVAILABLE MODELS FROM API...')));
1002
1042
  drawBoxFooter(boxWidth);
1003
1043
 
1004
1044
  // Fetch models from real API
@@ -1033,9 +1073,9 @@ const selectModel = async (agent) => {
1033
1073
 
1034
1074
  if (!models || models.length === 0) {
1035
1075
  console.log(makeLine(chalk.red('COULD NOT FETCH MODELS FROM API')));
1036
- console.log(makeLine(chalk.gray('Check your API key or network connection.')));
1076
+ console.log(makeLine(chalk.white('Check your API key or network connection.')));
1037
1077
  console.log(makeLine(''));
1038
- console.log(makeLine(chalk.gray('[<] BACK')));
1078
+ console.log(makeLine(chalk.white('[<] BACK')));
1039
1079
  drawBoxFooter(boxWidth);
1040
1080
 
1041
1081
  await prompts.waitForEnter();
@@ -1045,15 +1085,46 @@ const selectModel = async (agent) => {
1045
1085
  // Sort models (newest first typically)
1046
1086
  models.sort((a, b) => b.localeCompare(a));
1047
1087
 
1048
- // Display models from API
1049
- models.forEach((model, index) => {
1050
- const displayModel = model.length > W - 10 ? model.substring(0, W - 13) + '...' : model;
1051
- const currentMarker = model === agent.model ? chalk.yellow(' (CURRENT)') : '';
1052
- console.log(makeLine(chalk.cyan(`[${index + 1}] ${displayModel}`) + currentMarker));
1053
- });
1088
+ // Display models in 2 columns
1089
+ const rows = Math.ceil(models.length / 2);
1090
+ const colWidth = Math.floor((W - 4) / 2);
1091
+
1092
+ for (let i = 0; i < rows; i++) {
1093
+ const leftIndex = i;
1094
+ const rightIndex = i + rows;
1095
+
1096
+ // Left column
1097
+ const leftModel = models[leftIndex];
1098
+ const leftNum = chalk.cyan(`[${leftIndex + 1}]`);
1099
+ const leftCurrent = leftModel === agent.model ? chalk.green(' *') : '';
1100
+ const leftName = leftModel.length > colWidth - 8
1101
+ ? leftModel.substring(0, colWidth - 11) + '...'
1102
+ : leftModel;
1103
+ const leftText = `${leftNum} ${chalk.yellow(leftName)}${leftCurrent}`;
1104
+ const leftPlain = `[${leftIndex + 1}] ${leftName}${leftModel === agent.model ? ' *' : ''}`;
1105
+
1106
+ // Right column (if exists)
1107
+ let rightText = '';
1108
+ let rightPlain = '';
1109
+ if (rightIndex < models.length) {
1110
+ const rightModel = models[rightIndex];
1111
+ const rightNum = chalk.cyan(`[${rightIndex + 1}]`);
1112
+ const rightCurrent = rightModel === agent.model ? chalk.green(' *') : '';
1113
+ const rightName = rightModel.length > colWidth - 8
1114
+ ? rightModel.substring(0, colWidth - 11) + '...'
1115
+ : rightModel;
1116
+ rightText = `${rightNum} ${chalk.yellow(rightName)}${rightCurrent}`;
1117
+ rightPlain = `[${rightIndex + 1}] ${rightName}${rightModel === agent.model ? ' *' : ''}`;
1118
+ }
1119
+
1120
+ // Pad left column and combine
1121
+ const leftPadding = colWidth - leftPlain.length;
1122
+ const line = leftText + ' '.repeat(Math.max(2, leftPadding)) + rightText;
1123
+ console.log(makeLine(line));
1124
+ }
1054
1125
 
1055
1126
  console.log(makeLine(''));
1056
- console.log(makeLine(chalk.gray('[<] BACK')));
1127
+ console.log(makeLine(chalk.white('[<] BACK') + chalk.white(' * = CURRENT')));
1057
1128
 
1058
1129
  drawBoxFooter(boxWidth);
1059
1130
 
@@ -336,7 +336,7 @@ const PROVIDERS = {
336
336
  baichuan: {
337
337
  id: 'baichuan',
338
338
  name: 'BAICHUAN',
339
- description: 'Chinese language specialist',
339
+ description: 'Multilingual AI model',
340
340
  category: 'direct',
341
341
  models: ['Baichuan4', 'Baichuan3-Turbo', 'Baichuan2-Turbo'],
342
342
  defaultModel: 'Baichuan4',