openclawapi 1.3.9 → 1.3.11
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/cli.js +112 -66
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -381,7 +381,7 @@ async function activate(paths, type) {
|
|
|
381
381
|
|
|
382
382
|
// ============ 测试连接 ============
|
|
383
383
|
async function testConnection(paths) {
|
|
384
|
-
console.log(chalk.cyan('🧪 测试
|
|
384
|
+
console.log(chalk.cyan('🧪 测试 OpenClaw Gateway 连接\n'));
|
|
385
385
|
|
|
386
386
|
const config = readConfig(paths.openclawConfig);
|
|
387
387
|
|
|
@@ -415,68 +415,31 @@ async function testConnection(paths) {
|
|
|
415
415
|
return;
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
+
// 获取 Gateway 配置
|
|
419
|
+
const gatewayPort = config.gateway?.port || 18789;
|
|
420
|
+
const gatewayToken = config.gateway?.auth?.token || '';
|
|
421
|
+
|
|
418
422
|
console.log(chalk.gray(`当前激活: ${typeLabel}`));
|
|
419
|
-
console.log(chalk.gray(
|
|
420
|
-
console.log(chalk.gray(`模型: ${
|
|
423
|
+
console.log(chalk.gray(`中转节点: ${provider.baseUrl}`));
|
|
424
|
+
console.log(chalk.gray(`模型: ${primary}`));
|
|
425
|
+
console.log(chalk.gray(`Gateway: http://localhost:${gatewayPort}\n`));
|
|
421
426
|
|
|
422
|
-
//
|
|
423
|
-
console.log(chalk.cyan(
|
|
427
|
+
// 通过本地 Gateway 端口测试
|
|
428
|
+
console.log(chalk.cyan(`正在通过 Gateway 测试 ${typeLabel}...`));
|
|
424
429
|
|
|
425
430
|
try {
|
|
426
431
|
const startTime = Date.now();
|
|
432
|
+
const result = await testGatewayApi(gatewayPort, gatewayToken, primary);
|
|
433
|
+
const latency = Date.now() - startTime;
|
|
427
434
|
|
|
428
|
-
if (
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if (result.success) {
|
|
433
|
-
console.log(chalk.green(`\n✅ ${typeLabel} API 连接成功!`));
|
|
434
|
-
console.log(chalk.cyan(` 响应时间: ${latency}ms`));
|
|
435
|
-
console.log(chalk.yellow(` 模型回复: ${result.message}`));
|
|
436
|
-
|
|
437
|
-
// 询问是否重启 gateway
|
|
438
|
-
const { restart } = await inquirer.prompt([{
|
|
439
|
-
type: 'confirm',
|
|
440
|
-
name: 'restart',
|
|
441
|
-
message: '是否重启 OpenClaw Gateway 使配置生效?',
|
|
442
|
-
default: true
|
|
443
|
-
}]);
|
|
444
|
-
|
|
445
|
-
if (restart) {
|
|
446
|
-
await restartGateway();
|
|
447
|
-
} else {
|
|
448
|
-
console.log(chalk.gray(`\n💡 稍后可手动运行: openclaw gateway restart`));
|
|
449
|
-
}
|
|
450
|
-
} else {
|
|
451
|
-
console.log(chalk.red(`\n❌ ${typeLabel} API 连接失败`));
|
|
452
|
-
console.log(chalk.red(` 错误: ${result.error}`));
|
|
453
|
-
}
|
|
435
|
+
if (result.success) {
|
|
436
|
+
console.log(chalk.green(`\n✅ Gateway 连接成功!配置已生效`));
|
|
437
|
+
console.log(chalk.cyan(` 响应时间: ${latency}ms`));
|
|
438
|
+
console.log(chalk.yellow(` 模型回复: ${result.message}`));
|
|
454
439
|
} else {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
if (result.success) {
|
|
459
|
-
console.log(chalk.green(`\n✅ ${typeLabel} API 连接成功!`));
|
|
460
|
-
console.log(chalk.cyan(` 响应时间: ${latency}ms`));
|
|
461
|
-
console.log(chalk.yellow(` 模型回复: ${result.message}`));
|
|
462
|
-
|
|
463
|
-
// 询问是否重启 gateway
|
|
464
|
-
const { restart } = await inquirer.prompt([{
|
|
465
|
-
type: 'confirm',
|
|
466
|
-
name: 'restart',
|
|
467
|
-
message: '是否重启 OpenClaw Gateway 使配置生效?',
|
|
468
|
-
default: true
|
|
469
|
-
}]);
|
|
470
|
-
|
|
471
|
-
if (restart) {
|
|
472
|
-
await restartGateway();
|
|
473
|
-
} else {
|
|
474
|
-
console.log(chalk.gray(`\n💡 稍后可手动运行: openclaw gateway restart`));
|
|
475
|
-
}
|
|
476
|
-
} else {
|
|
477
|
-
console.log(chalk.red(`\n❌ ${typeLabel} API 连接失败`));
|
|
478
|
-
console.log(chalk.red(` 错误: ${result.error}`));
|
|
479
|
-
}
|
|
440
|
+
console.log(chalk.red(`\n❌ Gateway 连接失败`));
|
|
441
|
+
console.log(chalk.red(` 错误: ${result.error}`));
|
|
442
|
+
console.log(chalk.gray(`\n💡 请确保 Gateway 正在运行: openclaw gateway`));
|
|
480
443
|
}
|
|
481
444
|
} catch (error) {
|
|
482
445
|
console.log(chalk.red(`❌ 测试失败: ${error.message}`));
|
|
@@ -489,21 +452,104 @@ async function restartGateway() {
|
|
|
489
452
|
|
|
490
453
|
const { exec } = require('child_process');
|
|
491
454
|
|
|
455
|
+
// 尝试多种命令
|
|
456
|
+
const commands = [
|
|
457
|
+
'openclaw gateway restart',
|
|
458
|
+
'clawdbot gateway restart',
|
|
459
|
+
'npx openclaw gateway restart',
|
|
460
|
+
'npx clawdbot gateway restart'
|
|
461
|
+
];
|
|
462
|
+
|
|
492
463
|
return new Promise((resolve) => {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
464
|
+
let tried = 0;
|
|
465
|
+
|
|
466
|
+
const tryNext = () => {
|
|
467
|
+
if (tried >= commands.length) {
|
|
468
|
+
console.log(chalk.red(`❌ 重启失败: 找不到 openclaw/clawdbot 命令`));
|
|
496
469
|
console.log(chalk.gray(` 请手动运行: openclaw gateway restart`));
|
|
470
|
+
console.log(chalk.gray(` 或: clawdbot gateway restart`));
|
|
471
|
+
resolve();
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const cmd = commands[tried];
|
|
476
|
+
tried++;
|
|
477
|
+
|
|
478
|
+
exec(cmd, { timeout: 30000 }, (error) => {
|
|
479
|
+
if (error) {
|
|
480
|
+
tryNext();
|
|
481
|
+
} else {
|
|
482
|
+
console.log(chalk.green(`✅ Gateway 已重启`));
|
|
483
|
+
console.log(chalk.gray(` 现在可以在 Web/Telegram/Discord 等渠道测试对话了`));
|
|
484
|
+
resolve();
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
tryNext();
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Gateway API 测试 - 通过本地 Gateway 端口测试
|
|
494
|
+
function testGatewayApi(port, token, model) {
|
|
495
|
+
return new Promise((resolve) => {
|
|
496
|
+
const postData = JSON.stringify({
|
|
497
|
+
model: model,
|
|
498
|
+
messages: [{ role: 'user', content: '你是什么模型?' }]
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
const options = {
|
|
502
|
+
hostname: '127.0.0.1',
|
|
503
|
+
port: port,
|
|
504
|
+
path: '/v1/chat/completions',
|
|
505
|
+
method: 'POST',
|
|
506
|
+
timeout: 60000,
|
|
507
|
+
headers: {
|
|
508
|
+
'Content-Type': 'application/json',
|
|
509
|
+
'Authorization': `Bearer ${token}`,
|
|
510
|
+
'Content-Length': Buffer.byteLength(postData)
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
const req = http.request(options, (res) => {
|
|
515
|
+
let data = '';
|
|
516
|
+
res.on('data', chunk => data += chunk);
|
|
517
|
+
res.on('end', () => {
|
|
518
|
+
try {
|
|
519
|
+
const json = JSON.parse(data);
|
|
520
|
+
// OpenAI 格式响应
|
|
521
|
+
if (json.choices && json.choices[0]?.message?.content) {
|
|
522
|
+
resolve({ success: true, message: json.choices[0].message.content });
|
|
523
|
+
} else if (json.error) {
|
|
524
|
+
resolve({ success: false, error: json.error.message || JSON.stringify(json.error) });
|
|
525
|
+
} else {
|
|
526
|
+
resolve({ success: false, error: `HTTP ${res.statusCode}: ${data.substring(0, 300)}` });
|
|
527
|
+
}
|
|
528
|
+
} catch {
|
|
529
|
+
resolve({ success: false, error: `HTTP ${res.statusCode}: ${data.substring(0, 300)}` });
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
req.on('timeout', () => {
|
|
535
|
+
req.destroy();
|
|
536
|
+
resolve({ success: false, error: '请求超时 (60s)' });
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
req.on('error', (e) => {
|
|
540
|
+
if (e.code === 'ECONNREFUSED') {
|
|
541
|
+
resolve({ success: false, error: 'Gateway 未运行,请先启动: openclaw gateway' });
|
|
497
542
|
} else {
|
|
498
|
-
|
|
499
|
-
console.log(chalk.gray(` 现在可以在 Web/Telegram/Discord 等渠道测试对话了`));
|
|
543
|
+
resolve({ success: false, error: e.message });
|
|
500
544
|
}
|
|
501
|
-
resolve();
|
|
502
545
|
});
|
|
546
|
+
|
|
547
|
+
req.write(postData);
|
|
548
|
+
req.end();
|
|
503
549
|
});
|
|
504
550
|
}
|
|
505
551
|
|
|
506
|
-
// Claude API 测试
|
|
552
|
+
// Claude API 测试 (直接测试中转,备用)
|
|
507
553
|
function testClaudeApi(baseUrl, apiKey, model) {
|
|
508
554
|
return new Promise((resolve) => {
|
|
509
555
|
const urlObj = new URL(baseUrl);
|
|
@@ -511,8 +557,8 @@ function testClaudeApi(baseUrl, apiKey, model) {
|
|
|
511
557
|
|
|
512
558
|
const postData = JSON.stringify({
|
|
513
559
|
model: model || 'claude-sonnet-4-5',
|
|
514
|
-
max_tokens:
|
|
515
|
-
messages: [{ role: 'user', content: '
|
|
560
|
+
max_tokens: 150,
|
|
561
|
+
messages: [{ role: 'user', content: '你是哪个模型?请用一句话回答你的模型名称和版本。' }]
|
|
516
562
|
});
|
|
517
563
|
|
|
518
564
|
const options = {
|
|
@@ -571,7 +617,7 @@ function testCodexApi(baseUrl, apiKey, model) {
|
|
|
571
617
|
|
|
572
618
|
const postData = JSON.stringify({
|
|
573
619
|
model: model || 'gpt-5.2',
|
|
574
|
-
input: '
|
|
620
|
+
input: '你是哪个模型?请用一句话回答你的模型名称和版本。'
|
|
575
621
|
});
|
|
576
622
|
|
|
577
623
|
const options = {
|