galaxy-opc 0.5.3 → 0.5.6
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/cli.mjs +98 -14
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -55,6 +55,14 @@ async function askYesNo(question, defaultYes = true) {
|
|
|
55
55
|
return ans.toLowerCase().startsWith("y");
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
function printQwenCodingPlanGuide() {
|
|
59
|
+
console.log(dim("\n 推荐路径:阿里通义千问(Coding Plan)"));
|
|
60
|
+
console.log(dim(" 1) 注册/登录阿里云账号:https://www.aliyun.com"));
|
|
61
|
+
console.log(dim(" 2) 开通 DashScope(百炼)服务:https://dashscope.aliyun.com"));
|
|
62
|
+
console.log(dim(" 3) 完成实名认证与套餐购买(按量或套餐包)"));
|
|
63
|
+
console.log(dim(" 4) 回到安装向导,选择「Qwen OAuth 扫码登录」即可使用\n"));
|
|
64
|
+
}
|
|
65
|
+
|
|
58
66
|
function separator(char = "─", len = 60) { console.log(gray(char.repeat(len))); }
|
|
59
67
|
|
|
60
68
|
// ─── 工具函数 ───────────────────────────────────────────────────────────────
|
|
@@ -111,6 +119,42 @@ function runCommand(cmd, args, options = {}) {
|
|
|
111
119
|
});
|
|
112
120
|
}
|
|
113
121
|
|
|
122
|
+
function buildOpenclawInstallEnv() {
|
|
123
|
+
// On some Windows machines node-llama-cpp postinstall fails while cloning llama.cpp.
|
|
124
|
+
// OpenClaw works with hosted providers; skip local llama.cpp download to improve install success.
|
|
125
|
+
if (process.platform === "win32") {
|
|
126
|
+
return { ...process.env, NODE_LLAMA_CPP_SKIP_DOWNLOAD: "true" };
|
|
127
|
+
}
|
|
128
|
+
return process.env;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function installOpenclawWithFallback() {
|
|
132
|
+
const env = buildOpenclawInstallEnv();
|
|
133
|
+
const attempts = [
|
|
134
|
+
{
|
|
135
|
+
label: "官方源(原生)",
|
|
136
|
+
args: ["install", "-g", "openclaw@latest"],
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
label: "国内镜像(fallback)",
|
|
140
|
+
args: ["install", "-g", "openclaw@latest", "--registry", "https://registry.npmmirror.com"],
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
let lastErr = null;
|
|
145
|
+
for (const attempt of attempts) {
|
|
146
|
+
console.log(dim(` 尝试 ${attempt.label} 安装 OpenClaw...\n`));
|
|
147
|
+
try {
|
|
148
|
+
await runCommand("npm", attempt.args, { env });
|
|
149
|
+
return;
|
|
150
|
+
} catch (e) {
|
|
151
|
+
lastErr = e;
|
|
152
|
+
console.log(yellow(` ! ${attempt.label} 失败: ${e.message}\n`));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
throw lastErr || new Error("OpenClaw 安装失败");
|
|
156
|
+
}
|
|
157
|
+
|
|
114
158
|
function checkTool(cmd) {
|
|
115
159
|
try { execSync(`${cmd} --version`, { stdio: "ignore" }); return true; } catch { return false; }
|
|
116
160
|
}
|
|
@@ -232,7 +276,7 @@ ${bold(cyan(" ╚════════════════════
|
|
|
232
276
|
if (ocVersion) {
|
|
233
277
|
console.log(green(` ✓ OpenClaw 已安装 (${ocVersion})`));
|
|
234
278
|
} else {
|
|
235
|
-
console.log(dim(" 正在安装 OpenClaw
|
|
279
|
+
console.log(dim(" 正在安装 OpenClaw(优先官方源,失败自动切换镜像)...\n"));
|
|
236
280
|
// 临时覆盖 git url rewrite(强制 SSH 协议转 HTTPS,覆盖两种格式)
|
|
237
281
|
const gitRewrites = [
|
|
238
282
|
["url.https://github.com/.insteadOf", "git@github.com:"],
|
|
@@ -247,14 +291,12 @@ ${bold(cyan(" ╚════════════════════
|
|
|
247
291
|
}
|
|
248
292
|
|
|
249
293
|
try {
|
|
250
|
-
await
|
|
251
|
-
"install", "-g", "openclaw@latest",
|
|
252
|
-
"--registry", "https://registry.npmmirror.com",
|
|
253
|
-
]);
|
|
294
|
+
await installOpenclawWithFallback();
|
|
254
295
|
console.log(green("\n ✓ OpenClaw 安装完成"));
|
|
255
296
|
} catch {
|
|
256
297
|
console.error(red("\n ✗ OpenClaw 安装失败,请手动运行:"));
|
|
257
|
-
console.error(gray(" npm install -g openclaw@latest
|
|
298
|
+
console.error(gray(" npm install -g openclaw@latest"));
|
|
299
|
+
console.error(gray(" 或 npm install -g openclaw@latest --registry https://registry.npmmirror.com\n"));
|
|
258
300
|
process.exit(1);
|
|
259
301
|
} finally {
|
|
260
302
|
// 还原 git 配置
|
|
@@ -382,8 +424,9 @@ async function cmdSetup() {
|
|
|
382
424
|
let defaultModel = null;
|
|
383
425
|
|
|
384
426
|
if (regionIdx === 0) {
|
|
427
|
+
printQwenCodingPlanGuide();
|
|
385
428
|
const cnIdx = await askChoice("选择国产模型", [
|
|
386
|
-
{ label: "通义千问 Qwen",
|
|
429
|
+
{ label: "通义千问 Qwen(推荐)", desc: "最稳妥:阿里 Coding Plan 路径,支持 OAuth 扫码", recommended: true },
|
|
387
430
|
{ label: "MiniMax", desc: "MiniMax-M2.1 — 200K 上下文,支持 OAuth 扫码" },
|
|
388
431
|
{ label: "豆包 Doubao(火山引擎)", desc: "doubao-seed-1-8 / GLM-4.7 / Kimi-K2.5" },
|
|
389
432
|
{ label: "Kimi(Moonshot AI)", desc: "kimi-k2.5 — 256K 上下文" },
|
|
@@ -397,18 +440,34 @@ async function cmdSetup() {
|
|
|
397
440
|
{ label: "DashScope API Key", desc: "从 dashscope.aliyun.com 获取" },
|
|
398
441
|
]);
|
|
399
442
|
if (m === 0) {
|
|
400
|
-
console.log(gray("\n
|
|
443
|
+
console.log(gray("\n 浏览器即将打开,扫码登录通义千问(qwen-portal)...\n"));
|
|
401
444
|
const doLogin = await askYesNo(" 现在执行登录?", true);
|
|
402
445
|
if (doLogin) {
|
|
403
446
|
try {
|
|
404
447
|
await runCommand("openclaw", ["models", "auth", "login", "--provider", "qwen-portal"]);
|
|
405
448
|
console.log(green("\n ✓ Qwen OAuth 登录成功"));
|
|
449
|
+
defaultModel = "qwen-portal/qwen-max";
|
|
450
|
+
newConfig = deepMerge(newConfig, { agents: { defaults: { model: { primary: "qwen-portal/qwen-max" } } } });
|
|
406
451
|
} catch {
|
|
407
|
-
console.log(yellow("\n !
|
|
452
|
+
console.log(yellow("\n ! Qwen OAuth 登录失败"));
|
|
453
|
+
console.log(gray(" 你可以稍后手动运行: openclaw models auth login --provider qwen-portal"));
|
|
454
|
+
const useKey = await askYesNo(" 改用 DashScope API Key 方式继续配置?", true);
|
|
455
|
+
if (useKey) {
|
|
456
|
+
const key = await ask("\n 请输入 DashScope API Key (sk-...): ");
|
|
457
|
+
if (key) {
|
|
458
|
+
newEnv["DASHSCOPE_API_KEY"] = key;
|
|
459
|
+
defaultModel = "dashscope/qwen-plus";
|
|
460
|
+
newConfig = deepMerge(newConfig, {
|
|
461
|
+
models: { providers: { dashscope: { baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", apiKey: key, api: "openai-completions", models: [{ id: "qwen-plus", name: "Qwen Plus", contextWindow: 128000, maxTokens: 8192 }] } } },
|
|
462
|
+
agents: { defaults: { model: { primary: "dashscope/qwen-plus" } } },
|
|
463
|
+
});
|
|
464
|
+
console.log(green(" ✓ 已保存"));
|
|
465
|
+
}
|
|
466
|
+
}
|
|
408
467
|
}
|
|
468
|
+
} else {
|
|
469
|
+
console.log(dim(" 已跳过 OAuth 登录,可稍后执行:openclaw models auth login --provider qwen-portal"));
|
|
409
470
|
}
|
|
410
|
-
defaultModel = "qwen-portal/qwen-max";
|
|
411
|
-
newConfig = deepMerge(newConfig, { agents: { defaults: { model: { primary: "qwen-portal/qwen-max" } } } });
|
|
412
471
|
} else {
|
|
413
472
|
const key = await ask("\n 请输入 DashScope API Key (sk-...): ");
|
|
414
473
|
if (key) {
|
|
@@ -433,12 +492,37 @@ async function cmdSetup() {
|
|
|
433
492
|
try {
|
|
434
493
|
await runCommand("openclaw", ["models", "auth", "login", "--provider", "minimax"]);
|
|
435
494
|
console.log(green("\n ✓ MiniMax OAuth 登录成功"));
|
|
495
|
+
defaultModel = "minimax/MiniMax-M2.5";
|
|
496
|
+
newConfig = deepMerge(newConfig, { agents: { defaults: { model: { primary: "minimax/MiniMax-M2.5" } } } });
|
|
436
497
|
} catch {
|
|
437
|
-
console.log(yellow("\n !
|
|
498
|
+
console.log(yellow("\n ! MiniMax OAuth 登录失败"));
|
|
499
|
+
const fallbackIdx = await askChoice("请选择后续处理", [
|
|
500
|
+
{ label: "切换到 Qwen(推荐)", desc: "按阿里 Coding Plan 路径继续,成功率更高", recommended: true },
|
|
501
|
+
{ label: "改用 MiniMax API Key", desc: "手动填写 API Key 继续配置" },
|
|
502
|
+
{ label: "稍后手动处理", desc: "先完成安装,后续再配置模型" },
|
|
503
|
+
]);
|
|
504
|
+
if (fallbackIdx === 0) {
|
|
505
|
+
printQwenCodingPlanGuide();
|
|
506
|
+
defaultModel = "qwen-portal/qwen-max";
|
|
507
|
+
newConfig = deepMerge(newConfig, { agents: { defaults: { model: { primary: "qwen-portal/qwen-max" } } } });
|
|
508
|
+
} else if (fallbackIdx === 1) {
|
|
509
|
+
const key = await ask("\n 请输入 MiniMax API Key: ");
|
|
510
|
+
if (key) {
|
|
511
|
+
newEnv["MINIMAX_API_KEY"] = key;
|
|
512
|
+
defaultModel = "minimax/MiniMax-M2.5";
|
|
513
|
+
newConfig = deepMerge(newConfig, {
|
|
514
|
+
models: { providers: { minimax: { baseUrl: "https://api.minimax.chat/v1", apiKey: key, api: "openai-completions", models: [{ id: "MiniMax-M2.5", name: "MiniMax M2.5", contextWindow: 200000, maxTokens: 16384 }] } } },
|
|
515
|
+
agents: { defaults: { model: { primary: "minimax/MiniMax-M2.5" } } },
|
|
516
|
+
});
|
|
517
|
+
console.log(green(" ✓ 已保存"));
|
|
518
|
+
}
|
|
519
|
+
} else {
|
|
520
|
+
console.log(dim(" 已跳过模型配置,可稍后执行:openclaw models auth login --provider minimax"));
|
|
521
|
+
}
|
|
438
522
|
}
|
|
523
|
+
} else {
|
|
524
|
+
console.log(dim(" 已跳过 MiniMax 登录,可稍后执行:openclaw models auth login --provider minimax"));
|
|
439
525
|
}
|
|
440
|
-
defaultModel = "minimax/MiniMax-M2.5";
|
|
441
|
-
newConfig = deepMerge(newConfig, { agents: { defaults: { model: { primary: "minimax/MiniMax-M2.5" } } } });
|
|
442
526
|
} else {
|
|
443
527
|
const key = await ask("\n 请输入 MiniMax API Key: ");
|
|
444
528
|
if (key) {
|