yymaxapi 1.0.52 → 1.0.53

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.
Files changed (2) hide show
  1. package/bin/yymaxapi.js +71 -151
  2. package/package.json +1 -1
package/bin/yymaxapi.js CHANGED
@@ -88,36 +88,24 @@ const FALLBACK_ENDPOINTS = [
88
88
  ];
89
89
 
90
90
  const DEFAULT_CLAUDE_MODELS = [
91
- {
92
- "id": "claude-opus-4-6",
93
- "name": "Claude Opus 4.6"
94
- },
95
- {
96
- "id": "claude-opus-4-6-Thinking",
97
- "name": "Claude Opus 4.6 Thinking"
98
- },
99
91
  {
100
92
  "id": "claude-sonnet-4-6",
101
93
  "name": "Claude Sonnet 4.6"
102
94
  },
103
95
  {
104
- "id": "claude-sonnet-4-6-Thinking",
105
- "name": "Claude Sonnet 4.6 Thinking"
106
- },
107
- {
108
- "id": "claude-haiku-4-5",
109
- "name": "Claude Haiku 4.5"
96
+ "id": "claude-opus-4-6",
97
+ "name": "Claude Opus 4.6 (待恢复)"
110
98
  }
111
99
  ];
112
100
 
113
101
  const DEFAULT_CODEX_MODELS = [
114
102
  {
115
- "id": "gpt-5.3-codex",
116
- "name": "GPT 5.3 Codex"
103
+ "id": "gpt-5.4",
104
+ "name": "GPT 5.4"
117
105
  },
118
106
  {
119
- "id": "gpt-5.2",
120
- "name": "GPT 5.2"
107
+ "id": "gpt-5.4-pro",
108
+ "name": "GPT 5.4 Pro (待支持)"
121
109
  }
122
110
  ];
123
111
 
@@ -132,8 +120,8 @@ const DEFAULT_API_CONFIG = {
132
120
  "codex": {
133
121
  "urlSuffix": "/codex",
134
122
  "api": "openai-responses",
135
- "contextWindow": 128000,
136
- "maxTokens": 32768,
123
+ "contextWindow": 1050000,
124
+ "maxTokens": 128000,
137
125
  "providerName": "yunyi"
138
126
  }
139
127
  };
@@ -702,7 +690,7 @@ function writeCodexConfig(baseUrl, apiKey) {
702
690
  }
703
691
  const section = [
704
692
  marker,
705
- `model = "gpt-5.3-codex"`,
693
+ `model = "gpt-5.4"`,
706
694
  `model_provider = "${providerKey}"`,
707
695
  ``,
708
696
  `[model_providers.${providerKey}]`,
@@ -2598,50 +2586,13 @@ async function presetCodex(paths, args = {}) {
2598
2586
 
2599
2587
  // ============ 一键激活(同时配置 Claude Code + Codex) ============
2600
2588
  async function autoActivate(paths, args = {}) {
2601
- console.log(chalk.cyan.bold('\n🚀 一键激活(同时配置 Claude Code + Codex)\n'));
2589
+ console.log(chalk.cyan.bold('\n🚀 一键激活\n'));
2602
2590
 
2603
2591
  const claudeApiConfig = API_CONFIG.claude;
2604
2592
  const codexApiConfig = API_CONFIG.codex;
2605
2593
  const claudeProviderName = claudeApiConfig.providerName;
2606
2594
  const codexProviderName = codexApiConfig.providerName;
2607
-
2608
- // ---- 测速选节点 ----
2609
- const shouldTest = !(args['no-test'] || args.noTest);
2610
- let selectedEndpoint = ENDPOINTS[0];
2611
-
2612
- if (shouldTest) {
2613
- console.log(chalk.cyan('📡 开始测速节点...\n'));
2614
- const speedResult = await testAllEndpoints(ENDPOINTS, { autoFallback: true });
2615
-
2616
- const sorted = speedResult.ranked || [];
2617
- if (sorted.length > 0) {
2618
- const defaultEp = ENDPOINTS[0];
2619
- const { selectedIndex } = await inquirer.prompt([{
2620
- type: 'list',
2621
- name: 'selectedIndex',
2622
- message: '选择节点:',
2623
- choices: [
2624
- { name: `* 使用默认节点 (${defaultEp.name})`, value: -1 },
2625
- new inquirer.Separator(' ---- 或按测速结果选择 ----'),
2626
- ...sorted.map((e, i) => ({
2627
- name: `${e.name} - ${e.latency}ms (评分:${e.score})`,
2628
- value: i
2629
- }))
2630
- ]
2631
- }]);
2632
- selectedEndpoint = selectedIndex === -1 ? defaultEp : sorted[selectedIndex];
2633
- if (speedResult.usedFallback) {
2634
- console.log(chalk.yellow(`\n⚠ 当前使用备用节点\n`));
2635
- }
2636
- } else {
2637
- console.log(chalk.red('\n⚠️ 所有节点(含备用)均不可达'));
2638
- const { proceed } = await inquirer.prompt([{
2639
- type: 'confirm', name: 'proceed',
2640
- message: '仍要写入默认节点配置吗?', default: false
2641
- }]);
2642
- if (!proceed) { console.log(chalk.gray('已取消')); return; }
2643
- }
2644
- }
2595
+ const selectedEndpoint = ENDPOINTS[0];
2645
2596
 
2646
2597
  // ---- API Key ----
2647
2598
  const apiKeyEnvFallbacks = [
@@ -2657,7 +2608,7 @@ async function autoActivate(paths, args = {}) {
2657
2608
  apiKey = directKey;
2658
2609
  } else {
2659
2610
  const envKey = getApiKeyFromArgs({}, apiKeyEnvFallbacks);
2660
- apiKey = await promptApiKey('请输入 API Key(同时用于 Claude Code 和 Codex):', envKey || '');
2611
+ apiKey = await promptApiKey('请输入 API Key:', envKey || '');
2661
2612
  }
2662
2613
  if (!apiKey) { console.log(chalk.gray('已取消')); return; }
2663
2614
 
@@ -2672,51 +2623,67 @@ async function autoActivate(paths, args = {}) {
2672
2623
  if (!continueAnyway) { console.log(chalk.gray('已取消')); return; }
2673
2624
  }
2674
2625
 
2675
- // ---- 构建配置 ----
2676
- const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
2677
-
2678
- const claudeBaseUrl = buildFullUrl(selectedEndpoint.url, 'claude');
2679
- const codexBaseUrl = buildFullUrl(selectedEndpoint.url, 'codex');
2680
-
2681
- // 检测单一模式:Claude 和 Codex 只有一个模型且 id 相同(如 maxapi 的 heibai)
2626
+ // ---- 选模型(Claude + GPT 合并展示) ----
2682
2627
  const isSingleMode = CLAUDE_MODELS.length === 1 && CODEX_MODELS.length === 1
2683
2628
  && CLAUDE_MODELS[0].id === CODEX_MODELS[0].id;
2684
2629
 
2685
- let claudeModelId, codexModelId;
2630
+ let selectedModelId;
2631
+ let selectedType; // 'claude' or 'codex'
2686
2632
 
2687
2633
  if (isSingleMode) {
2688
- // 单一模式:固定模型,不选择,不分 Claude/Codex
2689
- claudeModelId = CLAUDE_MODELS[0].id;
2690
- codexModelId = CODEX_MODELS[0].id;
2634
+ selectedModelId = CLAUDE_MODELS[0].id;
2635
+ selectedType = 'claude';
2691
2636
  } else {
2692
- // 多模型模式:让用户选模型
2693
- claudeModelId = (args['claude-model'] || '').toString().trim();
2694
- if (!claudeModelId && CLAUDE_MODELS.length > 1) {
2637
+ const modelArg = (args.model || args['claude-model'] || args['codex-model'] || '').toString().trim();
2638
+ if (modelArg) {
2639
+ const inClaude = CLAUDE_MODELS.find(m => m.id === modelArg);
2640
+ const inCodex = CODEX_MODELS.find(m => m.id === modelArg);
2641
+ selectedModelId = modelArg;
2642
+ selectedType = inClaude ? 'claude' : inCodex ? 'codex' : 'claude';
2643
+ } else {
2644
+ const allChoices = [];
2645
+ if (CLAUDE_MODELS.length > 0) {
2646
+ allChoices.push(new inquirer.Separator(' -- Claude --'));
2647
+ for (const m of CLAUDE_MODELS) {
2648
+ allChoices.push({ name: m.name, value: `claude:${m.id}` });
2649
+ }
2650
+ }
2651
+ if (CODEX_MODELS.length > 0) {
2652
+ allChoices.push(new inquirer.Separator(' -- GPT --'));
2653
+ for (const m of CODEX_MODELS) {
2654
+ allChoices.push({ name: m.name, value: `codex:${m.id}` });
2655
+ }
2656
+ }
2657
+
2695
2658
  const { picked } = await inquirer.prompt([{
2696
2659
  type: 'list',
2697
2660
  name: 'picked',
2698
- message: '选择 Claude 模型:',
2699
- choices: CLAUDE_MODELS.map(m => ({ name: m.name, value: m.id })),
2700
- default: CLAUDE_MODELS[0].id
2661
+ message: '选择模型:',
2662
+ choices: allChoices,
2663
+ default: `claude:${CLAUDE_MODELS[0].id}`
2701
2664
  }]);
2702
- claudeModelId = picked;
2703
- }
2704
- if (!claudeModelId) claudeModelId = CLAUDE_MODELS[0]?.id || 'claude-sonnet-4-6';
2705
2665
 
2706
- codexModelId = (args['codex-model'] || '').toString().trim();
2707
- if (!codexModelId && CODEX_MODELS.length > 1) {
2708
- const { pickedCodex } = await inquirer.prompt([{
2709
- type: 'list',
2710
- name: 'pickedCodex',
2711
- message: '选择 Codex 模型:',
2712
- choices: CODEX_MODELS.map(m => ({ name: m.name, value: m.id })),
2713
- default: CODEX_MODELS[0].id
2714
- }]);
2715
- codexModelId = pickedCodex;
2666
+ const [pickedType, pickedId] = picked.split(':');
2667
+ selectedType = pickedType;
2668
+ selectedModelId = pickedId;
2716
2669
  }
2717
- if (!codexModelId) codexModelId = CODEX_MODELS[0]?.id || 'gpt-5.3-codex';
2718
2670
  }
2719
2671
 
2672
+ // ---- 构建配置 ----
2673
+ const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
2674
+
2675
+ const claudeBaseUrl = buildFullUrl(selectedEndpoint.url, 'claude');
2676
+ const codexBaseUrl = buildFullUrl(selectedEndpoint.url, 'codex');
2677
+
2678
+ // 根据用户选择确定主模型
2679
+ const isClaudePrimary = selectedType === 'claude';
2680
+ const claudeModelId = isClaudePrimary
2681
+ ? selectedModelId
2682
+ : CLAUDE_MODELS[0]?.id || 'claude-sonnet-4-6';
2683
+ const codexModelId = !isClaudePrimary
2684
+ ? selectedModelId
2685
+ : CODEX_MODELS[0]?.id || 'gpt-5.4';
2686
+
2720
2687
  const claudeModel = CLAUDE_MODELS.find(m => m.id === claudeModelId) || { id: claudeModelId, name: claudeModelId };
2721
2688
  const codexModel = CODEX_MODELS.find(m => m.id === codexModelId) || { id: codexModelId, name: codexModelId };
2722
2689
  const claudeModelKey = `${claudeProviderName}/${claudeModelId}`;
@@ -2740,7 +2707,7 @@ async function autoActivate(paths, args = {}) {
2740
2707
  config.auth.profiles[`${claudeProviderName}:default`] = { provider: claudeProviderName, mode: 'api_key' };
2741
2708
  config.agents.defaults.models[claudeModelKey] = { alias: claudeProviderName };
2742
2709
 
2743
- // 写入 Codex provider(单一模式下仍写入,保证配置完整)
2710
+ // 写入 Codex provider
2744
2711
  config.models.providers[codexProviderName] = {
2745
2712
  baseUrl: codexBaseUrl,
2746
2713
  auth: DEFAULT_AUTH_MODE,
@@ -2758,34 +2725,9 @@ async function autoActivate(paths, args = {}) {
2758
2725
  config.auth.profiles[`${codexProviderName}:default`] = { provider: codexProviderName, mode: 'api_key' };
2759
2726
  config.agents.defaults.models[codexModelKey] = { alias: codexProviderName };
2760
2727
 
2761
- // ---- 选择主力 ----
2762
- let primaryModelKey, fallbackModelKey;
2763
- if (isSingleMode) {
2764
- // 单一模式:直接用 Claude provider 作为 primary,不需要用户选
2765
- primaryModelKey = claudeModelKey;
2766
- fallbackModelKey = codexModelKey;
2767
- } else {
2768
- let primaryType = 'claude';
2769
- if (args.primary === 'claude') {
2770
- primaryType = 'claude';
2771
- } else if (args.primary === 'codex') {
2772
- primaryType = 'codex';
2773
- } else {
2774
- const { picked } = await inquirer.prompt([{
2775
- type: 'list',
2776
- name: 'picked',
2777
- message: '选择主力工具(默认启动哪个):',
2778
- choices: [
2779
- { name: 'Claude Code', value: 'claude' },
2780
- { name: 'Codex (GPT)', value: 'codex' }
2781
- ]
2782
- }]);
2783
- primaryType = picked;
2784
- }
2785
- primaryModelKey = primaryType === 'claude' ? claudeModelKey : codexModelKey;
2786
- fallbackModelKey = primaryType === 'claude' ? codexModelKey : claudeModelKey;
2787
- }
2788
-
2728
+ // 主模型 = 用户选的,备选 = 另一个
2729
+ const primaryModelKey = isClaudePrimary ? claudeModelKey : codexModelKey;
2730
+ const fallbackModelKey = isClaudePrimary ? codexModelKey : claudeModelKey;
2789
2731
  config.agents.defaults.model.primary = primaryModelKey;
2790
2732
  config.agents.defaults.model.fallbacks = [fallbackModelKey];
2791
2733
 
@@ -2802,19 +2744,11 @@ async function autoActivate(paths, args = {}) {
2802
2744
  writeSpinner.succeed('配置写入完成');
2803
2745
 
2804
2746
  // ---- 输出结果 ----
2805
- console.log(chalk.green('\n✅ 一键激活完成!'));
2806
- if (isSingleMode) {
2807
- console.log(chalk.cyan(` 节点: ${selectedEndpoint.url}`));
2808
- console.log(chalk.gray(` 模型: ${claudeModel.name}`));
2809
- } else {
2810
- const primaryType = primaryModelKey === claudeModelKey ? 'claude' : 'codex';
2811
- const primaryTag = primaryType === 'claude' ? ' (主)' : '';
2812
- const codexTag = primaryType === 'codex' ? ' (主)' : '';
2813
- console.log(chalk.cyan(` Claude Code${primaryTag}: ${claudeBaseUrl}`));
2814
- console.log(chalk.gray(` 模型: ${claudeModel.name}`));
2815
- console.log(chalk.cyan(` Codex${codexTag}: ${codexBaseUrl}`));
2816
- console.log(chalk.gray(` 模型: ${codexModel.name}`));
2817
- }
2747
+ const primaryLabel = isClaudePrimary ? 'Claude' : 'GPT';
2748
+ const selectedModel = isClaudePrimary ? claudeModel : codexModel;
2749
+ console.log(chalk.green('\n✅ 配置完成!'));
2750
+ console.log(chalk.cyan(` 模型: ${selectedModel.name} (${primaryLabel})`));
2751
+ console.log(chalk.gray(` 节点: ${selectedEndpoint.url} (${selectedEndpoint.name})`));
2818
2752
  console.log(chalk.gray(' API Key: 已设置'));
2819
2753
  if (extSynced.length > 0) console.log(chalk.gray(` 同步: ${extSynced.join(', ')}`));
2820
2754
 
@@ -2824,20 +2758,6 @@ async function autoActivate(paths, args = {}) {
2824
2758
  console.log(chalk.green(`\n🌐 Web Dashboard:`));
2825
2759
  console.log(chalk.cyan(` http://127.0.0.1:${gwPort}/?token=${gwToken}`));
2826
2760
  }
2827
-
2828
- // ---- 测试连接 ----
2829
- const shouldTestGateway = args.test !== undefined
2830
- ? !['false', '0', 'no'].includes(String(args.test).toLowerCase())
2831
- : await inquirer.prompt([{
2832
- type: 'confirm',
2833
- name: 'testGateway',
2834
- message: '是否立即通过 OpenClaw Gateway 测试?',
2835
- default: true
2836
- }]).then(r => r.testGateway);
2837
-
2838
- if (shouldTestGateway) {
2839
- await testConnection(paths, args);
2840
- }
2841
2761
  }
2842
2762
 
2843
2763
  // ============ 单独配置 Claude Code CLI ============
@@ -3112,8 +3032,8 @@ async function yycodeQuickSetup(paths) {
3112
3032
 
3113
3033
  // Codex 侧
3114
3034
  const codexBaseUrl = buildFullUrl(selectedEndpoint.url, 'codex');
3115
- const codexModelId = 'gpt-5.3-codex';
3116
- const codexModel = CODEX_MODELS.find(m => m.id === codexModelId) || { id: codexModelId, name: 'GPT 5.3 Codex' };
3035
+ const codexModelId = CODEX_MODELS[0]?.id || 'gpt-5.4';
3036
+ const codexModel = CODEX_MODELS.find(m => m.id === codexModelId) || { id: codexModelId, name: 'GPT 5.4' };
3117
3037
  const codexModelKey = `${codexProviderName}/${codexModelId}`;
3118
3038
 
3119
3039
  config.models.providers[codexProviderName] = {
@@ -4497,7 +4417,7 @@ function testCodexApi(baseUrl, apiKey, model) {
4497
4417
  const protocol = urlObj.protocol === 'https:' ? https : http;
4498
4418
 
4499
4419
  const postData = JSON.stringify({
4500
- model: model || 'gpt-5.2',
4420
+ model: model || 'gpt-5.4',
4501
4421
  input: '你是哪个模型?请用一句话回答你的模型名称和版本。'
4502
4422
  });
4503
4423
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yymaxapi",
3
- "version": "1.0.52",
3
+ "version": "1.0.53",
4
4
  "description": "跨平台 OpenClaw/Clawdbot 配置管理工具 - 管理中转地址、模型切换、API Keys、测速优化",
5
5
  "main": "bin/yymaxapi.js",
6
6
  "bin": {