yymaxapi 1.0.0 → 1.0.2

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 +67 -10
  2. package/package.json +1 -1
package/bin/yymaxapi.js CHANGED
@@ -1454,10 +1454,25 @@ async function presetClaude(paths, args = {}) {
1454
1454
  console.log(chalk.cyan('📡 开始测速 Claude 节点...\n'));
1455
1455
  const speedResult = await testAllEndpoints(ENDPOINTS, { autoFallback: true });
1456
1456
 
1457
- if (speedResult.best) {
1458
- selectedEndpoint = speedResult.best;
1457
+ const sorted = speedResult.ranked || [];
1458
+ if (sorted.length > 0) {
1459
+ const { selectedIndex } = await inquirer.prompt([{
1460
+ type: 'list',
1461
+ name: 'selectedIndex',
1462
+ message: '选择节点:',
1463
+ choices: [
1464
+ { name: `🚀 使用推荐节点 (${sorted[0].name}, ${sorted[0].latency}ms, 评分:${sorted[0].score})`, value: -1 },
1465
+ new inquirer.Separator('--- 或手动选择 ---'),
1466
+ ...sorted.map((e, i) => ({
1467
+ name: `${e.name} - ${e.latency}ms (评分:${e.score})`,
1468
+ value: i
1469
+ }))
1470
+ ]
1471
+ }]);
1472
+ const primaryIndex = selectedIndex === -1 ? 0 : selectedIndex;
1473
+ selectedEndpoint = sorted[primaryIndex];
1459
1474
  if (speedResult.usedFallback) {
1460
- console.log(chalk.yellow(`\n⚠ 使用备用节点: ${selectedEndpoint.name} (${selectedEndpoint.latency}ms, 评分:${selectedEndpoint.score})\n`));
1475
+ console.log(chalk.yellow(`\n⚠ 当前使用备用节点\n`));
1461
1476
  }
1462
1477
  } else {
1463
1478
  console.log(chalk.red('\n⚠️ 所有节点(含备用)均不可达'));
@@ -1633,10 +1648,25 @@ async function presetCodex(paths, args = {}) {
1633
1648
  console.log(chalk.cyan('📡 开始测速 Codex 节点...\n'));
1634
1649
  const speedResult = await testAllEndpoints(ENDPOINTS, { autoFallback: true });
1635
1650
 
1636
- if (speedResult.best) {
1637
- selectedEndpoint = speedResult.best;
1651
+ const sorted = speedResult.ranked || [];
1652
+ if (sorted.length > 0) {
1653
+ const { selectedIndex } = await inquirer.prompt([{
1654
+ type: 'list',
1655
+ name: 'selectedIndex',
1656
+ message: '选择节点:',
1657
+ choices: [
1658
+ { name: `🚀 使用推荐节点 (${sorted[0].name}, ${sorted[0].latency}ms, 评分:${sorted[0].score})`, value: -1 },
1659
+ new inquirer.Separator('--- 或手动选择 ---'),
1660
+ ...sorted.map((e, i) => ({
1661
+ name: `${e.name} - ${e.latency}ms (评分:${e.score})`,
1662
+ value: i
1663
+ }))
1664
+ ]
1665
+ }]);
1666
+ const primaryIndex = selectedIndex === -1 ? 0 : selectedIndex;
1667
+ selectedEndpoint = sorted[primaryIndex];
1638
1668
  if (speedResult.usedFallback) {
1639
- console.log(chalk.yellow(`\n⚠ 使用备用节点: ${selectedEndpoint.name} (${selectedEndpoint.latency}ms, 评分:${selectedEndpoint.score})\n`));
1669
+ console.log(chalk.yellow(`\n⚠ 当前使用备用节点\n`));
1640
1670
  }
1641
1671
  } else {
1642
1672
  console.log(chalk.red('\n⚠️ 所有节点(含备用)均不可达'));
@@ -2109,15 +2139,30 @@ async function testConnection(paths, args = {}) {
2109
2139
 
2110
2140
  const allowAutoDaemon = !(args['no-daemon'] || args.noDaemon);
2111
2141
 
2142
+ // 步骤0: 清理可能挂死的 agent 进程
2143
+ try {
2144
+ const { execSync } = require('child_process');
2145
+ const platform = process.platform;
2146
+ if (platform === 'win32') {
2147
+ execSync('taskkill /F /FI "WINDOWTITLE eq openclaw*" /FI "STATUS eq Not Responding" 2>nul', { stdio: 'ignore' });
2148
+ } else {
2149
+ // 杀掉所有挂死的 openclaw agent 子进程(排除 gateway 主进程)
2150
+ execSync("pkill -f 'openclaw.*agent.*yymaxapi-test' 2>/dev/null || true", { stdio: 'ignore' });
2151
+ execSync("pkill -f 'clawdbot.*agent.*yymaxapi-test' 2>/dev/null || true", { stdio: 'ignore' });
2152
+ execSync("pkill -f 'moltbot.*agent.*yymaxapi-test' 2>/dev/null || true", { stdio: 'ignore' });
2153
+ }
2154
+ console.log(chalk.gray('🧹 已清理残留 agent 进程'));
2155
+ } catch { /* ignore */ }
2156
+
2112
2157
  // 步骤1: 先重启 Gateway 使配置生效
2113
2158
  console.log(chalk.cyan('步骤 1/2: 重启 Gateway 使配置生效...'));
2114
2159
  await restartGateway();
2115
2160
 
2116
2161
  // 等待 Gateway 启动
2117
2162
  const gwSpinner = ora({ text: '等待 Gateway 启动...', spinner: 'dots' }).start();
2118
- await new Promise(resolve => setTimeout(resolve, 2000));
2163
+ await new Promise(resolve => setTimeout(resolve, 3000));
2119
2164
 
2120
- let gatewayRunning = await waitForGateway(gatewayPort);
2165
+ let gatewayRunning = await waitForGateway(gatewayPort, '127.0.0.1', 15000);
2121
2166
  if (!gatewayRunning) {
2122
2167
  gwSpinner.text = '尝试自动启动 Gateway...';
2123
2168
  const autoResult = await tryAutoStartGateway(gatewayPort, allowAutoDaemon);
@@ -2178,6 +2223,17 @@ async function testConnection(paths, args = {}) {
2178
2223
  }
2179
2224
  }
2180
2225
 
2226
+ // 在 HTTP 测试前重新确认 Gateway 存活(CLI agent 测试可能耗时较长)
2227
+ if (!await isPortOpen(gatewayPort, '127.0.0.1')) {
2228
+ console.log(chalk.yellow('⚠️ Gateway 端口不可达,等待恢复...'));
2229
+ const recovered = await waitForGateway(gatewayPort, '127.0.0.1', 10000);
2230
+ if (!recovered) {
2231
+ console.log(chalk.red('❌ Gateway 在 CLI 测试后不可达,可能已崩溃'));
2232
+ console.log(chalk.gray(' 请检查 Gateway 日志或手动重启: openclaw gateway'));
2233
+ return;
2234
+ }
2235
+ }
2236
+
2181
2237
  console.log(chalk.gray(` 端点: http://localhost:${gatewayPort}/v1/responses`));
2182
2238
  const startTime = Date.now();
2183
2239
  let result = await testGatewayApi(gatewayPort, gatewayToken, primary);
@@ -2400,9 +2456,10 @@ function testGatewayViaAgent(model) {
2400
2456
  delete env.OPENAI_API_KEY;
2401
2457
  delete env.OPENCLAW_CODEX_KEY;
2402
2458
  const useNode = nodeInfo && isNodeShebang(cliBinary);
2459
+ const sessionId = `yymaxapi-test-${Date.now()}`;
2403
2460
  const cmd = useNode
2404
- ? `"${nodeInfo.path}" "${cliBinary}" agent --session-id yymaxapi-test --message "请回复你的模型名称" --json --timeout 120`
2405
- : `"${cliBinary}" agent --session-id yymaxapi-test --message "请回复你的模型名称" --json --timeout 120`;
2461
+ ? `"${nodeInfo.path}" "${cliBinary}" agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120`
2462
+ : `"${cliBinary}" agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120`;
2406
2463
 
2407
2464
  exec(cmd, { timeout: 120000, env }, (error, stdout, stderr) => {
2408
2465
  // 过滤 stderr 中的 Node.js DeprecationWarning 噪音
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yymaxapi",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "跨平台 OpenClaw/Clawdbot 配置管理工具 - 管理中转地址、模型切换、API Keys、测速优化",
5
5
  "main": "bin/yymaxapi.js",
6
6
  "bin": {