yymaxapi 1.0.119 → 1.0.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/yymaxapi.js +121 -9
- package/package.json +1 -1
package/bin/yymaxapi.js
CHANGED
|
@@ -337,6 +337,12 @@ function resolveHermesModelType(modelId, preferredType = '') {
|
|
|
337
337
|
return requestedType || 'claude';
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
+
function getKnownModelName(modelId) {
|
|
341
|
+
const normalized = String(modelId || '').trim();
|
|
342
|
+
const model = [...CLAUDE_MODELS, ...CODEX_MODELS].find(item => item.id === normalized);
|
|
343
|
+
return model?.name || normalized || '未选择模型';
|
|
344
|
+
}
|
|
345
|
+
|
|
340
346
|
async function promptHermesModelSelection(args = {}, message = '选择 Hermes 默认模型:') {
|
|
341
347
|
const requestedModel = (args['model-id'] || args.model || '').toString().trim();
|
|
342
348
|
const requestedType = normalizeHermesModelType(
|
|
@@ -3846,7 +3852,7 @@ function scoreHermesWslCandidate(candidate) {
|
|
|
3846
3852
|
}
|
|
3847
3853
|
|
|
3848
3854
|
function getHermesWslMirrorInfo(options = {}) {
|
|
3849
|
-
if (process.platform !== 'win32'
|
|
3855
|
+
if (process.platform !== 'win32') {
|
|
3850
3856
|
return {
|
|
3851
3857
|
dataDir: null,
|
|
3852
3858
|
sourceConfigPath: null,
|
|
@@ -3892,7 +3898,8 @@ function getHermesWslMirrorInfo(options = {}) {
|
|
|
3892
3898
|
sourceConfigPath,
|
|
3893
3899
|
configPath: candidate.configPath,
|
|
3894
3900
|
envPath: candidate.envPath,
|
|
3895
|
-
target: candidate.target
|
|
3901
|
+
target: candidate.target,
|
|
3902
|
+
commandPath: selected?.commandPath || probeHermesWslCommand(candidate.target)
|
|
3896
3903
|
};
|
|
3897
3904
|
}
|
|
3898
3905
|
|
|
@@ -4115,6 +4122,36 @@ function readHermesCliConfig() {
|
|
|
4115
4122
|
};
|
|
4116
4123
|
}
|
|
4117
4124
|
|
|
4125
|
+
function buildHermesCliConfigFromRaw(configRaw, envRaw, configPath = '', envPath = '') {
|
|
4126
|
+
const parsed = parseSimpleYamlConfig(configRaw);
|
|
4127
|
+
const envEntries = parseEnvFile(envRaw);
|
|
4128
|
+
const modelConfig = parsed?.model && typeof parsed.model === 'object' ? parsed.model : {};
|
|
4129
|
+
const modelId = String(modelConfig.default || '').trim() || getDefaultClaudeModel().id;
|
|
4130
|
+
const provider = String(modelConfig.provider || '').trim().toLowerCase();
|
|
4131
|
+
const type = resolveHermesModelType(modelId, provider);
|
|
4132
|
+
const apiKey = type === 'codex'
|
|
4133
|
+
? (envEntries.OPENAI_API_KEY || '')
|
|
4134
|
+
: (envEntries.ANTHROPIC_API_KEY || envEntries.ANTHROPIC_TOKEN || '');
|
|
4135
|
+
|
|
4136
|
+
return {
|
|
4137
|
+
configPath,
|
|
4138
|
+
envPath,
|
|
4139
|
+
configured: !!configRaw || !!envRaw,
|
|
4140
|
+
modelId,
|
|
4141
|
+
provider,
|
|
4142
|
+
type,
|
|
4143
|
+
baseUrl: String(modelConfig.base_url || '').trim(),
|
|
4144
|
+
apiKey
|
|
4145
|
+
};
|
|
4146
|
+
}
|
|
4147
|
+
|
|
4148
|
+
function readHermesWslCliConfig(wslMirror = getHermesWslMirrorInfo()) {
|
|
4149
|
+
const configPath = wslMirror.sourceConfigPath || wslMirror.configPath;
|
|
4150
|
+
const configRaw = readWslTextFile(configPath, wslMirror.target);
|
|
4151
|
+
const envRaw = readWslTextFile(wslMirror.envPath, wslMirror.target);
|
|
4152
|
+
return buildHermesCliConfigFromRaw(configRaw, envRaw, configPath, wslMirror.envPath);
|
|
4153
|
+
}
|
|
4154
|
+
|
|
4118
4155
|
function getOpencodeConfigPath() {
|
|
4119
4156
|
const home = os.homedir();
|
|
4120
4157
|
return process.platform === 'win32'
|
|
@@ -4374,6 +4411,9 @@ function testCodexCliConnection() {
|
|
|
4374
4411
|
|
|
4375
4412
|
function testHermesCliConnection() {
|
|
4376
4413
|
const cliBinary = resolveCommandBinary('hermes');
|
|
4414
|
+
if (!cliBinary && process.platform === 'win32') {
|
|
4415
|
+
return testHermesWslCliConnection();
|
|
4416
|
+
}
|
|
4377
4417
|
if (!cliBinary) return { name: 'Hermes CLI', status: 'skipped', detail: '未安装 hermes 命令' };
|
|
4378
4418
|
|
|
4379
4419
|
const config = readHermesCliConfig();
|
|
@@ -4419,6 +4459,40 @@ function testHermesCliConnection() {
|
|
|
4419
4459
|
};
|
|
4420
4460
|
}
|
|
4421
4461
|
|
|
4462
|
+
function testHermesWslCliConnection() {
|
|
4463
|
+
const wslMirror = getHermesWslMirrorInfo();
|
|
4464
|
+
const commandPath = wslMirror.commandPath || probeHermesWslCommand(wslMirror.target || {});
|
|
4465
|
+
if (!commandPath) return { name: 'Hermes CLI (WSL)', status: 'skipped', detail: '未检测到 WSL 内 hermes 命令' };
|
|
4466
|
+
|
|
4467
|
+
const config = readHermesWslCliConfig(wslMirror);
|
|
4468
|
+
if (!config.configured) return { name: 'Hermes CLI (WSL)', status: 'skipped', detail: '未检测到 WSL ~/.hermes/config.yaml 或 ~/.hermes/.env' };
|
|
4469
|
+
if (!config.apiKey) return { name: 'Hermes CLI (WSL)', status: 'failed', detail: 'Hermes 配置缺少 API Key' };
|
|
4470
|
+
|
|
4471
|
+
const providerArg = config.provider === 'anthropic' ? ' --provider anthropic' : '';
|
|
4472
|
+
const command = [
|
|
4473
|
+
`export HERMES_HOME=${shellQuote(wslMirror.dataDir)}`,
|
|
4474
|
+
'export NODE_TLS_REJECT_UNAUTHORIZED=0',
|
|
4475
|
+
'export NODE_NO_WARNINGS=1',
|
|
4476
|
+
'set -a',
|
|
4477
|
+
`[ -f "$HERMES_HOME/.env" ] && . "$HERMES_HOME/.env"`,
|
|
4478
|
+
'set +a',
|
|
4479
|
+
`${shellQuote(commandPath)} chat -Q -q ${shellQuote('请只回复 OK')}${providerArg}`
|
|
4480
|
+
].join('; ');
|
|
4481
|
+
const result = runWslCommand(command, { timeout: 120000, maxBuffer: 1024 * 1024 }, { ...(wslMirror.target || {}), login: true });
|
|
4482
|
+
const combined = cleanCliTestOutput(`${result.output || ''}\n${result.stdout || ''}\n${result.stderr || ''}`);
|
|
4483
|
+
const reply = extractHermesCliReply(combined);
|
|
4484
|
+
|
|
4485
|
+
if (result.ok && /^OK$/i.test(reply) && !looksLikeCliTestError(combined)) {
|
|
4486
|
+
return { name: 'Hermes CLI (WSL)', status: 'success', detail: 'OK' };
|
|
4487
|
+
}
|
|
4488
|
+
|
|
4489
|
+
return {
|
|
4490
|
+
name: 'Hermes CLI (WSL)',
|
|
4491
|
+
status: 'failed',
|
|
4492
|
+
detail: reply || summarizeCliTestOutput(combined) || result.error || '命令执行失败'
|
|
4493
|
+
};
|
|
4494
|
+
}
|
|
4495
|
+
|
|
4422
4496
|
async function testAdditionalCliConnections(args = {}, options = {}) {
|
|
4423
4497
|
if (args['no-app-test'] || args.noAppTest) return;
|
|
4424
4498
|
|
|
@@ -5889,10 +5963,11 @@ async function activateHermes(paths, args = {}) {
|
|
|
5889
5963
|
async function main() {
|
|
5890
5964
|
console.clear();
|
|
5891
5965
|
|
|
5892
|
-
console.log(chalk.cyan.bold('\n🔧
|
|
5966
|
+
console.log(chalk.cyan.bold('\n🔧 yymaxapi 配置工具\n'));
|
|
5893
5967
|
|
|
5894
5968
|
const paths = getConfigPath();
|
|
5895
|
-
console.log(chalk.gray(
|
|
5969
|
+
console.log(chalk.gray(`OpenClaw 配置: ${paths.openclawConfig}`));
|
|
5970
|
+
console.log(chalk.gray(`Hermes 配置: ${getHermesConfigPath()}\n`));
|
|
5896
5971
|
|
|
5897
5972
|
// 首次运行备份
|
|
5898
5973
|
if (backupOriginalConfig(paths.openclawConfig, paths.configDir)) {
|
|
@@ -5931,10 +6006,15 @@ async function main() {
|
|
|
5931
6006
|
|
|
5932
6007
|
while (true) {
|
|
5933
6008
|
// 显示当前状态
|
|
5934
|
-
const
|
|
5935
|
-
|
|
6009
|
+
const statusLines = [
|
|
6010
|
+
getConfigStatusLine(paths),
|
|
6011
|
+
getHermesStatusLine()
|
|
6012
|
+
].filter(Boolean);
|
|
6013
|
+
if (statusLines.length > 0) {
|
|
5936
6014
|
console.log(chalk.gray('─'.repeat(40)));
|
|
5937
|
-
|
|
6015
|
+
for (const statusLine of statusLines) {
|
|
6016
|
+
console.log(statusLine);
|
|
6017
|
+
}
|
|
5938
6018
|
console.log(chalk.gray('─'.repeat(40)) + '\n');
|
|
5939
6019
|
}
|
|
5940
6020
|
|
|
@@ -6057,7 +6137,7 @@ function getConfigStatusLine(paths) {
|
|
|
6057
6137
|
}
|
|
6058
6138
|
|
|
6059
6139
|
if (parts.length === 0 && otherCount === 0) {
|
|
6060
|
-
return chalk.gray('
|
|
6140
|
+
return chalk.gray('OpenClaw: 未配置任何模型');
|
|
6061
6141
|
}
|
|
6062
6142
|
|
|
6063
6143
|
const primaryModelId = primary.split('/')[1] || '';
|
|
@@ -6065,7 +6145,39 @@ function getConfigStatusLine(paths) {
|
|
|
6065
6145
|
|
|
6066
6146
|
const gwEnv = detectGatewayEnv();
|
|
6067
6147
|
const envTag = gwEnv === 'wsl' ? chalk.cyan(' [WSL]') : '';
|
|
6068
|
-
return chalk.gray('
|
|
6148
|
+
return chalk.gray('OpenClaw: ') + parts.join(' ') + chalk.gray(' (✓ 主模型 ○ 已配置)') + modelTag + envTag;
|
|
6149
|
+
} catch {
|
|
6150
|
+
return null;
|
|
6151
|
+
}
|
|
6152
|
+
}
|
|
6153
|
+
|
|
6154
|
+
function getHermesStatusLine() {
|
|
6155
|
+
try {
|
|
6156
|
+
let config = readHermesCliConfig();
|
|
6157
|
+
let wslMirror = null;
|
|
6158
|
+
|
|
6159
|
+
if (process.platform === 'win32') {
|
|
6160
|
+
wslMirror = getHermesWslMirrorInfo();
|
|
6161
|
+
if (!config.configured && (wslMirror.configPath || wslMirror.envPath)) {
|
|
6162
|
+
config = readHermesWslCliConfig(wslMirror);
|
|
6163
|
+
}
|
|
6164
|
+
}
|
|
6165
|
+
|
|
6166
|
+
if (!config.configured) return null;
|
|
6167
|
+
|
|
6168
|
+
const modelName = getKnownModelName(config.modelId);
|
|
6169
|
+
const readyMark = config.apiKey ? chalk.green('✓') : chalk.yellow('○');
|
|
6170
|
+
const modelTag = config.modelId ? chalk.cyan(` [模型: ${config.modelId}]`) : '';
|
|
6171
|
+
const protocolTag = config.type === 'codex' ? chalk.cyan(' [GPT]') : chalk.cyan(' [Claude]');
|
|
6172
|
+
const hasWslTarget = !!(wslMirror?.sourceConfigPath || wslMirror?.commandPath);
|
|
6173
|
+
let envTag = '';
|
|
6174
|
+
if (hasWslTarget && wslMirror?.target?.user) {
|
|
6175
|
+
envTag = chalk.cyan(` [WSL ${wslMirror.target.user}]`);
|
|
6176
|
+
} else if (hasWslTarget) {
|
|
6177
|
+
envTag = chalk.cyan(' [WSL]');
|
|
6178
|
+
}
|
|
6179
|
+
|
|
6180
|
+
return chalk.gray('Hermes-Agent: ') + chalk.green(`${modelName} ${readyMark}`) + protocolTag + modelTag + envTag;
|
|
6069
6181
|
} catch {
|
|
6070
6182
|
return null;
|
|
6071
6183
|
}
|