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.
- package/bin/yymaxapi.js +71 -151
- 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-
|
|
105
|
-
"name": "Claude
|
|
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.
|
|
116
|
-
"name": "GPT 5.
|
|
103
|
+
"id": "gpt-5.4",
|
|
104
|
+
"name": "GPT 5.4"
|
|
117
105
|
},
|
|
118
106
|
{
|
|
119
|
-
"id": "gpt-5.
|
|
120
|
-
"name": "GPT 5.
|
|
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":
|
|
136
|
-
"maxTokens":
|
|
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.
|
|
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🚀
|
|
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
|
|
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
|
|
2630
|
+
let selectedModelId;
|
|
2631
|
+
let selectedType; // 'claude' or 'codex'
|
|
2686
2632
|
|
|
2687
2633
|
if (isSingleMode) {
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
codexModelId = CODEX_MODELS[0].id;
|
|
2634
|
+
selectedModelId = CLAUDE_MODELS[0].id;
|
|
2635
|
+
selectedType = 'claude';
|
|
2691
2636
|
} else {
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
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: '
|
|
2699
|
-
choices:
|
|
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
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
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
|
-
|
|
2763
|
-
|
|
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
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
}
|
|
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.
|
|
3116
|
-
const codexModel = CODEX_MODELS.find(m => m.id === codexModelId) || { id: codexModelId, name: 'GPT 5.
|
|
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.
|
|
4420
|
+
model: model || 'gpt-5.4',
|
|
4501
4421
|
input: '你是哪个模型?请用一句话回答你的模型名称和版本。'
|
|
4502
4422
|
});
|
|
4503
4423
|
|