yymaxapi 1.0.45 → 1.0.47
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 +108 -68
- package/package.json +1 -1
package/bin/yymaxapi.js
CHANGED
|
@@ -2660,22 +2660,7 @@ async function autoActivate(paths, args = {}) {
|
|
|
2660
2660
|
// ---- 构建配置 ----
|
|
2661
2661
|
const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
|
|
2662
2662
|
|
|
2663
|
-
|
|
2664
|
-
const toRemove = existingProviders.filter(n => n !== claudeProviderName && n !== codexProviderName);
|
|
2665
|
-
if (toRemove.length > 0 && !args.force) {
|
|
2666
|
-
const { overwrite } = await inquirer.prompt([{
|
|
2667
|
-
type: 'confirm',
|
|
2668
|
-
name: 'overwrite',
|
|
2669
|
-
message: `检测到已有中转配置: ${existingProviders.join(', ')},将替换为 ${claudeProviderName} + ${codexProviderName}。是否继续?`,
|
|
2670
|
-
default: false
|
|
2671
|
-
}]);
|
|
2672
|
-
if (!overwrite) { console.log(chalk.gray('已取消')); return; }
|
|
2673
|
-
}
|
|
2674
|
-
|
|
2675
|
-
if (toRemove.length > 0) {
|
|
2676
|
-
pruneProvidersExcept(config, [claudeProviderName, codexProviderName]);
|
|
2677
|
-
pruneAuthProfilesExcept(paths.authProfiles, [claudeProviderName, codexProviderName]);
|
|
2678
|
-
}
|
|
2663
|
+
// 增量写入: 只添加/更新云翼 provider,保留其他已有配置
|
|
2679
2664
|
|
|
2680
2665
|
// Claude 侧
|
|
2681
2666
|
const claudeBaseUrl = buildFullUrl(selectedEndpoint.url, 'claude');
|
|
@@ -3042,13 +3027,7 @@ async function yycodeQuickSetup(paths) {
|
|
|
3042
3027
|
// ---- 写入两套配置 ----
|
|
3043
3028
|
const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
|
|
3044
3029
|
|
|
3045
|
-
//
|
|
3046
|
-
const existingProviders = Object.keys(config.models.providers || {});
|
|
3047
|
-
const toRemove = existingProviders.filter(n => n !== claudeProviderName && n !== codexProviderName);
|
|
3048
|
-
if (toRemove.length > 0) {
|
|
3049
|
-
pruneProvidersExcept(config, [claudeProviderName, codexProviderName]);
|
|
3050
|
-
pruneAuthProfilesExcept(paths.authProfiles, [claudeProviderName, codexProviderName]);
|
|
3051
|
-
}
|
|
3030
|
+
// 增量写入: 只添加/更新云翼 provider,保留其他已有配置
|
|
3052
3031
|
|
|
3053
3032
|
// Claude 侧
|
|
3054
3033
|
const claudeBaseUrl = buildFullUrl(selectedEndpoint.url, 'claude');
|
|
@@ -3238,30 +3217,31 @@ function getConfigStatusLine(paths) {
|
|
|
3238
3217
|
|
|
3239
3218
|
const providers = Object.keys(config.models.providers);
|
|
3240
3219
|
const primary = config?.agents?.defaults?.model?.primary || '';
|
|
3220
|
+
const primaryProvider = primary.split('/')[0] || '';
|
|
3241
3221
|
|
|
3242
|
-
const
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
const isActive = primary.includes('claude');
|
|
3248
|
-
parts.push(isActive ? chalk.green('Claude ✓') : chalk.yellow('Claude ○'));
|
|
3249
|
-
}
|
|
3222
|
+
const PROVIDER_LABELS = {
|
|
3223
|
+
'claude-yunyi': 'Claude(包月)',
|
|
3224
|
+
'yunyi': 'Codex(包月)',
|
|
3225
|
+
'heibai': 'MAXAPI(按量)',
|
|
3226
|
+
};
|
|
3250
3227
|
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
const isActive =
|
|
3255
|
-
parts.push(isActive ? chalk.green(
|
|
3228
|
+
const parts = [];
|
|
3229
|
+
for (const p of providers) {
|
|
3230
|
+
const label = PROVIDER_LABELS[p] || p;
|
|
3231
|
+
const isActive = p === primaryProvider;
|
|
3232
|
+
parts.push(isActive ? chalk.green(`${label} ✓`) : chalk.yellow(`${label} ○`));
|
|
3256
3233
|
}
|
|
3257
3234
|
|
|
3258
3235
|
if (parts.length === 0) {
|
|
3259
3236
|
return chalk.gray('当前状态: 未配置任何模型');
|
|
3260
3237
|
}
|
|
3261
3238
|
|
|
3239
|
+
const primaryModelId = primary.split('/')[1] || '';
|
|
3240
|
+
const modelTag = primaryModelId ? chalk.cyan(` [模型: ${primaryModelId}]`) : '';
|
|
3241
|
+
|
|
3262
3242
|
const gwEnv = detectGatewayEnv();
|
|
3263
3243
|
const envTag = gwEnv === 'wsl' ? chalk.cyan(' [WSL]') : '';
|
|
3264
|
-
return chalk.gray('当前状态: ') + parts.join(' ') + chalk.gray(' (✓ 主模型 ○ 已配置)') + envTag;
|
|
3244
|
+
return chalk.gray('当前状态: ') + parts.join(' ') + chalk.gray(' (✓ 主模型 ○ 已配置)') + modelTag + envTag;
|
|
3265
3245
|
} catch {
|
|
3266
3246
|
return null;
|
|
3267
3247
|
}
|
|
@@ -3404,59 +3384,103 @@ async function activate(paths, type) {
|
|
|
3404
3384
|
|
|
3405
3385
|
// ============ 切换模型 ============
|
|
3406
3386
|
async function switchModel(paths) {
|
|
3407
|
-
console.log(chalk.cyan('🔄
|
|
3387
|
+
console.log(chalk.cyan('🔄 切换模型\n'));
|
|
3408
3388
|
|
|
3409
3389
|
const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
|
|
3410
3390
|
const primary = config.agents?.defaults?.model?.primary || '';
|
|
3391
|
+
const providers = config.models?.providers || {};
|
|
3411
3392
|
|
|
3412
|
-
if (
|
|
3413
|
-
console.log(chalk.yellow('⚠️
|
|
3393
|
+
if (Object.keys(providers).length === 0) {
|
|
3394
|
+
console.log(chalk.yellow('⚠️ 未找到任何中转配置,请先通过「一键配置」设置'));
|
|
3414
3395
|
return;
|
|
3415
3396
|
}
|
|
3416
3397
|
|
|
3417
|
-
|
|
3418
|
-
const
|
|
3419
|
-
|
|
3398
|
+
// 已知 provider 别名映射
|
|
3399
|
+
const PROVIDER_LABELS = {
|
|
3400
|
+
'claude-yunyi': '云翼 Claude (包月)',
|
|
3401
|
+
'yunyi': '云翼 Codex (包月)',
|
|
3402
|
+
'heibai': 'MAXAPI (按量)',
|
|
3403
|
+
};
|
|
3420
3404
|
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3405
|
+
// 收集所有 provider 的所有模型
|
|
3406
|
+
const choices = [];
|
|
3407
|
+
for (const [providerName, providerConfig] of Object.entries(providers)) {
|
|
3408
|
+
const label = PROVIDER_LABELS[providerName] || providerName;
|
|
3409
|
+
const models = providerConfig.models || [];
|
|
3410
|
+
if (models.length === 0) continue;
|
|
3411
|
+
|
|
3412
|
+
choices.push(new inquirer.Separator(` -- ${label} --`));
|
|
3413
|
+
for (const m of models) {
|
|
3414
|
+
const modelKey = `${providerName}/${m.id}`;
|
|
3415
|
+
const isCurrent = modelKey === primary;
|
|
3416
|
+
choices.push({
|
|
3417
|
+
name: isCurrent ? `${m.name || m.id} (当前)` : (m.name || m.id),
|
|
3418
|
+
value: modelKey,
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
3424
3421
|
}
|
|
3425
3422
|
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3423
|
+
// 也把 agents.defaults.models 里注册过但 provider.models 里没列出的补上
|
|
3424
|
+
const registeredKeys = Object.keys(config.agents?.defaults?.models || {});
|
|
3425
|
+
const listedKeys = new Set(choices.filter(c => c.value).map(c => c.value));
|
|
3426
|
+
for (const modelKey of registeredKeys) {
|
|
3427
|
+
if (listedKeys.has(modelKey)) continue;
|
|
3428
|
+
const [pName, mId] = modelKey.split('/');
|
|
3429
|
+
if (!pName || !mId) continue;
|
|
3430
|
+
const label = PROVIDER_LABELS[pName] || pName;
|
|
3431
|
+
const isCurrent = modelKey === primary;
|
|
3432
|
+
choices.push({
|
|
3433
|
+
name: isCurrent ? `${label} / ${mId} (当前)` : `${label} / ${mId}`,
|
|
3434
|
+
value: modelKey,
|
|
3435
|
+
});
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
if (choices.filter(c => c.value).length === 0) {
|
|
3439
|
+
console.log(chalk.yellow('⚠️ 未找到任何可用模型'));
|
|
3440
|
+
return;
|
|
3441
|
+
}
|
|
3430
3442
|
|
|
3431
|
-
|
|
3432
|
-
|
|
3443
|
+
const currentProvider = primary.split('/')[0] || '';
|
|
3444
|
+
const currentProviderConfig = providers[currentProvider];
|
|
3445
|
+
console.log(chalk.gray(`当前模型: ${primary || '未设置'}`));
|
|
3446
|
+
if (currentProviderConfig) {
|
|
3447
|
+
console.log(chalk.gray(`中转节点: ${currentProviderConfig.baseUrl}`));
|
|
3448
|
+
}
|
|
3449
|
+
console.log('');
|
|
3433
3450
|
|
|
3434
3451
|
const { selected } = await inquirer.prompt([{
|
|
3435
3452
|
type: 'list',
|
|
3436
3453
|
name: 'selected',
|
|
3437
3454
|
message: '选择模型:',
|
|
3438
|
-
default:
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
value: m.id,
|
|
3442
|
-
})),
|
|
3455
|
+
default: primary,
|
|
3456
|
+
pageSize: 15,
|
|
3457
|
+
choices,
|
|
3443
3458
|
}]);
|
|
3444
3459
|
|
|
3445
|
-
if (selected ===
|
|
3460
|
+
if (selected === primary) {
|
|
3446
3461
|
console.log(chalk.gray('\n模型未变更'));
|
|
3447
3462
|
return;
|
|
3448
3463
|
}
|
|
3449
3464
|
|
|
3450
|
-
const
|
|
3451
|
-
config.agents.defaults.model.primary =
|
|
3452
|
-
if (!config.agents.defaults.models[
|
|
3453
|
-
config.agents.defaults.models[
|
|
3465
|
+
const selectedProvider = selected.split('/')[0];
|
|
3466
|
+
config.agents.defaults.model.primary = selected;
|
|
3467
|
+
if (!config.agents.defaults.models[selected]) {
|
|
3468
|
+
config.agents.defaults.models[selected] = { alias: selectedProvider };
|
|
3469
|
+
}
|
|
3470
|
+
config.agents.defaults.model.fallbacks = (config.agents.defaults.model.fallbacks || []).filter(k => k !== selected);
|
|
3471
|
+
// 把旧的 primary 加入 fallbacks (如果存在且不同)
|
|
3472
|
+
if (primary && primary !== selected && !config.agents.defaults.model.fallbacks.includes(primary)) {
|
|
3473
|
+
config.agents.defaults.model.fallbacks.push(primary);
|
|
3454
3474
|
}
|
|
3455
3475
|
writeConfigWithSync(paths, config);
|
|
3456
3476
|
|
|
3457
|
-
const
|
|
3458
|
-
|
|
3459
|
-
console.log(chalk.
|
|
3477
|
+
const selectedProviderConfig = providers[selectedProvider];
|
|
3478
|
+
const selectedLabel = PROVIDER_LABELS[selectedProvider] || selectedProvider;
|
|
3479
|
+
console.log(chalk.green(`\n✅ 已切换到 ${selected}`));
|
|
3480
|
+
console.log(chalk.gray(` 来源: ${selectedLabel}`));
|
|
3481
|
+
if (selectedProviderConfig) {
|
|
3482
|
+
console.log(chalk.gray(` 节点: ${selectedProviderConfig.baseUrl}`));
|
|
3483
|
+
}
|
|
3460
3484
|
console.log(chalk.yellow('\n💡 切换后建议重启 Gateway: openclaw gateway restart'));
|
|
3461
3485
|
|
|
3462
3486
|
const gwPort = config.gateway?.port || 18789;
|
|
@@ -3478,10 +3502,26 @@ async function testConnection(paths, args = {}) {
|
|
|
3478
3502
|
}
|
|
3479
3503
|
|
|
3480
3504
|
// 检查当前激活的是哪个
|
|
3481
|
-
|
|
3505
|
+
let primary = config.agents?.defaults?.model?.primary || '';
|
|
3482
3506
|
if (!primary.includes('/')) {
|
|
3483
|
-
|
|
3484
|
-
|
|
3507
|
+
// primary 未设置,尝试从已有 provider 自动选择
|
|
3508
|
+
const providers = config.models?.providers || {};
|
|
3509
|
+
const providerNames = Object.keys(providers);
|
|
3510
|
+
if (providerNames.length === 0) {
|
|
3511
|
+
console.log(chalk.yellow('⚠️ 请先设置主模型'));
|
|
3512
|
+
return;
|
|
3513
|
+
}
|
|
3514
|
+
// 优先选 claude provider
|
|
3515
|
+
const claudeP = providerNames.find(n => n.includes('claude'));
|
|
3516
|
+
const firstP = claudeP || providerNames[0];
|
|
3517
|
+
const firstModels = providers[firstP]?.models || [];
|
|
3518
|
+
if (firstModels.length > 0) {
|
|
3519
|
+
primary = `${firstP}/${firstModels[0].id}`;
|
|
3520
|
+
console.log(chalk.yellow(`⚠️ 主模型未设置,自动使用: ${primary}`));
|
|
3521
|
+
} else {
|
|
3522
|
+
console.log(chalk.yellow('⚠️ 请先设置主模型'));
|
|
3523
|
+
return;
|
|
3524
|
+
}
|
|
3485
3525
|
}
|
|
3486
3526
|
|
|
3487
3527
|
const providerName = primary.split('/')[0];
|