hedgequantx 2.6.98 → 2.6.100

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.6.98",
3
+ "version": "2.6.100",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -782,9 +782,7 @@ const getOAuthConfig = (providerId) => {
782
782
 
783
783
  /**
784
784
  * Setup OAuth connection for any provider with OAuth support
785
- * Automatically detects environment and uses the appropriate method:
786
- * - Local (PC/Mac): Uses CLIProxyAPI for automatic token management
787
- * - Remote (VPS/Server): Uses cli.hedgequantx.com as OAuth relay
785
+ * Unified flow: copy code from URL (works on local and VPS)
788
786
  */
789
787
  const setupOAuthConnection = async (provider) => {
790
788
  const config = getOAuthConfig(provider.id);
@@ -794,47 +792,8 @@ const setupOAuthConnection = async (provider) => {
794
792
  return await selectProviderOption(provider);
795
793
  }
796
794
 
797
- // Check if we can open a browser locally
798
- const canUseBrowser = proxyManager.canOpenBrowser();
799
- const isServer = proxyManager.isServerEnvironment();
800
-
801
- // If on server or can't open browser, use remote OAuth
802
- if (isServer || !canUseBrowser) {
803
- // Only anthropic is supported for remote OAuth currently
804
- if (provider.id === 'anthropic') {
805
- return await setupRemoteOAuth(provider, config);
806
- } else {
807
- // For other providers on VPS, show message
808
- const boxWidth = getLogoWidth();
809
- const W = boxWidth - 2;
810
- const makeLine = (content) => {
811
- const plainLen = content.replace(/\x1b\[[0-9;]*m/g, '').length;
812
- const padding = W - plainLen;
813
- return chalk.cyan('║') + ' ' + content + ' '.repeat(Math.max(0, padding - 1)) + chalk.cyan('║');
814
- };
815
-
816
- console.clear();
817
- displayBanner();
818
- drawBoxHeaderContinue('SERVER DETECTED', boxWidth);
819
-
820
- console.log(makeLine(chalk.yellow('VPS/SERVER ENVIRONMENT DETECTED')));
821
- console.log(makeLine(''));
822
- console.log(makeLine(chalk.white('OAuth for this provider requires a browser.')));
823
- console.log(makeLine(''));
824
- console.log(makeLine(chalk.white('OPTIONS:')));
825
- console.log(makeLine(chalk.cyan('1. Use Claude (supports remote OAuth)')));
826
- console.log(makeLine(chalk.cyan('2. Use API Key instead of OAuth')));
827
- console.log(makeLine(chalk.cyan('3. Run this on a local machine first')));
828
- console.log(makeLine(''));
829
-
830
- drawBoxFooter(boxWidth);
831
- await prompts.waitForEnter();
832
- return await selectProviderOption(provider);
833
- }
834
- }
835
-
836
- // Local machine - use CLIProxyAPI
837
- return await setupProxyOAuth(provider, config);
795
+ // Use unified manual flow for all providers and environments
796
+ return await setupRemoteOAuth(provider, config);
838
797
  };
839
798
 
840
799
  /**
@@ -851,8 +810,24 @@ const setupRemoteOAuth = async (provider, config) => {
851
810
  return chalk.cyan('║') + ' ' + content + ' '.repeat(Math.max(0, padding - 1)) + chalk.cyan('║');
852
811
  };
853
812
 
854
- // Generate OAuth URL using the existing oauth module
855
- const authResult = oauthAnthropic.authorize('max');
813
+ // Get the right OAuth module for this provider
814
+ const oauthModules = {
815
+ anthropic: oauthAnthropic,
816
+ openai: oauthOpenai,
817
+ gemini: oauthGemini,
818
+ qwen: oauthQwen,
819
+ iflow: oauthIflow
820
+ };
821
+
822
+ const oauthModule = oauthModules[provider.id];
823
+ if (!oauthModule) {
824
+ console.log(chalk.red(`OAuth not supported for ${provider.id}`));
825
+ await prompts.waitForEnter();
826
+ return await selectProviderOption(provider);
827
+ }
828
+
829
+ // Generate OAuth URL using the provider's oauth module
830
+ const authResult = oauthModule.authorize(config.optionId || 'max');
856
831
  const url = authResult.url;
857
832
  const verifier = authResult.verifier;
858
833
 
@@ -895,7 +870,7 @@ const setupRemoteOAuth = async (provider, config) => {
895
870
  // Exchange code for tokens
896
871
  const spinner = ora({ text: 'Exchanging code for tokens...', color: 'cyan' }).start();
897
872
 
898
- const result = await oauthAnthropic.exchange(code.trim(), verifier);
873
+ const result = await oauthModule.exchange(code.trim(), verifier);
899
874
 
900
875
  if (result.type === 'failed') {
901
876
  spinner.fail(`Authentication failed: ${result.error || 'Invalid code'}`);
@@ -922,23 +897,30 @@ const setupRemoteOAuth = async (provider, config) => {
922
897
 
923
898
  let models = [];
924
899
  try {
925
- const { fetchAnthropicModelsOAuth } = require('../services/ai/client');
926
- models = await fetchAnthropicModelsOAuth(result.access);
900
+ const { fetchModelsWithOAuth } = require('../services/ai/client');
901
+ models = await fetchModelsWithOAuth(provider.id, result.access);
927
902
  } catch (e) {
928
- // Ignore - will use defaults
903
+ // API failed - will prompt for manual input
929
904
  }
930
905
 
931
- // Use defaults if API doesn't return models
932
- if (!models || models.length === 0) {
933
- models = getDefaultModelsForProvider(provider.id);
934
- }
935
-
936
- spinner.succeed(`Found ${models.length} models`);
906
+ let selectedModel;
937
907
 
938
- // Let user select model
939
- const selectedModel = await selectModelFromList(models, config.name);
940
- if (!selectedModel) {
941
- return await selectProviderOption(provider);
908
+ if (!models || models.length === 0) {
909
+ spinner.warn('Could not fetch models from API');
910
+
911
+ // Prompt user to enter model name manually
912
+ selectedModel = await promptForModelName(config.name);
913
+ if (!selectedModel) {
914
+ return await selectProviderOption(provider);
915
+ }
916
+ } else {
917
+ spinner.succeed(`Found ${models.length} models`);
918
+
919
+ // Let user select model from list
920
+ selectedModel = await selectModelFromList(models, config.name);
921
+ if (!selectedModel) {
922
+ return await selectProviderOption(provider);
923
+ }
942
924
  }
943
925
 
944
926
  // Add agent
@@ -957,33 +939,22 @@ const setupRemoteOAuth = async (provider, config) => {
957
939
  };
958
940
 
959
941
  /**
960
- * Get default models for a provider (used when we can't query the API)
942
+ * Prompt user to enter model name manually when API doesn't return models
961
943
  */
962
- const getDefaultModelsForProvider = (providerId) => {
963
- // These are fetched from provider APIs - not hardcoded fallbacks
964
- // They represent the known model IDs that the provider supports
965
- const models = {
966
- anthropic: [
967
- 'claude-sonnet-4-20250514',
968
- 'claude-opus-4-20250514',
969
- 'claude-3-5-sonnet-20241022',
970
- 'claude-3-5-haiku-20241022',
971
- 'claude-3-opus-20240229'
972
- ],
973
- openai: [
974
- 'gpt-4o',
975
- 'gpt-4o-mini',
976
- 'gpt-4-turbo',
977
- 'o1-preview',
978
- 'o1-mini'
979
- ],
980
- gemini: [
981
- 'gemini-2.0-flash-exp',
982
- 'gemini-1.5-pro',
983
- 'gemini-1.5-flash'
984
- ]
985
- };
986
- return models[providerId] || [];
944
+ const promptForModelName = async (providerName) => {
945
+ console.log();
946
+ console.log(chalk.yellow(' Could not fetch models from API.'));
947
+ console.log(chalk.white(' Please enter the model name manually.'));
948
+ console.log(chalk.gray(' (Check provider docs for available models)'));
949
+ console.log();
950
+
951
+ const modelName = await prompts.textInput(chalk.cyan('MODEL NAME:'));
952
+
953
+ if (!modelName || modelName.trim() === '' || modelName.trim() === '<') {
954
+ return null;
955
+ }
956
+
957
+ return modelName.trim();
987
958
  };
988
959
 
989
960
  /**