mu-agent 0.1.8 → 0.1.13
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/CHANGELOG.md +121 -0
- package/README.md +34 -30
- package/dist/bundle/chunks/anthropic-messages-4PAJY4R6.js +6 -0
- package/dist/bundle/chunks/anthropic.js +1 -1
- package/dist/bundle/chunks/azure-openai-responses-Y4BBWQ3N.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +12 -9
- package/dist/bundle/chunks/{chunk-NG4PO5FP.js → chunk-3J3HSHLX.js} +128 -110
- package/dist/bundle/chunks/{chunk-TRDNDS6A.js → chunk-3V45WARH.js} +6 -3
- package/dist/bundle/chunks/{chunk-S3GGRYIO.js → chunk-5AGIVGSV.js} +1 -1
- package/dist/bundle/chunks/chunk-6QGV3IWD.js +6 -0
- package/dist/bundle/chunks/{chunk-4OBXYPH4.js → chunk-6Z2347ML.js} +1 -1
- package/dist/bundle/chunks/{chunk-F5ZABL6Z.js → chunk-7CBJINYJ.js} +2 -2
- package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-7DDKXS2Q.js} +1 -1
- package/dist/bundle/chunks/{chunk-H3QXYIF7.js → chunk-CF5GWZHW.js} +1 -1
- package/dist/bundle/chunks/{chunk-RLZVFGW4.js → chunk-DYTENXHX.js} +29 -92
- package/dist/bundle/chunks/{chunk-NTSWBG4X.js → chunk-FLHKNMLQ.js} +1 -1
- package/dist/bundle/chunks/chunk-FTJT2X6E.js +2 -0
- package/dist/bundle/chunks/{chunk-4L3WN2XY.js → chunk-JXWJOIH4.js} +1 -1
- package/dist/bundle/chunks/{chunk-TAOL3JFA.js → chunk-KIDDRTZP.js} +4 -4
- package/dist/bundle/chunks/chunk-LHRPMXVI.js +2 -0
- package/dist/bundle/chunks/chunk-LMNWTX2L.js +11 -0
- package/dist/bundle/chunks/chunk-LPXNMA2W.js +2 -0
- package/dist/bundle/chunks/chunk-LT2C56HV.js +130 -0
- package/dist/bundle/chunks/{chunk-6CYCI3EJ.js → chunk-LVVZS2NO.js} +1 -1
- package/dist/bundle/chunks/chunk-MF3VB62R.js +91 -0
- package/dist/bundle/chunks/chunk-NN4BEPYX.js +2 -0
- package/dist/bundle/chunks/{chunk-LD2P6SFZ.js → chunk-PMRZO46Y.js} +1 -1
- package/dist/bundle/chunks/chunk-R4VPBBDS.js +2 -0
- package/dist/bundle/chunks/chunk-RDZVAGPR.js +2 -0
- package/dist/bundle/chunks/chunk-TMTOQ7H7.js +2 -0
- package/dist/bundle/chunks/chunk-UKVNB6C4.js +2 -0
- package/dist/bundle/chunks/chunk-URBBMV3M.js +9 -0
- package/dist/bundle/chunks/chunk-WCGU75WO.js +11 -0
- package/dist/bundle/chunks/chunk-WCJNJQO5.js +9 -0
- package/dist/bundle/chunks/chunk-WDURT4ZM.js +2 -0
- package/dist/bundle/chunks/{cli-AOVD3SSZ.js → cli-M4YBZZ6Q.js} +4 -4
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-MEZHQVNP.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +117 -13
- package/dist/bundle/chunks/easter-egg-3d-VFY3YRQR.js +2 -0
- package/dist/bundle/chunks/execute-FKI7Y4XR.js +499 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-XMFHGQC5.js → google-generative-ai-D2VJQBTK.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-4XRRNP74.js → google-vertex-SQG2BO6C.js} +1 -1
- package/dist/bundle/chunks/https-proxy-agent-LVOO5TPL.js +13 -0
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{jiti-loader-C3NU2SDH.js → jiti-loader-GL4HJFAD.js} +1 -1
- package/dist/bundle/chunks/{jiti-static-loader-E6ANQD5T.js → jiti-static-loader-2RCDI6B4.js} +1 -1
- package/dist/bundle/chunks/{lib-TEDK3E5I.js → lib-4AVRLBHM.js} +1 -1
- package/dist/bundle/chunks/{llama-cpp-classify-XT44PI3C.js → llama-cpp-classify-5YHLY3RC.js} +2 -2
- package/dist/bundle/chunks/mistral-conversations-BDARVJTT.js +5 -0
- package/dist/bundle/chunks/{multipart-parser-SQ6GDJL7.js → multipart-parser-FMGQ7342.js} +1 -1
- package/dist/bundle/chunks/{node-TWVVAGPO.js → node-AUOGOBCN.js} +1 -1
- package/dist/bundle/chunks/{node-N5BSDOA5.js → node-KCMANYC2.js} +1 -1
- package/dist/bundle/chunks/openai-chatgpt.js +1 -1
- package/dist/bundle/chunks/openai-codex-responses-CECGTDYD.js +10 -0
- package/dist/bundle/chunks/openai-codex.js +1 -1
- package/dist/bundle/chunks/openai-completions-UOA7MELD.js +7 -0
- package/dist/bundle/chunks/openai-decisions-HLM372N6.js +5 -0
- package/dist/bundle/chunks/openai-responses-TII7ZY5X.js +3 -0
- package/dist/bundle/chunks/{openrouter-images-ZVXWCSIM.js → openrouter-images-7T452AS5.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-TM5SOOIW.js → pi-messages-2UDKLKOO.js} +1 -1
- package/dist/bundle/chunks/runtime-IKE5OQIW.js +2 -0
- package/dist/bundle/chunks/{src-UK77SYZE.js → src-QKGKDFSU.js} +1 -1
- package/dist/bundle/chunks/typesafe-system-one-KNCICMO5.js +2 -0
- package/dist/bundle/chunks/virtual-modules-TJPHLTRT.js +2 -0
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/export-html/template.js +21 -16
- package/dist/modes/interactive/theme/dark.json +1 -1
- package/dist/modes/interactive/theme/light.json +1 -1
- package/dist/modes/interactive/theme/theme-schema.d.ts +28 -0
- package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-schema.js +105 -0
- package/dist/modes/interactive/theme/theme-schema.js.map +1 -0
- package/dist/modes/interactive/theme/theme-tokens.d.ts +257 -0
- package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-tokens.js +94 -0
- package/dist/modes/interactive/theme/theme-tokens.js.map +1 -0
- package/dist/modes/interactive/theme/theme.d.ts +13 -16
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +22 -29
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/docs/cli-integration.md +1 -1
- package/docs/cli.md +22 -10
- package/docs/codemode.md +29 -6
- package/docs/compaction.md +5 -5
- package/docs/custom-provider.md +53 -1
- package/docs/docs.json +8 -0
- package/docs/environment-variables.md +3 -1
- package/docs/extensions.md +122 -13
- package/docs/json.md +3 -3
- package/docs/keybindings.md +5 -4
- package/docs/llama-cpp.md +9 -2
- package/docs/mcp.md +4 -2
- package/docs/message-types.md +22 -4
- package/docs/models-configuration.md +187 -0
- package/docs/models.md +18 -2
- package/docs/nvidia-rtx-llama-cpp.md +96 -0
- package/docs/providers.md +47 -0
- package/docs/sessions.md +1 -1
- package/docs/settings.md +9 -6
- package/docs/terminal-setup.md +14 -0
- package/docs/themes.md +4 -2
- package/docs/tui.md +71 -1
- package/docs/usage.md +1 -1
- package/examples/README.md +0 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +4 -5
- package/examples/extensions/overlay-test.ts +2 -2
- package/examples/extensions/plan-mode/index.ts +6 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/index.ts +4 -6
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/judge/dist/auth.js +91 -35
- package/judge/dist/chrome.js +2 -2
- package/judge/dist/import.js +852 -175
- package/judge/dist/setup.js +240 -153
- package/judge/manifest.json +2512 -546
- package/judge/mu/chunk-3NQ5BIBI.js +4773 -0
- package/judge/mu/chunk-SKGYWHW6.js +51 -0
- package/judge/mu/chunk-WQM4MV6L.js +58 -0
- package/judge/mu/cloud-code-V7FOGB4J.js +22802 -0
- package/judge/mu/dist-75PS4OC4.js +1283 -0
- package/judge/{dist/kyrn-judge.js → mu/index.js} +5365 -32809
- package/judge/mu/multipart-parser-ZDXVIOOP.js +372 -0
- package/judge/mu/src-TVVA5ZK2.js +1409 -0
- package/judge/themes/mu-dark.json +80 -0
- package/judge/themes/mu-light.json +80 -0
- package/kyrn/bin/kyrn-doctor +44 -19
- package/kyrn/bin/kyrn-judge-local +43 -14
- package/kyrn/bin/kyrn-ledger +16 -1
- package/kyrn/bin/mu.mjs +142 -61
- package/kyrn/local-judge/server.py +26 -14
- package/package.json +8 -6
- package/dist/bundle/chunks/anthropic-messages-MI4QHRXW.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-E3QGN4VN.js +0 -2
- package/dist/bundle/chunks/chunk-33KL6IIQ.js +0 -20
- package/dist/bundle/chunks/chunk-A3JYRWB6.js +0 -2
- package/dist/bundle/chunks/chunk-C47CLQZK.js +0 -2
- package/dist/bundle/chunks/chunk-HQHD6PZI.js +0 -2
- package/dist/bundle/chunks/chunk-KJUDFE6Y.js +0 -11
- package/dist/bundle/chunks/chunk-TE3GUV6H.js +0 -9
- package/dist/bundle/chunks/chunk-VIV3CWXG.js +0 -2
- package/dist/bundle/chunks/chunk-WE4MXUQS.js +0 -11
- package/dist/bundle/chunks/chunk-Y2PP32XV.js +0 -2
- package/dist/bundle/chunks/chunk-YLY6CKPK.js +0 -132
- package/dist/bundle/chunks/chunk-ZE5FMF3V.js +0 -99
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-NM3JRRWQ.js +0 -2
- package/dist/bundle/chunks/easter-egg-3d-G2LUBEMZ.js +0 -2
- package/dist/bundle/chunks/execute-MZVUC6BB.js +0 -388
- package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +0 -13
- package/dist/bundle/chunks/mistral-conversations-Q22M3IBG.js +0 -5
- package/dist/bundle/chunks/openai-codex-responses-4MYQSO5E.js +0 -10
- package/dist/bundle/chunks/openai-completions-OSRCWAAA.js +0 -7
- package/dist/bundle/chunks/openai-responses-UHF3DHNG.js +0 -3
- package/dist/bundle/chunks/runtime-VJMMDLVH.js +0 -2
- package/dist/bundle/chunks/typesafe-system-one-PRR5K6CI.js +0 -2
- package/dist/bundle/chunks/virtual-modules-RJXJGCPI.js +0 -2
- package/dist/modes/interactive/theme/theme-json.d.ts +0 -85
- package/dist/modes/interactive/theme/theme-json.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme-json.js +0 -132
- package/dist/modes/interactive/theme/theme-json.js.map +0 -1
- package/dist/modes/interactive/theme/theme-schema.json +0 -361
- package/examples/plugins/pi-example-plugin/README.md +0 -38
- package/examples/plugins/pi-example-plugin/package.json +0 -10
- package/examples/plugins/pi-example-plugin/src/contract.ts +0 -13
- package/examples/plugins/pi-example-plugin/src/session.ts +0 -24
- package/examples/plugins/pi-example-plugin/src/tui.ts +0 -31
package/judge/dist/setup.js
CHANGED
|
@@ -328,6 +328,16 @@ function tiersOf(config) {
|
|
|
328
328
|
function withTiers(config, tiers) {
|
|
329
329
|
return { ...config, tiers: [...tiers] };
|
|
330
330
|
}
|
|
331
|
+
function judgeOff(config) {
|
|
332
|
+
return isRecord(config?.modes) && config.modes.default === "off";
|
|
333
|
+
}
|
|
334
|
+
function withJudge(config, on) {
|
|
335
|
+
const { default: _default, ...modes } = isRecord(config.modes) ? config.modes : {};
|
|
336
|
+
if (!on) return { ...config, modes: { default: "off", ...modes } };
|
|
337
|
+
if (!judgeOff(config)) return config;
|
|
338
|
+
const { modes: _modes, ...rest } = config;
|
|
339
|
+
return Object.keys(modes).length > 0 ? { ...rest, modes } : rest;
|
|
340
|
+
}
|
|
331
341
|
function readTextFile(path) {
|
|
332
342
|
try {
|
|
333
343
|
return readFileSync(path, "utf8");
|
|
@@ -378,14 +388,17 @@ function piAccess(runtime, agentDir2) {
|
|
|
378
388
|
storeKey: async (provider, key) => {
|
|
379
389
|
await runtime.refresh({ allowNetwork: false, providers: [provider] });
|
|
380
390
|
if (!runtime.getProvider(provider)) {
|
|
381
|
-
throw new Error(
|
|
391
|
+
throw new Error(
|
|
392
|
+
`mu has no provider named ${provider}${runtime.getError() ? `: ${runtime.getError()}` : ""}`
|
|
393
|
+
);
|
|
382
394
|
}
|
|
383
395
|
let asked = false;
|
|
384
396
|
try {
|
|
385
397
|
await runtime.login(provider, "api_key", {
|
|
386
398
|
// pi's key login asks one question, the key. Anything else is not answered, and nothing is guessed.
|
|
387
399
|
prompt: async (prompt) => {
|
|
388
|
-
if (asked || prompt.type !== "secret")
|
|
400
|
+
if (asked || prompt.type !== "secret")
|
|
401
|
+
throw new Error(`the sign-in for ${provider} asked for more than a key`);
|
|
389
402
|
asked = true;
|
|
390
403
|
return key;
|
|
391
404
|
},
|
|
@@ -459,11 +472,31 @@ function askSecret(input, output, question) {
|
|
|
459
472
|
input.resume();
|
|
460
473
|
});
|
|
461
474
|
}
|
|
475
|
+
var columnsOf = (char) => /[\u1100-\u115f\u2e80-\ua4cf\uac00-\ud7a3\uf900-\ufaff\ufe30-\ufe4f\uff00-\uff60\uffe0-\uffe6]/u.test(char) ? 2 : 1;
|
|
476
|
+
var widthOf = (text) => Array.from(text).reduce((sum, char) => sum + columnsOf(char), 0);
|
|
477
|
+
function wrapToWidth(text, width) {
|
|
478
|
+
if (!width || width < 20) return text;
|
|
479
|
+
return text.split("\n").map((line) => {
|
|
480
|
+
if (widthOf(line) <= width) return line;
|
|
481
|
+
const indent = " ".repeat(/^\s*(?:\d+\)\s+)?/.exec(line)?.[0].length ?? 0);
|
|
482
|
+
const out = [];
|
|
483
|
+
let current = "";
|
|
484
|
+
for (const word of line.trimEnd().split(/(?<=\S) (?=\S)/)) {
|
|
485
|
+
const next = current ? `${current} ${word}` : word;
|
|
486
|
+
if (current && widthOf(next) > width) {
|
|
487
|
+
out.push(current);
|
|
488
|
+
current = `${indent}${word.trimStart()}`;
|
|
489
|
+
} else current = next;
|
|
490
|
+
}
|
|
491
|
+
out.push(current);
|
|
492
|
+
return out.join("\n");
|
|
493
|
+
}).join("\n");
|
|
494
|
+
}
|
|
462
495
|
function terminalPrompter(input = process.stdin, output = process.stdout, errors = process.stderr) {
|
|
463
496
|
return {
|
|
464
|
-
say: (text) => output.write(`${text}
|
|
497
|
+
say: (text) => output.write(`${wrapToWidth(text, output.isTTY ? output.columns : void 0)}
|
|
465
498
|
`),
|
|
466
|
-
warn: (text) => errors.write(`${text}
|
|
499
|
+
warn: (text) => errors.write(`${wrapToWidth(text, errors.isTTY ? errors.columns : void 0)}
|
|
467
500
|
`),
|
|
468
501
|
ask: (question) => askLine(input, output, question),
|
|
469
502
|
secret: (question) => askSecret(input, output, question)
|
|
@@ -641,41 +674,41 @@ function explainProblem(problem, context, language) {
|
|
|
641
674
|
const host = hostOf(problem.url);
|
|
642
675
|
const seconds = Math.round((context.timeoutMs ?? CHECK_TIMEOUT_MS) / 1e3);
|
|
643
676
|
const local = /^(localhost|127\.|\[::1\])/.test(host);
|
|
644
|
-
const proxyHint = language === "zh" ? context.proxy ? `\u8FD9\u6B21\u8BF7\u6C42\u8D70\u4E86\u4EE3\u7406\uFF08${context.proxy}\uFF09\uFF0C\u786E\u8BA4\u4EE3\u7406\u6B63\u5728\u8FD0\u884C\u3002` : "\u5982\u679C\u9700\u8981\u4EE3\u7406\uFF1A\u8BBE\u7F6E HTTPS_PROXY\uFF0C\u6216\u5728 ~/.mu/agent/settings.json \u91CC\u5199 httpProxy\uFF0C\u7136\u540E\u91CD\u65B0\u8FD0\u884C mu setup\u3002" : context.proxy ? `The request went through your proxy (${context.proxy})
|
|
677
|
+
const proxyHint = language === "zh" ? context.proxy ? `\u8FD9\u6B21\u8BF7\u6C42\u8D70\u4E86\u4EE3\u7406\uFF08${context.proxy}\uFF09\uFF0C\u786E\u8BA4\u4EE3\u7406\u6B63\u5728\u8FD0\u884C\u3002` : "\u5982\u679C\u9700\u8981\u4EE3\u7406\uFF1A\u8BBE\u7F6E HTTPS_PROXY\uFF0C\u6216\u5728 ~/.mu/agent/settings.json \u91CC\u5199 httpProxy\uFF0C\u7136\u540E\u91CD\u65B0\u8FD0\u884C mu setup\u3002" : context.proxy ? `The request went through your proxy (${context.proxy}). Check that it's running.` : "If you need a proxy, set HTTPS_PROXY (or httpProxy in ~/.mu/agent/settings.json) and run mu setup again.";
|
|
645
678
|
const said = problem.said ? language === "zh" ? `\uFF08\u670D\u52A1\u7684\u539F\u8BDD\uFF1A${problem.said}\uFF09` : ` (The service said: ${problem.said})` : "";
|
|
646
679
|
const zh = language === "zh";
|
|
647
680
|
switch (problem.kind) {
|
|
648
681
|
case "key":
|
|
649
|
-
return zh ? `${service} \u4E0D\u63A5\u53D7\u8FD9\u4E2A\u5BC6\u94A5\u3002\u68C0\u67E5\u662F\u5426\u5B8C\u6574\u590D\u5236\uFF0C\u4EE5\u53CA\u5B83\u786E\u5B9E\u662F ${service} \u7684\u5BC6\u94A5\u3002` : `${service}
|
|
682
|
+
return zh ? `${service} \u4E0D\u63A5\u53D7\u8FD9\u4E2A\u5BC6\u94A5\u3002\u68C0\u67E5\u662F\u5426\u5B8C\u6574\u590D\u5236\uFF0C\u4EE5\u53CA\u5B83\u786E\u5B9E\u662F ${service} \u7684\u5BC6\u94A5\u3002` : `${service} didn't accept this key. Check that you copied all of it and that it's ${article(service)} key.`;
|
|
650
683
|
case "refused":
|
|
651
|
-
return zh ? `${service} \u62D2\u7EDD\u4E86\u8FD9\u4E2A\u5BC6\u94A5\uFF08HTTP 403\uFF09\uFF1A\u53EF\u80FD\u662F\u5BC6\u94A5\u4E0D\u5BF9\uFF0C\u6216\u5B83\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\u3002${said}` : `${service} refused this key (HTTP 403)
|
|
684
|
+
return zh ? `${service} \u62D2\u7EDD\u4E86\u8FD9\u4E2A\u5BC6\u94A5\uFF08HTTP 403\uFF09\uFF1A\u53EF\u80FD\u662F\u5BC6\u94A5\u4E0D\u5BF9\uFF0C\u6216\u5B83\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\u3002${said}` : `${service} refused this key (HTTP 403). The key may be wrong or lack access.${said}`;
|
|
652
685
|
case "permission":
|
|
653
|
-
return zh ? "\u8FD9\u4E2A\u5BC6\u94A5\u6709\u6548\uFF0C\u4F46\u6CA1\u6709\u8BFB\u53D6\u6A21\u578B\u5217\u8868\u7684\u6743\u9650\uFF08\u53D7\u9650\u5BC6\u94A5\uFF09\u3002\u7ED9\u5B83\u8BFB\u53D6\u6A21\u578B\u7684\u6743\u9650\uFF0C\u6216\u6362\u4E00\u4E2A\u5BC6\u94A5\u3002" : "The key works
|
|
686
|
+
return zh ? "\u8FD9\u4E2A\u5BC6\u94A5\u6709\u6548\uFF0C\u4F46\u6CA1\u6709\u8BFB\u53D6\u6A21\u578B\u5217\u8868\u7684\u6743\u9650\uFF08\u53D7\u9650\u5BC6\u94A5\uFF09\u3002\u7ED9\u5B83\u8BFB\u53D6\u6A21\u578B\u7684\u6743\u9650\uFF0C\u6216\u6362\u4E00\u4E2A\u5BC6\u94A5\u3002" : "The key works but can't list models (it's a restricted key). Give it permission to read models, or use another key.";
|
|
654
687
|
case "balance":
|
|
655
688
|
return zh ? `${service} \u7684\u8D26\u6237\u6CA1\u6709\u4F59\u989D\u6216\u989D\u5EA6\u4E86\u3002\u5145\u503C\u540E\u91CD\u65B0\u8FD0\u884C mu setup\u3002` : `The ${service} account has no balance or quota left. Top it up, then run mu setup again.`;
|
|
656
689
|
case "region":
|
|
657
|
-
return zh ? `${service} \u4E0D\u5411\u4F60\u6240\u5728\u7684\u5730\u533A\u63D0\u4F9B\u670D\u52A1\u3002\u9700\u8981\u4E00\u4E2A\u4F4D\u4E8E\u652F\u6301\u5730\u533A\u7684\u4EE3\u7406\u6216 VPN\u3002${proxyHint}` : `${service}
|
|
690
|
+
return zh ? `${service} \u4E0D\u5411\u4F60\u6240\u5728\u7684\u5730\u533A\u63D0\u4F9B\u670D\u52A1\u3002\u9700\u8981\u4E00\u4E2A\u4F4D\u4E8E\u652F\u6301\u5730\u533A\u7684\u4EE3\u7406\u6216 VPN\u3002${proxyHint}` : `${service} isn't available in the region this request came from. You need a proxy or VPN in a supported region. ${proxyHint}`;
|
|
658
691
|
case "rate":
|
|
659
|
-
return zh ? `${service} \u8BF4\u8BF7\u6C42\u592A\u9891\u7E41\u3002\u7B49\u4E00\u5206\u949F\u518D\u8BD5\u3002` : `${service}
|
|
692
|
+
return zh ? `${service} \u8BF4\u8BF7\u6C42\u592A\u9891\u7E41\u3002\u7B49\u4E00\u5206\u949F\u518D\u8BD5\u3002` : `${service} is getting too many requests from you. Wait a minute and try again.`;
|
|
660
693
|
case "address":
|
|
661
|
-
return zh ? `${problem.url} \u8FD9\u4E2A\u5730\u5740\u4E0D\u5B58\u5728\uFF08HTTP 404\uFF09\uFF1A\u5730\u5740\u586B\u9519\u4E86\u3002` : `Nothing
|
|
694
|
+
return zh ? `${problem.url} \u8FD9\u4E2A\u5730\u5740\u4E0D\u5B58\u5728\uFF08HTTP 404\uFF09\uFF1A\u5730\u5740\u586B\u9519\u4E86\u3002` : `Nothing was found at ${problem.url} (HTTP 404). Check the address.`;
|
|
662
695
|
case "server":
|
|
663
|
-
return zh ? `${service} \u81EA\u5DF1\u51FA\u9519\u4E86\uFF08HTTP ${problem.status}\uFF09\u3002\u8FC7\u4E00\u4F1A\u513F\u518D\u8BD5\u3002` : `${service}
|
|
696
|
+
return zh ? `${service} \u81EA\u5DF1\u51FA\u9519\u4E86\uFF08HTTP ${problem.status}\uFF09\u3002\u8FC7\u4E00\u4F1A\u513F\u518D\u8BD5\u3002` : `${service} returned a server error (HTTP ${problem.status}). Try again later.`;
|
|
664
697
|
case "response":
|
|
665
|
-
return zh ? `${problem.url} \u6709\u56DE\u5E94\uFF0C\u4F46\u4E0D\u662F\u6A21\u578B\u5217\u8868\uFF1A\u68C0\u67E5\u5730\u5740\u548C\u63A5\u53E3\u7C7B\u578B\u3002` : `${problem.url}
|
|
698
|
+
return zh ? `${problem.url} \u6709\u56DE\u5E94\uFF0C\u4F46\u4E0D\u662F\u6A21\u578B\u5217\u8868\uFF1A\u68C0\u67E5\u5730\u5740\u548C\u63A5\u53E3\u7C7B\u578B\u3002` : `${problem.url} responded, but not with a list of models. Check the address and the API type.`;
|
|
666
699
|
case "timeout":
|
|
667
|
-
return zh ? `${seconds} \u79D2\u5185 ${host} \u6CA1\u6709\u56DE\u5E94\u3002\u7F51\u7EDC\u53EF\u80FD\u4E0D\u901A\uFF1A\u6709\u4E9B\u5730\u533A\u8981\u7528\u4EE3\u7406\u6216 VPN \u624D\u80FD\u8BBF\u95EE\u3002${proxyHint}` : `No
|
|
700
|
+
return zh ? `${seconds} \u79D2\u5185 ${host} \u6CA1\u6709\u56DE\u5E94\u3002\u7F51\u7EDC\u53EF\u80FD\u4E0D\u901A\uFF1A\u6709\u4E9B\u5730\u533A\u8981\u7528\u4EE3\u7406\u6216 VPN \u624D\u80FD\u8BBF\u95EE\u3002${proxyHint}` : `No response from ${host} within ${seconds} s. The network may be blocking it; some regions need a proxy or VPN. ${proxyHint}`;
|
|
668
701
|
case "dns":
|
|
669
|
-
return zh ? `\u627E\u4E0D\u5230 ${host}\uFF1A\u6CA1\u6709\u8054\u7F51\uFF0C\u6216\u8FD9\u91CC\u89E3\u6790\u4E0D\u4E86\u8FD9\u4E2A\u57DF\u540D\u3002${proxyHint}` : `
|
|
702
|
+
return zh ? `\u627E\u4E0D\u5230 ${host}\uFF1A\u6CA1\u6709\u8054\u7F51\uFF0C\u6216\u8FD9\u91CC\u89E3\u6790\u4E0D\u4E86\u8FD9\u4E2A\u57DF\u540D\u3002${proxyHint}` : `Couldn't resolve ${host}. Check your internet connection and DNS. ${proxyHint}`;
|
|
670
703
|
case "connection":
|
|
671
704
|
if (local) {
|
|
672
|
-
return zh ? `${host} \u4E0A\u6CA1\u6709\u670D\u52A1\u5728\u76D1\u542C\uFF1A\u5B83\u542F\u52A8\u4E86\u5417\uFF1F` : `Nothing is listening at ${host}
|
|
705
|
+
return zh ? `${host} \u4E0A\u6CA1\u6709\u670D\u52A1\u5728\u76D1\u542C\uFF1A\u5B83\u542F\u52A8\u4E86\u5417\uFF1F` : `Nothing is listening at ${host}. Is the service running?`;
|
|
673
706
|
}
|
|
674
|
-
return zh ? `\u8FDE\u4E0D\u4E0A ${host}\u3002${proxyHint}` : `
|
|
707
|
+
return zh ? `\u8FDE\u4E0D\u4E0A ${host}\u3002${proxyHint}` : `Couldn't connect to ${host}. ${proxyHint}`;
|
|
675
708
|
case "tls":
|
|
676
|
-
return zh ? `\u548C ${host} \u7684\u5B89\u5168\u8FDE\u63A5\u5931\u8D25\u4E86\uFF1A\u53EF\u80FD\u6709\u4EE3\u7406\u6216\u9632\u706B\u5899\u5728\u62E6\u622A HTTPS\u3002` : `The secure connection to ${host} failed
|
|
709
|
+
return zh ? `\u548C ${host} \u7684\u5B89\u5168\u8FDE\u63A5\u5931\u8D25\u4E86\uFF1A\u53EF\u80FD\u6709\u4EE3\u7406\u6216\u9632\u706B\u5899\u5728\u62E6\u622A HTTPS\u3002` : `The secure connection to ${host} failed. A proxy or firewall may be intercepting HTTPS.`;
|
|
677
710
|
default:
|
|
678
|
-
return zh ? `${service} \u62D2\u7EDD\u4E86\u8FD9\u6B21\u68C0\u67E5\uFF08HTTP ${problem.status ?? "?"}\uFF09\u3002${said}` : `${service}
|
|
711
|
+
return zh ? `${service} \u62D2\u7EDD\u4E86\u8FD9\u6B21\u68C0\u67E5\uFF08HTTP ${problem.status ?? "?"}\uFF09\u3002${said}` : `${service} rejected the check (HTTP ${problem.status ?? "?"}).${said}`;
|
|
679
712
|
}
|
|
680
713
|
}
|
|
681
714
|
async function opencodeRefuses(baseUrl, key, fetch, timeoutMs) {
|
|
@@ -809,7 +842,7 @@ var SETUP_SERVICES = [
|
|
|
809
842
|
{
|
|
810
843
|
id: "opencode",
|
|
811
844
|
name: "OpenCode Zen",
|
|
812
|
-
baseUrls: ["https://opencode.ai/
|
|
845
|
+
baseUrls: ["https://opencode.ai/inference/v1"],
|
|
813
846
|
api: "openai-completions",
|
|
814
847
|
models: ["kimi-k2.6"],
|
|
815
848
|
keyPage: "https://opencode.ai/auth",
|
|
@@ -885,6 +918,12 @@ var SETUP_SERVICES = [
|
|
|
885
918
|
keyOptional: true
|
|
886
919
|
}
|
|
887
920
|
];
|
|
921
|
+
var FIRST_IN_ENGLISH = ["openai", "anthropic", "google", "xai", "openrouter", "opencode"];
|
|
922
|
+
function servicesInOrder(language) {
|
|
923
|
+
if (language === "zh") return SETUP_SERVICES;
|
|
924
|
+
const first = FIRST_IN_ENGLISH.flatMap((id) => SETUP_SERVICES.filter((service) => service.id === id));
|
|
925
|
+
return [...first, ...SETUP_SERVICES.filter((service) => !FIRST_IN_ENGLISH.includes(service.id))];
|
|
926
|
+
}
|
|
888
927
|
function serviceById(id) {
|
|
889
928
|
return SETUP_SERVICES.find((service) => service.id === id);
|
|
890
929
|
}
|
|
@@ -893,6 +932,9 @@ function cleanKey(raw) {
|
|
|
893
932
|
if (key.length >= 2 && (key[0] === '"' || key[0] === "'") && key.at(-1) === key[0]) key = key.slice(1, -1).trim();
|
|
894
933
|
return key;
|
|
895
934
|
}
|
|
935
|
+
function isClaudeSubscriptionToken(key) {
|
|
936
|
+
return cleanKey(key).startsWith("sk-ant-oat");
|
|
937
|
+
}
|
|
896
938
|
function servicesForKey(key) {
|
|
897
939
|
const clean = cleanKey(key);
|
|
898
940
|
return clean ? SETUP_SERVICES.filter((service) => service.keyShape?.test(clean)) : [];
|
|
@@ -939,7 +981,7 @@ function namedModel(service) {
|
|
|
939
981
|
|
|
940
982
|
// packages/kyrn-judge/src/setup/wizard.ts
|
|
941
983
|
var SETUP_DECLINED_FILE = "setup-declined";
|
|
942
|
-
var SETUP_EXIT = { done: 0, failed: 1, usage: 2, start: 3, cancelled: 130 };
|
|
984
|
+
var SETUP_EXIT = { done: 0, failed: 1, usage: 2, start: 3, signIn: 4, cancelled: 130 };
|
|
943
985
|
var SETUP_VALUE_FLAGS = [
|
|
944
986
|
"--service",
|
|
945
987
|
"--model",
|
|
@@ -970,6 +1012,10 @@ var JEV_TIERS = /* @__PURE__ */ new Set([
|
|
|
970
1012
|
]);
|
|
971
1013
|
var OPENCODE_KEY = "OPENCODE_API_KEY";
|
|
972
1014
|
var JEV_PAGE = "https://typesafe.ai";
|
|
1015
|
+
var CLAUDE_TOKEN = {
|
|
1016
|
+
zh: "\u8FD9\u662F Claude \u8BA2\u9605\u4EE4\u724C\uFF08claude setup-token \u751F\u6210\u7684\uFF09\uFF0C\u4E0D\u662F API \u5BC6\u94A5\u3002Anthropic \u4E0D\u5141\u8BB8\u5176\u4ED6\u5E94\u7528\u4F7F\u7528 Claude \u8BA2\u9605\uFF0C\u6240\u4EE5 mu \u7528\u4E0D\u4E86\u5B83\u3002\u8BF7\u6539\u7528 Anthropic API \u5BC6\u94A5\uFF08sk-ant-api\u2026\uFF09\uFF0C\u5728\u8FD9\u91CC\u521B\u5EFA\uFF1Ahttps://platform.claude.com/settings/keys",
|
|
1017
|
+
en: "That's a Claude subscription token (from claude setup-token), not an API key. Anthropic doesn't allow other apps to use a Claude subscription, so mu can't use it. Use an Anthropic API key (sk-ant-api\u2026) instead; create one at https://platform.claude.com/settings/keys"
|
|
1018
|
+
};
|
|
973
1019
|
var BRANDED = /* @__PURE__ */ new Set(["openai", "anthropic", "openrouter", "google", "xai"]);
|
|
974
1020
|
var OTHER = {
|
|
975
1021
|
zh: "\u5176\u4ED6 OpenAI \u6216 Anthropic \u517C\u5BB9\u7684\u670D\u52A1",
|
|
@@ -977,7 +1023,7 @@ var OTHER = {
|
|
|
977
1023
|
};
|
|
978
1024
|
var NOT_READY = {
|
|
979
1025
|
zh: "Ollama \u8FD8\u6CA1\u51C6\u5907\u597D\uFF08\u7528 `ollama serve` \u542F\u52A8\u5B83\uFF0C\u518D\u62C9\u53D6\u4E00\u4E2A\u6A21\u578B\uFF09\u3002",
|
|
980
|
-
en: "Ollama
|
|
1026
|
+
en: "Ollama isn't ready yet. Start it with `ollama serve`, then pull a model."
|
|
981
1027
|
};
|
|
982
1028
|
function parseSetupArgs(argv) {
|
|
983
1029
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -1000,14 +1046,14 @@ function parseSetupArgs(argv) {
|
|
|
1000
1046
|
}
|
|
1001
1047
|
const api = values.get("--api");
|
|
1002
1048
|
if (api !== void 0 && api !== "openai" && api !== "anthropic") {
|
|
1003
|
-
return { error: { zh: "--api \u53EA\u80FD\u662F openai \u6216 anthropic", en: "--api
|
|
1049
|
+
return { error: { zh: "--api \u53EA\u80FD\u662F openai \u6216 anthropic", en: "--api must be openai or anthropic" } };
|
|
1004
1050
|
}
|
|
1005
1051
|
const judge = values.get("--judge");
|
|
1006
|
-
if (judge !== void 0 && !["jev", "opencode", "free", "model", "none"].includes(judge)) {
|
|
1052
|
+
if (judge !== void 0 && !["jev", "opencode", "free", "model", "off", "none"].includes(judge)) {
|
|
1007
1053
|
return {
|
|
1008
1054
|
error: {
|
|
1009
|
-
zh: "--judge \u53EA\u80FD\u662F jev\u3001opencode\u3001free\u3001model \u6216 none",
|
|
1010
|
-
en: "--judge
|
|
1055
|
+
zh: "--judge \u53EA\u80FD\u662F jev\u3001opencode\u3001free\u3001model\u3001off \u6216 none",
|
|
1056
|
+
en: "--judge must be jev, opencode, free, model, off or none"
|
|
1011
1057
|
}
|
|
1012
1058
|
};
|
|
1013
1059
|
}
|
|
@@ -1016,11 +1062,11 @@ function parseSetupArgs(argv) {
|
|
|
1016
1062
|
return {
|
|
1017
1063
|
error: {
|
|
1018
1064
|
zh: `\u6CA1\u6709\u53EB ${service} \u7684\u670D\u52A1\uFF08mu setup --list \u5217\u51FA\u5168\u90E8\uFF09`,
|
|
1019
|
-
en: `
|
|
1065
|
+
en: `no service named ${service} (mu setup --list shows them all)`
|
|
1020
1066
|
}
|
|
1021
1067
|
};
|
|
1022
1068
|
}
|
|
1023
|
-
if (words.length > 1) return { error: { zh: "\u53EA\u80FD\u7ED9\u4E00\u4E2A\u5BC6\u94A5", en: "give one key
|
|
1069
|
+
if (words.length > 1) return { error: { zh: "\u53EA\u80FD\u7ED9\u4E00\u4E2A\u5BC6\u94A5", en: "give at most one key" } };
|
|
1024
1070
|
return {
|
|
1025
1071
|
help: flags.has("help"),
|
|
1026
1072
|
list: flags.has("list"),
|
|
@@ -1050,42 +1096,44 @@ function setupUsage(language) {
|
|
|
1050
1096
|
"\u4E3A\u4EC0\u4E48\u811A\u672C\u8981\u4ECE\u6807\u51C6\u8F93\u5165\u7ED9\u5BC6\u94A5\uFF1A\u5199\u5728\u547D\u4EE4\u884C\u4E0A\u7684\u5BC6\u94A5\u4F1A\u7559\u5728 shell \u7684\u5386\u53F2\u8BB0\u5F55\u91CC\uFF0C",
|
|
1051
1097
|
"\u8FD9\u53F0\u7535\u8111\u4E0A\u80FD\u5217\u51FA\u8FDB\u7A0B\u7684\u7A0B\u5E8F\u4E5F\u90FD\u770B\u5F97\u5230\u5B83\u3002mu setup <\u5BC6\u94A5> \u53EA\u662F\u4E3A\u4E86\u4E0A\u624B\u5FEB\uFF1B\u80FD\u5728\u63D0\u793A\u91CC\u7C98\u8D34\u5C31\u7C98\u8D34\u3002",
|
|
1052
1098
|
"",
|
|
1053
|
-
" --judge jev
|
|
1099
|
+
" --judge jev Jev \u5BC6\u94A5\uFF08TypeSafe\uFF09\u5199\u5728\u6807\u51C6\u8F93\u5165\u7684\u7B2C\u4E8C\u884C\uFF1B\u5DF2\u7ECF\u8BBE\u7F6E\u4E86 TYPESAFE_API_KEY \u5C31\u4E0D\u7528",
|
|
1054
1100
|
" --judge opencode OpenCode Zen \u4E0A\u7684 Jev\uFF0C\u7528 OpenCode \u7684\u5BC6\u94A5\uFF08--service opencode \u6216 OPENCODE_API_KEY\uFF09",
|
|
1055
|
-
" --judge free
|
|
1056
|
-
" --judge model
|
|
1057
|
-
" --judge
|
|
1058
|
-
" --
|
|
1059
|
-
" --
|
|
1101
|
+
" --judge free OpenCode Zen \u4E0A\u9650\u65F6\u514D\u8D39\u7684 Jev\uFF0C\u4E0D\u7528\u5BC6\u94A5\uFF08\u6CA1\u6709\u5BC6\u94A5\u65F6\u672C\u6765\u5C31\u7528\u5B83\uFF09",
|
|
1102
|
+
" --judge model \u7528\u521A\u8BBE\u7F6E\u7684\u6A21\u578B\u5F53\u5224\u5B9A\u5668\uFF08\u66F4\u6162\uFF0C\u6BCF\u6B21\u5224\u65AD\u90FD\u82B1 token\uFF09",
|
|
1103
|
+
" --judge off \u4E0D\u7528\u5224\u5B9A\u5668\uFF1A\u6240\u6709\u5224\u5B9A\u70B9\u5173\u95ED\uFF0C\u4EC0\u4E48\u90FD\u4E0D\u53D1\u7ED9\u5224\u5B9A\u5668",
|
|
1104
|
+
" --judge none \u4E0D\u6539\u5224\u5B9A\u5668\uFF1B\u4E0D\u5199 --judge \u65F6\u4E5F\u4E0D\u6539",
|
|
1105
|
+
" --api, --name \u670D\u52A1 other \u7684\u63A5\u53E3\uFF08openai \u6216 anthropic\uFF09\u548C\u5B83\u5728 mu \u91CC\u7684\u540D\u5B57",
|
|
1106
|
+
" --yes \u4E0D\u63D0\u95EE\uFF1B\u66FF\u6362\u5DF2\u6709\u7684\u8BBE\u7F6E\uFF08\u8BA2\u9605\u767B\u5F55\u3001\u540C\u540D\u670D\u52A1\u7684\u5730\u5740\u3001Jev \u5BC6\u94A5\uFF09",
|
|
1060
1107
|
"",
|
|
1061
1108
|
"\u4F1A\u6539\u52A8\u7684\u6587\u4EF6\uFF1A~/.mu/agent \u91CC\u7684 auth.json\uFF08\u5BC6\u94A5\uFF09\u3001models.json\u3001settings.json\u3001mu.json\uFF0C",
|
|
1062
1109
|
"\u4EE5\u53CA mu \u8BFB\u53D6\u7684 .env\uFF08Jev \u5BC6\u94A5\uFF09\u3002\u6BCF\u4E2A\u6587\u4EF6\u6539\u52A8\u524D\u90FD\u4F1A\u5148\u590D\u5236\u5230 ~/.mu/backups/<\u65F6\u95F4>/\u3002"
|
|
1063
1110
|
].join("\n");
|
|
1064
1111
|
}
|
|
1065
1112
|
return [
|
|
1066
|
-
"mu setup: connect a model for mu to work with, and choose
|
|
1113
|
+
"mu setup: connect a model for mu to work with, and choose a judge.",
|
|
1067
1114
|
"",
|
|
1068
|
-
" mu setup
|
|
1069
|
-
" mu setup <key> starts from an API key
|
|
1115
|
+
" mu setup walks you through it, one question at a time",
|
|
1116
|
+
" mu setup <key> starts from an API key and detects its service from the key's format",
|
|
1070
1117
|
" mu setup --service <id> --key-stdin [--model <id>] [--base-url <url>] [--judge <judge>] [--yes]",
|
|
1071
|
-
" for scripts: the key
|
|
1072
|
-
" mu setup --list the services mu knows
|
|
1118
|
+
" for scripts: reads the key from stdin",
|
|
1119
|
+
" mu setup --list lists the services mu knows and their ids",
|
|
1073
1120
|
"",
|
|
1074
|
-
"Why stdin for scripts: a key on the command line stays in your shell
|
|
1075
|
-
"computer that lists processes can read it. `mu setup <key>` is
|
|
1076
|
-
"prompt when you can.",
|
|
1121
|
+
"Why stdin for scripts: a key on the command line stays in your shell history, and any program on this",
|
|
1122
|
+
"computer that lists processes can read it. `mu setup <key>` is a shortcut for getting started; paste the key",
|
|
1123
|
+
"at the prompt when you can.",
|
|
1077
1124
|
"",
|
|
1078
|
-
" --judge jev
|
|
1079
|
-
" --judge opencode Jev on OpenCode Zen
|
|
1080
|
-
" --judge free
|
|
1081
|
-
" --judge model
|
|
1082
|
-
" --judge
|
|
1083
|
-
" --
|
|
1084
|
-
" --
|
|
1085
|
-
"
|
|
1125
|
+
" --judge jev read the Jev key (TypeSafe) from stdin's second line, unless TYPESAFE_API_KEY is already set",
|
|
1126
|
+
" --judge opencode use Jev on OpenCode Zen with an OpenCode key (--service opencode or OPENCODE_API_KEY)",
|
|
1127
|
+
" --judge free use the free Jev on OpenCode Zen (limited time, no key; the default while no key is set)",
|
|
1128
|
+
" --judge model use the model you just set up as the judge (slower, and every verdict costs tokens)",
|
|
1129
|
+
" --judge off no judge: every decision point is off, and nothing is sent to a judge",
|
|
1130
|
+
" --judge none leave the judge unchanged (the same as omitting --judge)",
|
|
1131
|
+
" --api, --name for the service `other`: its API (openai or anthropic) and its name in mu",
|
|
1132
|
+
" --yes don't ask; replace what's already set up (a subscription sign-in, a provider's",
|
|
1133
|
+
" address, the Jev key)",
|
|
1086
1134
|
"",
|
|
1087
|
-
"Files: auth.json (keys), models.json, settings.json and mu.json in ~/.mu/agent, and the .env
|
|
1088
|
-
"(the Jev key). Each is
|
|
1135
|
+
"Files it changes: auth.json (keys), models.json, settings.json and mu.json in ~/.mu/agent, and the .env",
|
|
1136
|
+
"mu reads (the Jev key). Each one is backed up to ~/.mu/backups/<time>/ before it changes."
|
|
1089
1137
|
].join("\n");
|
|
1090
1138
|
}
|
|
1091
1139
|
function label(service, language) {
|
|
@@ -1093,7 +1141,7 @@ function label(service, language) {
|
|
|
1093
1141
|
}
|
|
1094
1142
|
function serviceList(language) {
|
|
1095
1143
|
const width = Math.max(...SETUP_SERVICES.map((service) => service.id.length));
|
|
1096
|
-
return
|
|
1144
|
+
return servicesInOrder(language).map((service) => ` ${service.id.padEnd(width)} ${label(service, language)}`).join("\n");
|
|
1097
1145
|
}
|
|
1098
1146
|
function providerIdFor(baseUrl) {
|
|
1099
1147
|
let host;
|
|
@@ -1202,10 +1250,14 @@ var Setup = class {
|
|
|
1202
1250
|
if (key || allowEmpty) return key;
|
|
1203
1251
|
}
|
|
1204
1252
|
}
|
|
1205
|
-
pasteKey() {
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1253
|
+
async pasteKey() {
|
|
1254
|
+
for (; ; ) {
|
|
1255
|
+
const key = await this.secret(
|
|
1256
|
+
this.t({ zh: "\u7C98\u8D34 API \u5BC6\u94A5\uFF08\u4E0D\u4F1A\u663E\u793A\u51FA\u6765\uFF09\uFF1A", en: "Paste the API key (it won't be shown): " })
|
|
1257
|
+
);
|
|
1258
|
+
if (!isClaudeSubscriptionToken(key)) return key;
|
|
1259
|
+
this.io.warn(this.t(CLAUDE_TOKEN));
|
|
1260
|
+
}
|
|
1209
1261
|
}
|
|
1210
1262
|
async choose(question, choices) {
|
|
1211
1263
|
this.io.say(question);
|
|
@@ -1216,7 +1268,7 @@ var Setup = class {
|
|
|
1216
1268
|
if (answer === "") return choices[0].value;
|
|
1217
1269
|
const number = Number(answer);
|
|
1218
1270
|
if (Number.isInteger(number) && number >= 1 && number <= choices.length) return choices[number - 1].value;
|
|
1219
|
-
this.io.say(this.t({ zh: `\u8BF7\u8F93\u5165 ${range} \u4E4B\u95F4\u7684\u6570\u5B57\u3002`, en: `Type a number from ${
|
|
1271
|
+
this.io.say(this.t({ zh: `\u8BF7\u8F93\u5165 ${range} \u4E4B\u95F4\u7684\u6570\u5B57\u3002`, en: `Type a number from 1 to ${choices.length}.` }));
|
|
1220
1272
|
}
|
|
1221
1273
|
}
|
|
1222
1274
|
async confirm(question, yes) {
|
|
@@ -1236,7 +1288,7 @@ var Setup = class {
|
|
|
1236
1288
|
throw this.fail(
|
|
1237
1289
|
{
|
|
1238
1290
|
zh: "--key-stdin \u4ECE\u7BA1\u9053\u8BFB\u5BC6\u94A5\u3002\u5728\u7EC8\u7AEF\u91CC\u8BF7\u76F4\u63A5\u8FD0\u884C mu setup\uFF0C\u5728\u63D0\u793A\u91CC\u7C98\u8D34\u5BC6\u94A5\uFF08\u4E0D\u4F1A\u663E\u793A\uFF09\u3002",
|
|
1239
|
-
en: "--key-stdin reads the key from a pipe. In a terminal, run mu setup and paste the key at
|
|
1291
|
+
en: "--key-stdin reads the key from a pipe. In a terminal, run mu setup and paste the key at the prompt (it won't be shown)."
|
|
1240
1292
|
},
|
|
1241
1293
|
SETUP_EXIT.usage
|
|
1242
1294
|
);
|
|
@@ -1245,11 +1297,12 @@ var Setup = class {
|
|
|
1245
1297
|
key = modelKey;
|
|
1246
1298
|
this.jevFromStdin = jevKey;
|
|
1247
1299
|
}
|
|
1300
|
+
if (key !== void 0 && isClaudeSubscriptionToken(key)) throw this.fail(CLAUDE_TOKEN, SETUP_EXIT.usage);
|
|
1248
1301
|
if (this.scripted && key === void 0 && args.service === void 0) {
|
|
1249
1302
|
throw this.fail(
|
|
1250
|
-
deps.interactive ? { zh: "\u6CA1\u6709\u5BC6\u94A5\uFF0C\u4E5F\u6CA1\u6709 --service", en: "no key
|
|
1303
|
+
deps.interactive ? { zh: "\u6CA1\u6709\u5BC6\u94A5\uFF0C\u4E5F\u6CA1\u6709 --service", en: "no key or --service given" } : {
|
|
1251
1304
|
zh: "\u95EE\u9898\u8981\u5728\u7EC8\u7AEF\u91CC\u56DE\u7B54\u3002\u811A\u672C\u91CC\u7528\uFF1Amu setup --service <id> --key-stdin\uFF08\u89C1 mu setup --help\uFF09",
|
|
1252
|
-
en: "
|
|
1305
|
+
en: "no terminal to ask in. In a script, use mu setup --service <id> --key-stdin (see mu setup --help)"
|
|
1253
1306
|
},
|
|
1254
1307
|
SETUP_EXIT.usage
|
|
1255
1308
|
);
|
|
@@ -1258,14 +1311,14 @@ var Setup = class {
|
|
|
1258
1311
|
this.io.say(
|
|
1259
1312
|
this.t({
|
|
1260
1313
|
zh: "mu setup\uFF1A\u7ED9 mu \u63A5\u4E0A\u4E00\u4E2A\u5E72\u6D3B\u7684\u6A21\u578B\uFF0C\u518D\u9009\u4E00\u4E2A\u5224\u5B9A\u5668\u3002",
|
|
1261
|
-
en: "mu setup: connect a model for mu to work with, and choose
|
|
1314
|
+
en: "mu setup: connect a model for mu to work with, and choose a judge."
|
|
1262
1315
|
})
|
|
1263
1316
|
);
|
|
1264
1317
|
}
|
|
1265
1318
|
const start = await this.start(key === void 0 ? void 0 : cleanKey(key));
|
|
1266
1319
|
if (start === "subscription") {
|
|
1267
1320
|
const code2 = await this.write(void 0, void 0, await this.judge(void 0));
|
|
1268
|
-
return code2 === SETUP_EXIT.done ? this.offerSession() : code2;
|
|
1321
|
+
return code2 === SETUP_EXIT.done ? this.offerSession(true) : code2;
|
|
1269
1322
|
}
|
|
1270
1323
|
const target = await this.checked(start.service, start.key);
|
|
1271
1324
|
this.modelKey = target.key;
|
|
@@ -1296,7 +1349,7 @@ var Setup = class {
|
|
|
1296
1349
|
this.io.say(
|
|
1297
1350
|
this.t({
|
|
1298
1351
|
zh: "\u597D\u7684\uFF0C\u4EE5\u540E\u4E0D\u518D\u95EE\u4E86\u3002\u9700\u8981\u65F6\u8FD0\u884C mu setup\uFF0C\u6216\u5728 mu \u91CC\u8F93\u5165 /login\u3002",
|
|
1299
|
-
en: "OK, mu
|
|
1352
|
+
en: "OK, mu won't ask again. Run mu setup whenever you're ready, or type /login inside mu."
|
|
1300
1353
|
})
|
|
1301
1354
|
);
|
|
1302
1355
|
return false;
|
|
@@ -1308,34 +1361,37 @@ var Setup = class {
|
|
|
1308
1361
|
const named2 = this.args.service === void 0 ? void 0 : serviceById(this.args.service);
|
|
1309
1362
|
if (named2) return this.keyFor(named2, key);
|
|
1310
1363
|
if (key !== void 0) return { service: await this.serviceOf(key), key };
|
|
1311
|
-
const route = await this.choose(
|
|
1312
|
-
{
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
label: this.t({
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1364
|
+
const route = await this.choose(
|
|
1365
|
+
this.t({ zh: "mu \u7528\u4EC0\u4E48\u65B9\u5F0F\u8FDE\u63A5\u6A21\u578B\uFF1F", en: "How should mu connect to a model?" }),
|
|
1366
|
+
[
|
|
1367
|
+
{
|
|
1368
|
+
label: this.t({
|
|
1369
|
+
zh: "\u7C98\u8D34 API \u5BC6\u94A5\uFF08mu \u4F1A\u8BA4\u51FA\u5B83\u5C5E\u4E8E\u54EA\u4E2A\u670D\u52A1\uFF09",
|
|
1370
|
+
en: "Paste an API key (mu detects which service it belongs to)"
|
|
1371
|
+
}),
|
|
1372
|
+
value: "key"
|
|
1373
|
+
},
|
|
1374
|
+
{ label: this.t({ zh: "\u4ECE\u5217\u8868\u91CC\u9009\u4E00\u4E2A\u670D\u52A1", en: "Choose a service from the list" }), value: "list" },
|
|
1375
|
+
{
|
|
1376
|
+
label: this.t({
|
|
1377
|
+
zh: "\u7528\u8BA2\u9605\u8D26\u53F7\u767B\u5F55\uFF1AChatGPT\u3001Grok \u6216 Google",
|
|
1378
|
+
en: "Sign in with a subscription: ChatGPT, Grok or Google"
|
|
1379
|
+
}),
|
|
1380
|
+
value: "subscription"
|
|
1381
|
+
}
|
|
1382
|
+
]
|
|
1383
|
+
);
|
|
1328
1384
|
if (route === "subscription") {
|
|
1329
1385
|
const auth = this.path(join3(this.deps.paths.agentDir, "auth.json"));
|
|
1330
1386
|
this.io.say(
|
|
1331
1387
|
this.t({
|
|
1332
|
-
zh: `\u8BA2\u9605\u8D26\u53F7\u5728 mu \u91CC\u9762\u767B\u5F55\uFF1A\u542F\u52A8 mu\uFF0C\u8F93\u5165 /login\uFF0C\u9009
|
|
1333
|
-
en: `
|
|
1388
|
+
zh: `\u8BA2\u9605\u8D26\u53F7\u5728 mu \u91CC\u9762\u767B\u5F55\uFF1A\u542F\u52A8 mu\uFF0C\u8F93\u5165 /login\uFF0C\u9009 Sign in with an account\uFF0C\u518D\u9009 OpenAI\uFF08ChatGPT\uFF09\u3001xAI\uFF08Grok\uFF09\u6216 Google \u7684\u4E00\u9879\uFF0C\u6309\u63D0\u793A\u5728\u6D4F\u89C8\u5668\u91CC\u5B8C\u6210\u3002\u767B\u5F55\u4FE1\u606F\u4FDD\u5B58\u5728 ${auth}\u3002`,
|
|
1389
|
+
en: `To use a subscription, sign in from inside mu: start mu, type /login, choose Sign in with an account, then OpenAI for ChatGPT, xAI for Grok, or one of the Google sign-ins, and finish in the browser. The sign-in is saved in ${auth}.`
|
|
1334
1390
|
})
|
|
1335
1391
|
);
|
|
1336
1392
|
return "subscription";
|
|
1337
1393
|
}
|
|
1338
|
-
if (route === "list") return this.keyFor(await this.pickService(
|
|
1394
|
+
if (route === "list") return this.keyFor(await this.pickService(servicesInOrder(this.language)), void 0);
|
|
1339
1395
|
const pasted = await this.pasteKey();
|
|
1340
1396
|
return { service: await this.serviceOf(pasted), key: pasted };
|
|
1341
1397
|
}
|
|
@@ -1364,10 +1420,10 @@ var Setup = class {
|
|
|
1364
1420
|
throw this.fail(
|
|
1365
1421
|
matches.length > 1 ? {
|
|
1366
1422
|
zh: `${this.names(matches)} \u7684\u5BC6\u94A5\u957F\u5F97\u4E00\u6837\u3002\u7528 --service \u8BF4\u660E\u662F\u54EA\u5BB6\uFF1A${matches.map((service) => service.id).join(" \u6216 ")}`,
|
|
1367
|
-
en:
|
|
1423
|
+
en: `${this.names(matches)} keys look the same. Choose one with --service ${matches.map((service) => service.id).join(" or ")}`
|
|
1368
1424
|
} : {
|
|
1369
1425
|
zh: "\u8BA4\u4E0D\u51FA\u8FD9\u4E2A\u5BC6\u94A5\u5C5E\u4E8E\u54EA\u4E2A\u670D\u52A1\u3002\u7528 --service <id> \u8BF4\u660E\uFF08mu setup --list \u5217\u51FA\u5168\u90E8\uFF09",
|
|
1370
|
-
en: "this key's
|
|
1426
|
+
en: "mu doesn't recognize this key's format. Say which service it's for with --service <id> (mu setup --list)"
|
|
1371
1427
|
},
|
|
1372
1428
|
SETUP_EXIT.usage
|
|
1373
1429
|
);
|
|
@@ -1377,15 +1433,15 @@ var Setup = class {
|
|
|
1377
1433
|
matches,
|
|
1378
1434
|
this.t({
|
|
1379
1435
|
zh: `${this.names(matches)} \u7684\u5BC6\u94A5\u957F\u5F97\u4E00\u6837\u3002\u8FD9\u4E2A\u5BC6\u94A5\u662F\u54EA\u5BB6\u7684\uFF1Fmu \u53EA\u628A\u5BC6\u94A5\u53D1\u7ED9\u5B83\u6240\u5C5E\u7684\u670D\u52A1\u3002`,
|
|
1380
|
-
en:
|
|
1436
|
+
en: `${this.names(matches)} keys look the same. Which service is this key for? mu only sends a key to the service it belongs to.`
|
|
1381
1437
|
})
|
|
1382
1438
|
);
|
|
1383
1439
|
}
|
|
1384
1440
|
return this.pickService(
|
|
1385
|
-
|
|
1441
|
+
servicesInOrder(this.language).filter((service) => !service.keyless),
|
|
1386
1442
|
this.t({
|
|
1387
1443
|
zh: "mu \u8BA4\u4E0D\u51FA\u8FD9\u4E2A\u5BC6\u94A5\u3002\u5B83\u662F\u54EA\u4E2A\u670D\u52A1\u7684\uFF1F",
|
|
1388
|
-
en: "mu
|
|
1444
|
+
en: "mu doesn't recognize this key. Which service is it for?"
|
|
1389
1445
|
})
|
|
1390
1446
|
);
|
|
1391
1447
|
}
|
|
@@ -1396,9 +1452,7 @@ var Setup = class {
|
|
|
1396
1452
|
let key = given;
|
|
1397
1453
|
if (key === void 0 && !this.scripted) {
|
|
1398
1454
|
if (service.keyPage) {
|
|
1399
|
-
this.io.say(
|
|
1400
|
-
this.t({ zh: `\u5BC6\u94A5\u5728\u8FD9\u91CC\u521B\u5EFA\uFF1A${service.keyPage}`, en: `Keys are made at ${service.keyPage}` })
|
|
1401
|
-
);
|
|
1455
|
+
this.io.say(this.t({ zh: `\u5BC6\u94A5\u5728\u8FD9\u91CC\u521B\u5EFA\uFF1A${service.keyPage}`, en: `Create a key at ${service.keyPage}` }));
|
|
1402
1456
|
}
|
|
1403
1457
|
key = await this.pasteKey();
|
|
1404
1458
|
}
|
|
@@ -1416,7 +1470,7 @@ var Setup = class {
|
|
|
1416
1470
|
this.io.warn(
|
|
1417
1471
|
this.t({
|
|
1418
1472
|
zh: `\u6CE8\u610F\uFF1A\u8FD9\u4E2A\u5BC6\u94A5\u770B\u8D77\u6765\u662F ${this.names(matches)} \u7684\uFF1B\u6309 --service \u53D1\u7ED9 ${this.name(service)}\u3002`,
|
|
1419
|
-
en: `Note: this key looks like ${article(this.names(matches))} key; it
|
|
1473
|
+
en: `Note: this key looks like ${article(this.names(matches))} key; sending it to ${this.name(service)}, as --service says.`
|
|
1420
1474
|
})
|
|
1421
1475
|
);
|
|
1422
1476
|
return { service, key };
|
|
@@ -1463,11 +1517,14 @@ var Setup = class {
|
|
|
1463
1517
|
);
|
|
1464
1518
|
if (/^https?:\/\/[^\s/]+/i.test(baseUrl)) break;
|
|
1465
1519
|
this.io.say(
|
|
1466
|
-
this.t({
|
|
1520
|
+
this.t({
|
|
1521
|
+
zh: "\u5730\u5740\u4EE5 http:// \u6216 https:// \u5F00\u5934\u3002",
|
|
1522
|
+
en: "The address must start with http:// or https://."
|
|
1523
|
+
})
|
|
1467
1524
|
);
|
|
1468
1525
|
}
|
|
1469
1526
|
}
|
|
1470
|
-
const api = args.api === "anthropic" ? "anthropic-messages" : args.api === "openai" || this.scripted ? "openai-completions" : await this.choose(this.t({ zh: "\u5B83\u7528\u54EA\u79CD\u63A5\u53E3\uFF1F", en: "Which API does it
|
|
1527
|
+
const api = args.api === "anthropic" ? "anthropic-messages" : args.api === "openai" || this.scripted ? "openai-completions" : await this.choose(this.t({ zh: "\u5B83\u7528\u54EA\u79CD\u63A5\u53E3\uFF1F", en: "Which API does it use?" }), [
|
|
1471
1528
|
{
|
|
1472
1529
|
label: this.t({
|
|
1473
1530
|
zh: "OpenAI \u517C\u5BB9\uFF08chat completions\uFF09",
|
|
@@ -1489,7 +1546,7 @@ var Setup = class {
|
|
|
1489
1546
|
const typed = await this.ask(
|
|
1490
1547
|
this.t({
|
|
1491
1548
|
zh: `\u7ED9\u5B83\u8D77\u4E2A\u7B80\u77ED\u7684\u540D\u5B57\uFF08\u5B57\u6BCD\u3001\u6570\u5B57\u3001-\uFF09[${provider}]\uFF1A`,
|
|
1492
|
-
en: `A short name for it in mu (letters, digits
|
|
1549
|
+
en: `A short name for it in mu (letters, digits and -) [${provider}]: `
|
|
1493
1550
|
})
|
|
1494
1551
|
);
|
|
1495
1552
|
if (typed) provider = typed.toLowerCase().replace(/[^a-z0-9-]+/g, "-");
|
|
@@ -1518,7 +1575,7 @@ var Setup = class {
|
|
|
1518
1575
|
key = await this.secret(
|
|
1519
1576
|
this.t({
|
|
1520
1577
|
zh: "\u7C98\u8D34\u5B83\u7684 API \u5BC6\u94A5\uFF1B\u4E0D\u9700\u8981\u5BC6\u94A5\u5C31\u76F4\u63A5\u56DE\u8F66\uFF08\u4E0D\u4F1A\u663E\u793A\uFF09\uFF1A",
|
|
1521
|
-
en: "Paste its API key, or press Enter if it
|
|
1578
|
+
en: "Paste its API key, or press Enter if it doesn't need one (it won't be shown): "
|
|
1522
1579
|
}),
|
|
1523
1580
|
true
|
|
1524
1581
|
) || void 0;
|
|
@@ -1537,15 +1594,15 @@ var Setup = class {
|
|
|
1537
1594
|
choices.push({ label: this.t({ zh: "\u518D\u8BD5\u4E00\u6B21", en: "Try again" }), value: "again" });
|
|
1538
1595
|
if (result.problem.kind !== "key") {
|
|
1539
1596
|
choices.push({
|
|
1540
|
-
label: this.t({ zh: "\u4E0D\u68C0\u67E5\u4E86\uFF0C\u7167\u6837\u4FDD\u5B58", en: "Save it without
|
|
1597
|
+
label: this.t({ zh: "\u4E0D\u68C0\u67E5\u4E86\uFF0C\u7167\u6837\u4FDD\u5B58", en: "Save it without checking" }),
|
|
1541
1598
|
value: "unchecked"
|
|
1542
1599
|
});
|
|
1543
1600
|
}
|
|
1544
1601
|
choices.push({
|
|
1545
|
-
label: this.t({ zh: "\u5230\u6B64\u4E3A\u6B62\uFF08\u4EC0\u4E48\u90FD\u4E0D\u6539\uFF09", en: "Stop here (nothing
|
|
1602
|
+
label: this.t({ zh: "\u5230\u6B64\u4E3A\u6B62\uFF08\u4EC0\u4E48\u90FD\u4E0D\u6539\uFF09", en: "Stop here (change nothing)" }),
|
|
1546
1603
|
value: "stop"
|
|
1547
1604
|
});
|
|
1548
|
-
const next = await this.choose(this.t({ zh: "\u63A5\u4E0B\u6765\u600E\u4E48\u529E\uFF1F", en: "What
|
|
1605
|
+
const next = await this.choose(this.t({ zh: "\u63A5\u4E0B\u6765\u600E\u4E48\u529E\uFF1F", en: "What next?" }), choices);
|
|
1549
1606
|
if (next === "stop") throw this.cancelled();
|
|
1550
1607
|
if (next === "unchecked") return { service, reach: reaches[0], key };
|
|
1551
1608
|
if (next === "key") key = await this.pasteKey();
|
|
@@ -1561,10 +1618,10 @@ var Setup = class {
|
|
|
1561
1618
|
this.io.say(
|
|
1562
1619
|
key ? this.t({
|
|
1563
1620
|
zh: `\u6B63\u5728\u7528 ${where}\u68C0\u67E5\u5BC6\u94A5\u2026\u2026`,
|
|
1564
|
-
en: `Checking the key with ${this.name(service)} (${hostOf2(reach.baseUrl)})
|
|
1621
|
+
en: `Checking the key with ${this.name(service)} (${hostOf2(reach.baseUrl)})\u2026`
|
|
1565
1622
|
}) : this.t({
|
|
1566
1623
|
zh: `\u6B63\u5728\u68C0\u67E5 ${where}\u2026\u2026`,
|
|
1567
|
-
en: `Checking ${this.name(service)} (${hostOf2(reach.baseUrl)})
|
|
1624
|
+
en: `Checking ${this.name(service)} (${hostOf2(reach.baseUrl)})\u2026`
|
|
1568
1625
|
})
|
|
1569
1626
|
);
|
|
1570
1627
|
const result = await checkKey({
|
|
@@ -1579,7 +1636,7 @@ var Setup = class {
|
|
|
1579
1636
|
this.io.say(
|
|
1580
1637
|
count === void 0 ? this.t({ zh: "\u5BC6\u94A5\u53EF\u4EE5\u7528\u3002", en: "The key works." }) : this.t({
|
|
1581
1638
|
zh: `\u53EF\u4EE5\u7528\uFF1A\u5217\u51FA\u4E86 ${count} \u4E2A\u6A21\u578B\u3002`,
|
|
1582
|
-
en: `It works: ${count} model${count === 1 ? "" : "s"}
|
|
1639
|
+
en: `It works: ${count} model${count === 1 ? "" : "s"} available.`
|
|
1583
1640
|
})
|
|
1584
1641
|
);
|
|
1585
1642
|
return { ok: true, reach, listed: result.models };
|
|
@@ -1603,13 +1660,13 @@ var Setup = class {
|
|
|
1603
1660
|
if (this.scripted) {
|
|
1604
1661
|
throw this.fail({
|
|
1605
1662
|
zh: `${this.name(service)} \u5DF2\u7ECF\u7528\u8BA2\u9605\u8D26\u53F7\u767B\u5F55\u4E86\u3002\u8981\u6539\u5B58\u5BC6\u94A5\uFF0C\u52A0\u4E0A --yes`,
|
|
1606
|
-
en:
|
|
1663
|
+
en: `You're signed in to ${this.name(service)} with a subscription. To use a key instead, add --yes`
|
|
1607
1664
|
});
|
|
1608
1665
|
}
|
|
1609
1666
|
const replace = await this.confirm(
|
|
1610
1667
|
this.t({
|
|
1611
1668
|
zh: `\u4F60\u5DF2\u7ECF\u7528\u8BA2\u9605\u8D26\u53F7\u767B\u5F55\u4E86 ${this.name(service)}\u3002\u6539\u7528\u8FD9\u4E2A\u5BC6\u94A5\u5417\uFF1F\u767B\u5F55\u4F1A\u88AB\u66FF\u6362\uFF08\u7559\u6709\u5907\u4EFD\uFF09\u3002[y/N] `,
|
|
1612
|
-
en: `You
|
|
1669
|
+
en: `You're signed in to ${this.name(service)} with a subscription. Use this key instead? It replaces the sign-in (a backup is kept). [y/N] `
|
|
1613
1670
|
}),
|
|
1614
1671
|
false
|
|
1615
1672
|
);
|
|
@@ -1622,7 +1679,7 @@ var Setup = class {
|
|
|
1622
1679
|
if (readJsonFile(path).state !== "unreadable") return;
|
|
1623
1680
|
throw this.fail({
|
|
1624
1681
|
zh: `${this.path(path)} \u4E0D\u662F\u7EAF JSON\uFF08\u4E5F\u8BB8\u6709\u6CE8\u91CA\u6216\u5199\u9519\u4E86\uFF09\uFF0Cmu setup \u4E0D\u6539\u5199\u5B83\u3002\u5148\u4FEE\u597D\u5B83\uFF0C\u6216\u624B\u52A8\u628A\u670D\u52A1\u52A0\u8FDB\u53BB\u3002`,
|
|
1625
|
-
en: `${this.path(path)}
|
|
1682
|
+
en: `${this.path(path)} isn't plain JSON (it may have comments or a typo), so mu setup won't rewrite it. Fix it, or add the service by hand.`
|
|
1626
1683
|
});
|
|
1627
1684
|
}
|
|
1628
1685
|
// -----------------------------------------------------------------------------------------------------------
|
|
@@ -1635,7 +1692,7 @@ var Setup = class {
|
|
|
1635
1692
|
this.io.say(
|
|
1636
1693
|
this.t({
|
|
1637
1694
|
zh: `\u6CE8\u610F\uFF1A${this.name(service)} \u6CA1\u6709\u5217\u51FA ${this.args.model}\uFF0C\u7167\u6837\u4F7F\u7528\u3002`,
|
|
1638
|
-
en: `Note: ${this.name(service)}
|
|
1695
|
+
en: `Note: ${this.name(service)} doesn't list ${this.args.model}; using it anyway.`
|
|
1639
1696
|
})
|
|
1640
1697
|
);
|
|
1641
1698
|
}
|
|
@@ -1651,14 +1708,14 @@ var Setup = class {
|
|
|
1651
1708
|
if (options.length === 0) {
|
|
1652
1709
|
const none = service.keyless ? NOT_READY : {
|
|
1653
1710
|
zh: `${this.name(service)} \u6CA1\u6709\u5217\u51FA\u6A21\u578B\u3002`,
|
|
1654
|
-
en: `${this.name(service)}
|
|
1711
|
+
en: `${this.name(service)} doesn't list any models.`
|
|
1655
1712
|
};
|
|
1656
1713
|
if (this.scripted) {
|
|
1657
|
-
throw this.fail({ zh: `${none.zh}\u53EF\u4EE5\u7528 --model \u6307\u5B9A\u4E00\u4E2A\u3002`, en: `${none.en}
|
|
1714
|
+
throw this.fail({ zh: `${none.zh}\u53EF\u4EE5\u7528 --model \u6307\u5B9A\u4E00\u4E2A\u3002`, en: `${none.en} Specify one with --model.` });
|
|
1658
1715
|
}
|
|
1659
1716
|
this.io.say(this.t(none));
|
|
1660
1717
|
for (; ; ) {
|
|
1661
|
-
const typed = await this.ask(this.t({ zh: "\u8981\u7528\u7684\u6A21\u578B\u540D\uFF1A", en: "
|
|
1718
|
+
const typed = await this.ask(this.t({ zh: "\u8981\u7528\u7684\u6A21\u578B\u540D\uFF1A", en: "Name of the model to use: " }));
|
|
1662
1719
|
if (typed) return typed;
|
|
1663
1720
|
}
|
|
1664
1721
|
}
|
|
@@ -1674,7 +1731,7 @@ var Setup = class {
|
|
|
1674
1731
|
this.io.say(
|
|
1675
1732
|
this.t({
|
|
1676
1733
|
zh: ` \uFF08\u8FD8\u6709 ${more} \u4E2A\uFF0C\u8F93\u5165\u540D\u5B57\u4E5F\u53EF\u4EE5\uFF09`,
|
|
1677
|
-
en: ` (${more} more
|
|
1734
|
+
en: ` (${more} more; type a name to use one of them)`
|
|
1678
1735
|
})
|
|
1679
1736
|
);
|
|
1680
1737
|
}
|
|
@@ -1692,7 +1749,7 @@ var Setup = class {
|
|
|
1692
1749
|
this.io.say(
|
|
1693
1750
|
this.t({
|
|
1694
1751
|
zh: `\u8BF7\u8F93\u5165 1-${shown.length} \u4E4B\u95F4\u7684\u6570\u5B57\uFF0C\u6216\u6A21\u578B\u540D\u3002`,
|
|
1695
|
-
en: `Type a number from 1
|
|
1752
|
+
en: `Type a number from 1 to ${shown.length}, or a model name.`
|
|
1696
1753
|
})
|
|
1697
1754
|
);
|
|
1698
1755
|
}
|
|
@@ -1708,13 +1765,13 @@ var Setup = class {
|
|
|
1708
1765
|
if (this.scripted) {
|
|
1709
1766
|
throw this.fail({
|
|
1710
1767
|
zh: `models.json \u91CC\u7684 ${target.reach.provider} \u6307\u5411 ${old}\u3002\u8981\u6539\u6210 ${target.reach.baseUrl}\uFF0C\u52A0\u4E0A --yes`,
|
|
1711
|
-
en: `models.json
|
|
1768
|
+
en: `models.json already points ${target.reach.provider} at ${old}. To point it at ${target.reach.baseUrl}, add --yes`
|
|
1712
1769
|
});
|
|
1713
1770
|
}
|
|
1714
1771
|
const move = await this.confirm(
|
|
1715
1772
|
this.t({
|
|
1716
1773
|
zh: `models.json \u91CC\u5DF2\u7ECF\u6709 ${target.reach.provider}\uFF0C\u5730\u5740\u662F ${old}\u3002\u6539\u6210 ${target.reach.baseUrl} \u5417\uFF1F[y/N] `,
|
|
1717
|
-
en: `models.json already
|
|
1774
|
+
en: `models.json already points ${target.reach.provider} at ${old}. Point it at ${target.reach.baseUrl} instead? [y/N] `
|
|
1718
1775
|
}),
|
|
1719
1776
|
false
|
|
1720
1777
|
);
|
|
@@ -1739,7 +1796,7 @@ var Setup = class {
|
|
|
1739
1796
|
choices.push({
|
|
1740
1797
|
label: this.t({
|
|
1741
1798
|
zh: "Jev \u514D\u8D39\u7248\uFF08\u63A8\u8350\uFF09\uFF0C\u5728 OpenCode Zen \u4E0A\uFF1A\u4E0D\u7528\u5BC6\u94A5\uFF0C\u9650\u65F6\u514D\u8D39\uFF1B\u4EE5\u540E\u52A0\u4E86\u5BC6\u94A5\u81EA\u52A8\u6362\u7528",
|
|
1742
|
-
en: "Jev
|
|
1799
|
+
en: "Free Jev on OpenCode Zen (recommended): no key needed, free for a limited time; a key you add later takes over"
|
|
1743
1800
|
}),
|
|
1744
1801
|
value: "free"
|
|
1745
1802
|
});
|
|
@@ -1748,7 +1805,7 @@ var Setup = class {
|
|
|
1748
1805
|
choices.push({
|
|
1749
1806
|
label: this.t({
|
|
1750
1807
|
zh: "Jev\uFF08\u63A8\u8350\uFF09\uFF0C\u5728 OpenCode Zen \u4E0A\uFF0C\u7528\u4F60\u7684 OpenCode \u5BC6\u94A5\uFF0C\u6309\u6B21\u8BA1\u8D39",
|
|
1751
|
-
en: "Jev
|
|
1808
|
+
en: "Jev on OpenCode Zen with your OpenCode key (recommended), billed per call"
|
|
1752
1809
|
}),
|
|
1753
1810
|
value: "opencode"
|
|
1754
1811
|
});
|
|
@@ -1757,18 +1814,18 @@ var Setup = class {
|
|
|
1757
1814
|
choices.push({
|
|
1758
1815
|
label: this.t({
|
|
1759
1816
|
zh: `Jev\uFF08\u63A8\u8350\uFF09\uFF0C\u7528\u5DF2\u7ECF\u8BBE\u7F6E\u7684\u5BC6\u94A5\uFF08${where}\uFF09`,
|
|
1760
|
-
en: `Jev
|
|
1817
|
+
en: `Jev with the key that's already set (recommended): ${where}`
|
|
1761
1818
|
}),
|
|
1762
1819
|
value: "keep"
|
|
1763
1820
|
});
|
|
1764
1821
|
}
|
|
1765
1822
|
choices.push({
|
|
1766
|
-
label: where ? this.t({ zh: "Jev\uFF0C\u6362\u4E00\u4E2A\u65B0\u5BC6\u94A5", en: "Jev
|
|
1823
|
+
label: where ? this.t({ zh: "Jev\uFF0C\u6362\u4E00\u4E2A\u65B0\u5BC6\u94A5", en: "Jev with a new key" }) : opencode ? this.t({
|
|
1767
1824
|
zh: `Jev\uFF0C\u7528 TypeSafe \u7684\u5BC6\u94A5\uFF1A${JEV_PAGE}`,
|
|
1768
1825
|
en: `Jev with a TypeSafe key: ${JEV_PAGE}`
|
|
1769
1826
|
}) : this.t({
|
|
1770
|
-
zh: `Jev\uFF0C\u7528\u81EA\u5DF1\u7684\u5BC6\u94A5\uFF1A\
|
|
1771
|
-
en: `Jev with
|
|
1827
|
+
zh: `Jev\uFF0C\u7528\u81EA\u5DF1\u7684\u5BC6\u94A5\uFF1A\u6BCF\u4E2A\u95EE\u9898\u7EA6 0.3 \u79D2\uFF0C\u6309\u6B21\u8BA1\u8D39\u3002\u5BC6\u94A5\u5728 TypeSafe \u7533\u8BF7\uFF1A${JEV_PAGE}`,
|
|
1828
|
+
en: `Jev with your own key: about 0.3 s per question, billed per call. Get a key from TypeSafe: ${JEV_PAGE}`
|
|
1772
1829
|
}),
|
|
1773
1830
|
value: "jev"
|
|
1774
1831
|
});
|
|
@@ -1776,7 +1833,7 @@ var Setup = class {
|
|
|
1776
1833
|
choices.push({
|
|
1777
1834
|
label: this.t({
|
|
1778
1835
|
zh: "Jev \u514D\u8D39\u7248\uFF0C\u5728 OpenCode Zen \u4E0A\uFF1A\u4E0D\u7528\u5BC6\u94A5\uFF0C\u9650\u65F6\u514D\u8D39",
|
|
1779
|
-
en: "Jev
|
|
1836
|
+
en: "Free Jev on OpenCode Zen: no key needed, free for a limited time"
|
|
1780
1837
|
}),
|
|
1781
1838
|
value: "free"
|
|
1782
1839
|
});
|
|
@@ -1785,22 +1842,22 @@ var Setup = class {
|
|
|
1785
1842
|
choices.push({
|
|
1786
1843
|
label: this.t({
|
|
1787
1844
|
zh: `\u521A\u8BBE\u7F6E\u7684\u6A21\u578B\uFF08${model.provider}/${model.model}\uFF09\uFF1A\u66F4\u6162\uFF0C\u800C\u4E14\u6BCF\u6B21\u5224\u65AD\u90FD\u8981\u82B1 token`,
|
|
1788
|
-
en: `The model you just set up (${model.provider}/${model.model}): slower, and every
|
|
1845
|
+
en: `The model you just set up (${model.provider}/${model.model}): slower, and every verdict costs tokens`
|
|
1789
1846
|
}),
|
|
1790
1847
|
value: "model"
|
|
1791
1848
|
});
|
|
1792
1849
|
}
|
|
1793
1850
|
choices.push({
|
|
1794
1851
|
label: this.t({
|
|
1795
|
-
zh: "\u6682\u65F6\u4E0D\u8981\
|
|
1796
|
-
en: "Not now:
|
|
1852
|
+
zh: "\u6682\u65F6\u4E0D\u8981\uFF1A\u4E0D\u95EE\u5224\u5B9A\u5668\uFF0C\u4EC0\u4E48\u90FD\u4E0D\u53D1\u7ED9\u5B83\uFF0Cmu \u6309\u9ED8\u8BA4\u89C4\u5219\u5DE5\u4F5C",
|
|
1853
|
+
en: "Not now: no judge is asked and nothing is sent to one; mu uses its fallbacks"
|
|
1797
1854
|
}),
|
|
1798
1855
|
value: "none"
|
|
1799
1856
|
});
|
|
1800
1857
|
const picked = await this.choose(
|
|
1801
1858
|
this.t({
|
|
1802
1859
|
zh: "mu \u5DE5\u4F5C\u65F6\u8981\u505A\u5F88\u591A\u5C0F\u5224\u65AD\uFF1A\u8FD9\u6761\u6D88\u606F\u8BE5\u600E\u4E48\u5904\u7406\u3001\u8FD9\u4E00\u6B65\u4F1A\u4E0D\u4F1A\u8FDD\u53CD\u4F60\u5B9A\u7684\u89C4\u5219\u2026\u2026\u5224\u5B9A\u5668\u8D1F\u8D23\u56DE\u7B54\u3002\u9009\u54EA\u4E2A\u5224\u5B9A\u5668\uFF1F",
|
|
1803
|
-
en: "mu
|
|
1860
|
+
en: "As it works, mu faces many small decisions: how to handle a message, whether a step breaks your rules. A judge answers them. Which judge do you want?"
|
|
1804
1861
|
}),
|
|
1805
1862
|
choices
|
|
1806
1863
|
);
|
|
@@ -1814,7 +1871,7 @@ var Setup = class {
|
|
|
1814
1871
|
throw this.fail(
|
|
1815
1872
|
{
|
|
1816
1873
|
zh: "--judge opencode \u9700\u8981 OpenCode \u7684\u5BC6\u94A5\uFF1A\u7528 --service opencode \u8BBE\u7F6E\u5B83\uFF0C\u6216\u5148\u8BBE\u7F6E OPENCODE_API_KEY",
|
|
1817
|
-
en: "--judge opencode needs an OpenCode key: set
|
|
1874
|
+
en: "--judge opencode needs an OpenCode key: set one up with --service opencode, or set OPENCODE_API_KEY first"
|
|
1818
1875
|
},
|
|
1819
1876
|
SETUP_EXIT.usage
|
|
1820
1877
|
);
|
|
@@ -1822,6 +1879,8 @@ var Setup = class {
|
|
|
1822
1879
|
return { kind: "opencode" };
|
|
1823
1880
|
case "free":
|
|
1824
1881
|
return { kind: "free" };
|
|
1882
|
+
case "off":
|
|
1883
|
+
return { kind: "none" };
|
|
1825
1884
|
case "jev": {
|
|
1826
1885
|
const key = this.jevFromStdin;
|
|
1827
1886
|
if (!key) {
|
|
@@ -1829,14 +1888,14 @@ var Setup = class {
|
|
|
1829
1888
|
throw this.fail(
|
|
1830
1889
|
{
|
|
1831
1890
|
zh: "--judge jev \u9700\u8981 Jev \u5BC6\u94A5\uFF1A\u5199\u5728\u6807\u51C6\u8F93\u5165\u7684\u7B2C\u4E8C\u884C\uFF0C\u6216\u5148\u8BBE\u7F6E TYPESAFE_API_KEY",
|
|
1832
|
-
en: "--judge jev needs a Jev key: the second line of stdin, or TYPESAFE_API_KEY
|
|
1891
|
+
en: "--judge jev needs a Jev key: put it on the second line of stdin, or set TYPESAFE_API_KEY first"
|
|
1833
1892
|
},
|
|
1834
1893
|
SETUP_EXIT.usage
|
|
1835
1894
|
);
|
|
1836
1895
|
}
|
|
1837
1896
|
if (key === this.modelKey) {
|
|
1838
1897
|
throw this.fail(
|
|
1839
|
-
{ zh: "Jev \u5BC6\u94A5\u548C\u6A21\u578B\u7684\u5BC6\u94A5\u662F\u540C\u4E00\u4E2A", en: "the Jev key is the same as the model
|
|
1898
|
+
{ zh: "Jev \u5BC6\u94A5\u548C\u6A21\u578B\u7684\u5BC6\u94A5\u662F\u540C\u4E00\u4E2A", en: "the Jev key is the same as the model key" },
|
|
1840
1899
|
SETUP_EXIT.usage
|
|
1841
1900
|
);
|
|
1842
1901
|
}
|
|
@@ -1844,7 +1903,7 @@ var Setup = class {
|
|
|
1844
1903
|
if (current && current !== key && !this.args.yes) {
|
|
1845
1904
|
throw this.fail({
|
|
1846
1905
|
zh: `${this.path(this.deps.paths.envFile)} \u91CC\u5DF2\u7ECF\u6709 TYPESAFE_API_KEY\u3002\u8981\u66FF\u6362\u5B83\uFF0C\u52A0\u4E0A --yes`,
|
|
1847
|
-
en: `${this.path(this.deps.paths.envFile)} has a TYPESAFE_API_KEY
|
|
1906
|
+
en: `${this.path(this.deps.paths.envFile)} already has a TYPESAFE_API_KEY. To replace it, add --yes`
|
|
1848
1907
|
});
|
|
1849
1908
|
}
|
|
1850
1909
|
return { kind: "jev", key };
|
|
@@ -1860,14 +1919,14 @@ var Setup = class {
|
|
|
1860
1919
|
const key = await this.secret(
|
|
1861
1920
|
this.t({
|
|
1862
1921
|
zh: "\u7C98\u8D34 Jev \u5BC6\u94A5\uFF08TYPESAFE_API_KEY\uFF0C\u4E0D\u4F1A\u663E\u793A\uFF09\uFF1A",
|
|
1863
|
-
en: "Paste the Jev key (TYPESAFE_API_KEY
|
|
1922
|
+
en: "Paste the Jev key (TYPESAFE_API_KEY; it won't be shown): "
|
|
1864
1923
|
})
|
|
1865
1924
|
);
|
|
1866
1925
|
if (key === this.modelKey) {
|
|
1867
1926
|
this.io.say(
|
|
1868
1927
|
this.t({
|
|
1869
1928
|
zh: `\u8FD9\u662F\u521A\u624D\u7ED9\u6A21\u578B\u7684\u5BC6\u94A5\u3002Jev \u7684\u5BC6\u94A5\u5728 TypeSafe \u7533\u8BF7\uFF1A${JEV_PAGE}`,
|
|
1870
|
-
en: `That
|
|
1929
|
+
en: `That's the key you gave for the model. Get a Jev key from TypeSafe: ${JEV_PAGE}`
|
|
1871
1930
|
})
|
|
1872
1931
|
);
|
|
1873
1932
|
continue;
|
|
@@ -1935,7 +1994,7 @@ var Setup = class {
|
|
|
1935
1994
|
saved.push(
|
|
1936
1995
|
this.savedLine(
|
|
1937
1996
|
modelsPath,
|
|
1938
|
-
custom || moved ? this.t({ zh: `${provider}\uFF1A${reach.baseUrl}`, en: `${provider} at ${reach.baseUrl}` }) : this.t({ zh: `\u7ED9 ${provider} \u52A0\u4E0A ${model}`, en:
|
|
1997
|
+
custom || moved ? this.t({ zh: `${provider}\uFF1A${reach.baseUrl}`, en: `${provider} at ${reach.baseUrl}` }) : this.t({ zh: `\u7ED9 ${provider} \u52A0\u4E0A ${model}`, en: `added ${model} to ${provider}` })
|
|
1939
1998
|
)
|
|
1940
1999
|
);
|
|
1941
2000
|
}
|
|
@@ -1955,35 +2014,36 @@ var Setup = class {
|
|
|
1955
2014
|
saved.push(
|
|
1956
2015
|
this.savedLine(
|
|
1957
2016
|
settingsPath,
|
|
1958
|
-
this.t({ zh: `\u9ED8\u8BA4\u6A21\u578B ${provider}/${model}`, en: `
|
|
2017
|
+
this.t({ zh: `\u9ED8\u8BA4\u6A21\u578B ${provider}/${model}`, en: `default model ${provider}/${model}` })
|
|
1959
2018
|
)
|
|
1960
2019
|
);
|
|
1961
2020
|
} catch {
|
|
1962
2021
|
notes.push(
|
|
1963
2022
|
this.t({
|
|
1964
2023
|
zh: `${this.path(settingsPath)} \u8BFB\u4E0D\u4E86\uFF0C\u9ED8\u8BA4\u6A21\u578B\u6CA1\u6709\u4FDD\u5B58\u3002\u5728 mu \u91CC\u7528 /model \u9009\u5B83\u3002`,
|
|
1965
|
-
en:
|
|
2024
|
+
en: `Couldn't read ${this.path(settingsPath)}, so the default model wasn't saved. Choose it inside mu with /model.`
|
|
1966
2025
|
})
|
|
1967
2026
|
);
|
|
1968
2027
|
}
|
|
1969
2028
|
}
|
|
1970
|
-
if (judge
|
|
2029
|
+
if (judge?.kind === "none") this.writeNoJudge(backups, saved, notes);
|
|
2030
|
+
else if (judge) this.writeJudge(judge, target, model, backups, saved, notes);
|
|
1971
2031
|
} catch (error) {
|
|
1972
2032
|
if (error instanceof Stop) throw error;
|
|
1973
2033
|
let reason = error instanceof Error ? error.message : String(error);
|
|
1974
2034
|
for (const secret of [target?.key, judge?.kind === "jev" ? judge.key : void 0]) {
|
|
1975
2035
|
if (secret) reason = reason.replaceAll(secret, "\u2026");
|
|
1976
2036
|
}
|
|
1977
|
-
this.io.warn(this.t({ zh: `mu setup\uFF1A\u4FDD\u5B58\u65F6\u51FA\u9519\uFF1A${reason}`, en: `mu setup:
|
|
2037
|
+
this.io.warn(this.t({ zh: `mu setup\uFF1A\u4FDD\u5B58\u65F6\u51FA\u9519\uFF1A${reason}`, en: `mu setup: couldn't save: ${reason}` }));
|
|
1978
2038
|
if (saved.length > 0) {
|
|
1979
|
-
this.io.warn(this.t({ zh: "\u51FA\u9519\u524D\u5DF2\u7ECF\u4FDD\u5B58\u7684\uFF1A", en: "Saved before
|
|
2039
|
+
this.io.warn(this.t({ zh: "\u51FA\u9519\u524D\u5DF2\u7ECF\u4FDD\u5B58\u7684\uFF1A", en: "Saved before the error:" }));
|
|
1980
2040
|
for (const entry of saved) this.io.warn(entry);
|
|
1981
2041
|
}
|
|
1982
2042
|
if (backups.path) {
|
|
1983
2043
|
this.io.warn(
|
|
1984
2044
|
this.t({
|
|
1985
2045
|
zh: `\u539F\u6765\u7684\u6587\u4EF6\u5728 ${this.path(backups.path)}`,
|
|
1986
|
-
en: `The
|
|
2046
|
+
en: `The previous versions are in ${this.path(backups.path)}`
|
|
1987
2047
|
})
|
|
1988
2048
|
);
|
|
1989
2049
|
}
|
|
@@ -1997,7 +2057,7 @@ var Setup = class {
|
|
|
1997
2057
|
this.io.say(
|
|
1998
2058
|
this.t({
|
|
1999
2059
|
zh: `\u6539\u52A8\u524D\u7684\u6587\u4EF6\u5DF2\u590D\u5236\u5230 ${this.path(backups.path)}`,
|
|
2000
|
-
en: `
|
|
2060
|
+
en: `Backed up the previous files to ${this.path(backups.path)}`
|
|
2001
2061
|
})
|
|
2002
2062
|
);
|
|
2003
2063
|
}
|
|
@@ -2008,6 +2068,25 @@ var Setup = class {
|
|
|
2008
2068
|
savedLine(path, what) {
|
|
2009
2069
|
return ` ${this.path(path).padEnd(30)} ${what}`;
|
|
2010
2070
|
}
|
|
2071
|
+
/** "Not now": no decision point asks a judge (the default mode "off"), so nothing goes to one. */
|
|
2072
|
+
writeNoJudge(backups, saved, notes) {
|
|
2073
|
+
const configPath = judgeConfigPath(this.deps.paths.agentDir);
|
|
2074
|
+
const config = readJsonFile(configPath);
|
|
2075
|
+
if (config.state === "unreadable") {
|
|
2076
|
+
notes.push(
|
|
2077
|
+
this.t({
|
|
2078
|
+
zh: `${this.path(configPath)} \u4E0D\u662F\u7EAF JSON\uFF0C\u6CA1\u6709\u6539\u5B83\u3002\u8BF7\u624B\u52A8\u52A0\u4E0A "modes": { "default": "off" }`,
|
|
2079
|
+
en: `${this.path(configPath)} isn't plain JSON, so it was left unchanged. Add "modes": { "default": "off" } by hand.`
|
|
2080
|
+
})
|
|
2081
|
+
);
|
|
2082
|
+
return;
|
|
2083
|
+
}
|
|
2084
|
+
const current = config.state === "ok" ? config.value : void 0;
|
|
2085
|
+
if (judgeOff(current)) return;
|
|
2086
|
+
backups.save(configPath);
|
|
2087
|
+
writeJsonFile(configPath, withJudge(current ?? {}, false));
|
|
2088
|
+
saved.push(this.savedLine(configPath, this.t({ zh: "\u5224\u5B9A\u5668\uFF1A\u5173\u95ED", en: "judge: off" })));
|
|
2089
|
+
}
|
|
2011
2090
|
writeJudge(judge, target, model, backups, saved, notes) {
|
|
2012
2091
|
const { env, paths } = this.deps;
|
|
2013
2092
|
const configPath = judgeConfigPath(paths.agentDir);
|
|
@@ -2020,18 +2099,21 @@ var Setup = class {
|
|
|
2020
2099
|
else if (judge.kind === "free") {
|
|
2021
2100
|
if (!tiersOf(current).some((tier) => tier === "jev" || tier === "jev-opencode-free")) tiers = ["jev"];
|
|
2022
2101
|
} else if (!tiersOf(current).some((tier) => JEV_TIERS.has(tier))) tiers = ["jev"];
|
|
2102
|
+
const turnOn = judgeOff(current);
|
|
2023
2103
|
if (tiers && config.state === "unreadable") {
|
|
2024
2104
|
notes.push(
|
|
2025
2105
|
this.t({
|
|
2026
2106
|
zh: `${this.path(configPath)} \u4E0D\u662F\u7EAF JSON\uFF0C\u6CA1\u6709\u6539\u5B83\u3002\u8BF7\u624B\u52A8\u52A0\u4E0A "tiers": ${JSON.stringify(tiers)}`,
|
|
2027
|
-
en: `${this.path(configPath)}
|
|
2107
|
+
en: `${this.path(configPath)} isn't plain JSON, so it was left unchanged. Add "tiers": ${JSON.stringify(tiers)} by hand.`
|
|
2028
2108
|
})
|
|
2029
2109
|
);
|
|
2030
|
-
} else if (tiers) {
|
|
2110
|
+
} else if (tiers || turnOn) {
|
|
2031
2111
|
backups.save(configPath);
|
|
2032
|
-
|
|
2112
|
+
const next = tiers ? withTiers(current ?? {}, tiers) : current ?? {};
|
|
2113
|
+
writeJsonFile(configPath, turnOn ? withJudge(next, true) : next);
|
|
2114
|
+
const named2 = tiers ?? tiersOf(current);
|
|
2033
2115
|
saved.push(
|
|
2034
|
-
this.savedLine(configPath, this.t({ zh: `\u5224\u5B9A\u5668 ${
|
|
2116
|
+
this.savedLine(configPath, this.t({ zh: `\u5224\u5B9A\u5668 ${named2.join(", ")}`, en: `judge: ${named2.join(", ")}` }))
|
|
2035
2117
|
);
|
|
2036
2118
|
}
|
|
2037
2119
|
if (judge.kind === "jev") {
|
|
@@ -2047,7 +2129,7 @@ var Setup = class {
|
|
|
2047
2129
|
notes.push(
|
|
2048
2130
|
this.t({
|
|
2049
2131
|
zh: `\u6CE8\u610F\uFF1A\u73AF\u5883\u53D8\u91CF\u91CC\u4E5F\u6709 TYPESAFE_API_KEY\uFF0C\u5B83\u6BD4 ${this.path(paths.envFile)} \u4F18\u5148\u3002\u5230\u8BBE\u7F6E\u5B83\u7684\u5730\u65B9\uFF08\u4F8B\u5982 ~/.zshrc\uFF09\u6539\u6389\u6216\u5220\u6389\u3002`,
|
|
2050
|
-
en: `Note: TYPESAFE_API_KEY is also set in your environment
|
|
2132
|
+
en: `Note: TYPESAFE_API_KEY is also set in your environment and takes precedence over ${this.path(paths.envFile)}. Change or remove it where it's set (~/.zshrc, for example).`
|
|
2051
2133
|
})
|
|
2052
2134
|
);
|
|
2053
2135
|
}
|
|
@@ -2057,7 +2139,7 @@ var Setup = class {
|
|
|
2057
2139
|
notes.push(
|
|
2058
2140
|
this.t({
|
|
2059
2141
|
zh: `\u6CE8\u610F\uFF1A\u73AF\u5883\u53D8\u91CF MU_JUDGE=${override} \u6BD4 mu.json \u4F18\u5148\uFF0C\u7531\u5B83\u51B3\u5B9A\u5224\u5B9A\u5668\u3002`,
|
|
2060
|
-
en: `Note: MU_JUDGE=${override} is set in your environment
|
|
2142
|
+
en: `Note: MU_JUDGE=${override} is set in your environment and takes precedence over mu.json for the judge.`
|
|
2061
2143
|
})
|
|
2062
2144
|
);
|
|
2063
2145
|
}
|
|
@@ -2065,26 +2147,31 @@ var Setup = class {
|
|
|
2065
2147
|
summary(target, model, judge) {
|
|
2066
2148
|
const done = target && model ? this.t({
|
|
2067
2149
|
zh: `\u5B8C\u6210\u3002mu \u4F1A\u7528 ${this.name(target.service)} \xB7 ${model} \u5F00\u59CB\u5DE5\u4F5C\u3002`,
|
|
2068
|
-
en: `Done. mu
|
|
2150
|
+
en: `Done. mu will start on ${this.name(target.service)} \xB7 ${model}.`
|
|
2069
2151
|
}) : this.t({ zh: "\u5B8C\u6210\u3002", en: "Done." });
|
|
2070
2152
|
const judged = judge === void 0 ? "" : judge.kind === "model" ? this.t({ zh: "\u5224\u5B9A\u5668\uFF1A\u540C\u4E00\u4E2A\u6A21\u578B\u3002", en: " Judge: the same model." }) : judge.kind === "none" ? this.t({ zh: "\u5224\u5B9A\u5668\uFF1A\u6682\u65F6\u6CA1\u6709\u3002", en: " Judge: none for now." }) : judge.kind === "opencode" ? this.t({ zh: "\u5224\u5B9A\u5668\uFF1AOpenCode Zen \u4E0A\u7684 Jev\u3002", en: " Judge: Jev on OpenCode Zen." }) : judge.kind === "free" ? this.t({
|
|
2071
2153
|
zh: "\u5224\u5B9A\u5668\uFF1AJev\uFF0C\u52A0\u5BC6\u94A5\u4E4B\u524D\u7528 OpenCode Zen \u4E0A\u9650\u65F6\u514D\u8D39\u7684\u7248\u672C\u3002",
|
|
2072
|
-
en: " Judge: Jev, free on OpenCode Zen
|
|
2154
|
+
en: " Judge: Jev, using the free version on OpenCode Zen until you add a key."
|
|
2073
2155
|
}) : this.t({ zh: "\u5224\u5B9A\u5668\uFF1AJev\u3002", en: " Judge: Jev." });
|
|
2074
2156
|
this.io.say("");
|
|
2075
2157
|
this.io.say(`${done}${judged}`);
|
|
2076
2158
|
this.io.say(
|
|
2077
2159
|
target ? this.t({
|
|
2078
2160
|
zh: "\u5728 mu \u91CC\u7528 /model \u6362\u6A21\u578B\uFF1B\u968F\u65F6\u53EF\u4EE5\u518D\u8FD0\u884C mu setup\u3002",
|
|
2079
|
-
en: "Switch models inside mu with /model
|
|
2080
|
-
}) : this.t({ zh: "\
|
|
2161
|
+
en: "Switch models inside mu with /model, and run mu setup again any time."
|
|
2162
|
+
}) : this.t({ zh: "\u63A5\u4E0B\u6765\u5728 mu \u91CC\u7528 /login \u767B\u5F55\u3002", en: "Next, sign in with /login in mu." })
|
|
2081
2163
|
);
|
|
2082
2164
|
}
|
|
2083
|
-
/**
|
|
2084
|
-
|
|
2085
|
-
|
|
2165
|
+
/**
|
|
2166
|
+
* On its own, a finished setup offers a session; on a first start the launcher goes on into one anyway. After a
|
|
2167
|
+
* subscription was chosen (`signIn`), that session opens on /login: SETUP_EXIT.signIn.
|
|
2168
|
+
*/
|
|
2169
|
+
async offerSession(signIn = false) {
|
|
2170
|
+
if (this.scripted) return SETUP_EXIT.done;
|
|
2171
|
+
if (this.args.firstRun) return signIn ? SETUP_EXIT.signIn : SETUP_EXIT.done;
|
|
2086
2172
|
const start = await this.confirm(this.t({ zh: "\u73B0\u5728\u542F\u52A8 mu \u5417\uFF1F[Y/n] ", en: "Start mu now? [Y/n] " }), true);
|
|
2087
|
-
|
|
2173
|
+
if (!start) return SETUP_EXIT.done;
|
|
2174
|
+
return signIn ? SETUP_EXIT.signIn : SETUP_EXIT.start;
|
|
2088
2175
|
}
|
|
2089
2176
|
};
|
|
2090
2177
|
function existingProviders(models) {
|