yymaxapi 1.0.85 → 1.0.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/yymaxapi.js +108 -87
  2. package/package.json +1 -1
package/bin/yymaxapi.js CHANGED
@@ -2025,6 +2025,53 @@ function getAgentModelState(agent) {
2025
2025
  return { primary, fallbacks };
2026
2026
  }
2027
2027
 
2028
+ function findAgentById(config, agentId) {
2029
+ if (!Array.isArray(config?.agents?.list) || !agentId) return null;
2030
+ return config.agents.list.find(agent => agent && typeof agent === 'object' && agent.id === agentId) || null;
2031
+ }
2032
+
2033
+ function resolveOpenClawTestTarget(config, args = {}) {
2034
+ const requestedAgentId = String(args.agent || args['agent-id'] || '').trim();
2035
+ const requestedAgent = requestedAgentId ? findAgentById(config, requestedAgentId) : null;
2036
+ const defaultPrimary = String(config?.agents?.defaults?.model?.primary || '').trim();
2037
+ const defaultFallbacks = Array.isArray(config?.agents?.defaults?.model?.fallbacks)
2038
+ ? [...config.agents.defaults.model.fallbacks]
2039
+ : [];
2040
+
2041
+ let primary = defaultPrimary;
2042
+ let fallbacks = defaultFallbacks;
2043
+ let agentId = null;
2044
+ let agentName = '';
2045
+
2046
+ if (requestedAgent) {
2047
+ const agentState = getAgentModelState(requestedAgent);
2048
+ if (agentState.primary) {
2049
+ primary = agentState.primary;
2050
+ fallbacks = agentState.fallbacks;
2051
+ agentId = requestedAgent.id;
2052
+ agentName = String(requestedAgent.name || '').trim();
2053
+ }
2054
+ }
2055
+
2056
+ const providerName = primary.includes('/') ? primary.split('/')[0] : '';
2057
+ const provider = providerName ? (config.models?.providers?.[providerName] || null) : null;
2058
+ const apiType = provider?.api || '';
2059
+ const typeLabel = apiType.startsWith('anthropic')
2060
+ ? 'Claude'
2061
+ : (apiType.startsWith('openai') ? 'Codex' : '模型');
2062
+
2063
+ return {
2064
+ agentId,
2065
+ agentName,
2066
+ primary,
2067
+ fallbacks,
2068
+ providerName,
2069
+ provider,
2070
+ typeLabel,
2071
+ defaultPrimary
2072
+ };
2073
+ }
2074
+
2028
2075
  function hasManagedYunyiFootprint(config) {
2029
2076
  const providers = config?.models?.providers || {};
2030
2077
  if (Object.entries(providers).some(([name, provider]) => isYunyiProviderEntry(name, provider, 'claude') || isYunyiProviderEntry(name, provider, 'codex'))) {
@@ -2103,6 +2150,18 @@ function buildManagedYunyiProviderConfig(type, endpointUrl, apiKey, existingProv
2103
2150
  return next;
2104
2151
  }
2105
2152
 
2153
+ function buildGatewayAgentSubcommand({ sessionId, agentId, message = '请回复你的模型名称' }) {
2154
+ const agentArg = agentId ? ` --agent ${shellQuote(agentId)}` : '';
2155
+ return `agent${agentArg} --session-id ${shellQuote(sessionId)} --message ${shellQuote(message)} --json --timeout 120`;
2156
+ }
2157
+
2158
+ function buildGatewayAgentCliCommand({ cliBinary, nodeInfo, useNode, sessionId, agentId, message = '请回复你的模型名称' }) {
2159
+ const subcommand = buildGatewayAgentSubcommand({ sessionId, agentId, message });
2160
+ return useNode
2161
+ ? `${shellQuote(nodeInfo.path)} ${shellQuote(cliBinary)} ${subcommand}`
2162
+ : `${shellQuote(cliBinary)} ${subcommand}`;
2163
+ }
2164
+
2106
2165
  function ensureAgentList(config) {
2107
2166
  if (!config.agents) config.agents = {};
2108
2167
  if (!Array.isArray(config.agents.list)) config.agents.list = [];
@@ -2309,13 +2368,10 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
2309
2368
 
2310
2369
  function printYunyiOpenClawSwitchHint(result = {}) {
2311
2370
  if (!result?.applied) return;
2312
- if (result.preservedMain && result.claudeAgentId === YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID) {
2313
- console.log(chalk.gray(' 已保留你现有的 main;Yunyi Claude 入口为 yunyi-claude'));
2314
- } else {
2315
- console.log(chalk.gray(' 默认主入口是 yunyi-claude'));
2316
- }
2317
- console.log(chalk.gray(' GPT 入口是 yunyi-gpt'));
2318
- console.log(chalk.yellow(' 提示: 当前 OpenClaw Web 顶部模型下拉跨 provider 切换可能报错,建议通过左侧会话/agent 切换 Claude 和 GPT'));
2371
+ const summary = result.preservedMain && result.claudeAgentId === YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID
2372
+ ? 'OpenClaw: main 已保留, Claude=yunyi-claude, GPT=yunyi-gpt'
2373
+ : 'OpenClaw: main=yunyi-claude, GPT=yunyi-gpt';
2374
+ console.log(chalk.cyan(` ${summary}`));
2319
2375
  }
2320
2376
 
2321
2377
  function pruneProvidersByPrefix(config, prefixBase, keepProviders = []) {
@@ -3889,17 +3945,13 @@ async function presetClaude(paths, args = {}) {
3889
3945
  updateAuthProfilesWithSync(paths, YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER, apiKey);
3890
3946
  updateAuthProfilesWithSync(paths, YYMAXAPI_OPENCLAW_GPT_PROVIDER, apiKey);
3891
3947
  }
3892
- const extSynced = syncExternalTools('claude', baseUrl, apiKey, { claudeModelId: modelId, opencodeDefaultModelKey: `yunyi-claude/${modelId}` });
3948
+ syncExternalTools('claude', baseUrl, apiKey, { claudeModelId: modelId, opencodeDefaultModelKey: `yunyi-claude/${modelId}` });
3893
3949
  writeSpinner.succeed('配置写入完成');
3894
3950
 
3895
3951
  console.log(chalk.green('\n✅ Claude 节点配置完成!'));
3896
- const tag = setPrimary ? ' (主)' : '';
3897
- console.log(chalk.cyan(` ${providerName}${tag}: ${buildFullUrl(selectedEndpoint.url, 'claude')}`));
3898
- console.log(chalk.gray(` 模型: ${modelName}`));
3899
- console.log(chalk.gray(' API Key: 已设置'));
3900
- if (extSynced.length > 0) console.log(chalk.gray(` 同步: ${extSynced.join(', ')}`));
3952
+ console.log(chalk.cyan(` Claude: ${modelName}`));
3901
3953
  if (repairResult.renamedProviders.length > 0) {
3902
- console.log(chalk.gray(` 已保留并修复冲突 provider: ${repairResult.renamedProviders.map(item => `${item.from}→${item.to}`).join(', ')}`));
3954
+ console.log(chalk.cyan(` 已修复 provider 冲突: ${repairResult.renamedProviders.map(item => `${item.from}→${item.to}`).join(', ')}`));
3903
3955
  }
3904
3956
  printYunyiOpenClawSwitchHint(yunyiLayoutResult);
3905
3957
 
@@ -4076,17 +4128,13 @@ async function presetCodex(paths, args = {}) {
4076
4128
  updateAuthProfilesWithSync(paths, YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER, apiKey);
4077
4129
  updateAuthProfilesWithSync(paths, YYMAXAPI_OPENCLAW_GPT_PROVIDER, apiKey);
4078
4130
  }
4079
- const extSynced2 = syncExternalTools('codex', baseUrl, apiKey, { modelId });
4131
+ syncExternalTools('codex', baseUrl, apiKey, { modelId });
4080
4132
  writeSpinner2.succeed('配置写入完成');
4081
4133
 
4082
4134
  console.log(chalk.green('\n✅ Codex 节点配置完成!'));
4083
- const tag = setPrimary ? ' (主)' : '';
4084
- console.log(chalk.cyan(` ${providerName}${tag}: ${baseUrl}`));
4085
- console.log(chalk.gray(` 模型: ${modelName}`));
4086
- console.log(chalk.gray(' API Key: 已设置'));
4087
- if (extSynced2.length > 0) console.log(chalk.gray(` 同步: ${extSynced2.join(', ')}`));
4135
+ console.log(chalk.cyan(` Codex: ${modelName}`));
4088
4136
  if (repairResult.renamedProviders.length > 0) {
4089
- console.log(chalk.gray(` 已保留并修复冲突 provider: ${repairResult.renamedProviders.map(item => `${item.from}→${item.to}`).join(', ')}`));
4137
+ console.log(chalk.cyan(` 已修复 provider 冲突: ${repairResult.renamedProviders.map(item => `${item.from}→${item.to}`).join(', ')}`));
4090
4138
  }
4091
4139
  printYunyiOpenClawSwitchHint(yunyiLayoutResult);
4092
4140
 
@@ -4271,22 +4319,15 @@ async function autoActivate(paths, args = {}) {
4271
4319
  writeConfigWithSync(paths, config);
4272
4320
  updateAuthProfilesWithSync(paths, claudeProviderName, apiKey);
4273
4321
  updateAuthProfilesWithSync(paths, codexProviderName, apiKey);
4274
- const extSynced = [];
4275
4322
  const opencodeDefaultModelKey = isClaudePrimary ? `yunyi-claude/${claudeModelId}` : `yunyi-codex/${codexModelId}`;
4276
- try { extSynced.push(...syncExternalTools('claude', claudeBaseUrl, apiKey, { codexBaseUrl, claudeModelId, opencodeDefaultModelKey })); } catch { /* ignore */ }
4277
- try { extSynced.push(...syncExternalTools('codex', codexBaseUrl, apiKey, { modelId: codexModelId })); } catch { /* ignore */ }
4323
+ try { syncExternalTools('claude', claudeBaseUrl, apiKey, { codexBaseUrl, claudeModelId, opencodeDefaultModelKey }); } catch { /* ignore */ }
4324
+ try { syncExternalTools('codex', codexBaseUrl, apiKey, { modelId: codexModelId }); } catch { /* ignore */ }
4278
4325
  writeSpinner.succeed('配置写入完成');
4279
4326
 
4280
4327
  // ---- 输出结果 ----
4281
- const primaryLabel = isClaudePrimary ? 'Claude' : 'GPT';
4282
4328
  const selectedModel = isClaudePrimary ? claudeModel : codexModel;
4283
4329
  console.log(chalk.green('\n✅ 配置完成!'));
4284
- console.log(chalk.cyan(` 外部工具默认: ${selectedModel.name} (${primaryLabel})`));
4285
- console.log(chalk.gray(` 节点: ${selectedEndpoint.url} (${selectedEndpoint.name})`));
4286
- console.log(chalk.gray(' API Key: 已设置'));
4287
- if (extSynced.length > 0) console.log(chalk.gray(` 同步: ${extSynced.join(', ')}`));
4288
- console.log(chalk.gray(' 若遇 certificate 报错,请新开终端或执行 source ~/.zshrc 后重试(已放宽 TLS 校验)'));
4289
- console.log(chalk.gray(` 使用 OpenCode 时可在界面中切换 ${getOpencodeSwitchHint()};Codex 仅支持 GPT`));
4330
+ console.log(chalk.cyan(` 外部工具默认: ${selectedModel.name}`));
4290
4331
  printYunyiOpenClawSwitchHint(yunyiLayoutResult);
4291
4332
 
4292
4333
  const gwPort = config.gateway?.port || 18789;
@@ -4308,7 +4349,10 @@ async function autoActivate(paths, args = {}) {
4308
4349
  }]);
4309
4350
 
4310
4351
  if (nextAction === 'test') {
4311
- await testConnection(paths, args);
4352
+ const selectedOpenClawAgentId = isClaudePrimary
4353
+ ? (yunyiLayoutResult.claudeAgentId || YYMAXAPI_OPENCLAW_MAIN_AGENT_ID)
4354
+ : YYMAXAPI_OPENCLAW_GPT_AGENT_ID;
4355
+ await testConnection(paths, { ...args, agent: selectedOpenClawAgentId });
4312
4356
  } else {
4313
4357
  console.log(chalk.cyan('👋 再见!\n'));
4314
4358
  process.exit(0);
@@ -4728,12 +4772,8 @@ async function yycodeQuickSetup(paths) {
4728
4772
 
4729
4773
  // ---- 结果 ----
4730
4774
  console.log(chalk.green('\n✅ 配置完成!'));
4731
- console.log(chalk.cyan(` Claude Code: ${claudeBaseUrl}`));
4732
- console.log(chalk.gray(` 模型: ${claudeModel.name}`));
4733
- console.log(chalk.cyan(` Codex CLI: ${codexBaseUrl}`));
4734
- console.log(chalk.gray(` 模型: ${codexModel.name}`));
4735
- console.log(chalk.gray(' API Key: 已设置'));
4736
- console.log(chalk.gray(' 同步: Claude Code settings, Opencode config, Codex CLI config'));
4775
+ console.log(chalk.cyan(` Claude Code: ${claudeModel.name}`));
4776
+ console.log(chalk.cyan(` Codex CLI: ${codexModel.name}`));
4737
4777
  printYunyiOpenClawSwitchHint(yunyiLayoutResult);
4738
4778
  console.log('');
4739
4779
  }
@@ -4866,7 +4906,9 @@ async function main() {
4866
4906
  // 获取当前配置状态摘要
4867
4907
  function getConfigStatusLine(paths) {
4868
4908
  try {
4869
- const config = readConfig(paths.openclawConfig);
4909
+ const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
4910
+ applyConfigRepairsWithSync(config, paths);
4911
+ applyManagedYunyiOpenClawLayout(config);
4870
4912
  if (!config?.models?.providers) return null;
4871
4913
 
4872
4914
  const providers = Object.keys(config.models.providers);
@@ -5008,9 +5050,7 @@ async function selectNode(paths, type) {
5008
5050
  if (managedGptKey) updateAuthProfilesWithSync(paths, YYMAXAPI_OPENCLAW_GPT_PROVIDER, managedGptKey);
5009
5051
 
5010
5052
  console.log(chalk.green(`\n✅ ${typeLabel} 节点配置完成!`));
5011
- console.log(chalk.cyan(` 节点: ${selectedEndpoint.name} (${selectedEndpoint.url})`));
5012
- console.log(chalk.gray(` 模型: ${modelConfig.name} (主模型)`));
5013
- console.log(chalk.gray(` API Key: ${oldApiKey ? '已设置' : '未设置'}`));
5053
+ console.log(chalk.cyan(` ${typeLabel}: ${modelConfig.name}`));
5014
5054
  printYunyiOpenClawSwitchHint(yunyiLayoutResult);
5015
5055
  }
5016
5056
 
@@ -5065,9 +5105,7 @@ async function activate(paths, type) {
5065
5105
  writeAuthStore(paths.authProfiles, authStore);
5066
5106
 
5067
5107
  console.log(chalk.green(`\n✅ 已激活 ${typeLabel}`));
5068
- console.log(chalk.cyan(` 节点: ${provider.baseUrl}`));
5069
- console.log(chalk.gray(` 模型: ${modelConfig.name}`));
5070
- console.log(chalk.gray(` API Key: 已设置`));
5108
+ console.log(chalk.cyan(` ${typeLabel}: ${modelConfig.name}`));
5071
5109
  printYunyiOpenClawSwitchHint(yunyiLayoutResult);
5072
5110
  }
5073
5111
 
@@ -5343,30 +5381,28 @@ async function testConnection(paths, args = {}) {
5343
5381
 
5344
5382
  const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
5345
5383
  applyConfigRepairsWithSync(config, paths);
5384
+ applyManagedYunyiOpenClawLayout(config);
5346
5385
 
5347
5386
  if (!config || !config.models) {
5348
5387
  console.log(chalk.yellow('配置文件不存在,请先选择节点'));
5349
5388
  return;
5350
5389
  }
5351
5390
 
5352
- // 检查当前激活的是哪个
5353
- let primary = config.agents?.defaults?.model?.primary || '';
5391
+ const testTarget = resolveOpenClawTestTarget(config, args);
5392
+ const primary = testTarget.primary;
5354
5393
  if (!primary.includes('/')) {
5355
5394
  console.log(chalk.yellow('⚠️ 主模型未设置,请先通过「切换 OpenClaw 模型」或「一键配置」设置主模型'));
5356
5395
  return;
5357
5396
  }
5358
5397
 
5359
- const providerName = primary.split('/')[0];
5360
- const provider = config.models?.providers?.[providerName];
5398
+ const providerName = testTarget.providerName;
5399
+ const provider = testTarget.provider;
5361
5400
  if (!provider) {
5362
5401
  console.log(chalk.yellow(`⚠️ 主模型对应的中转站不存在: ${providerName}`));
5363
5402
  return;
5364
5403
  }
5365
5404
 
5366
- const apiType = provider.api || '';
5367
- const typeLabel = apiType.startsWith('anthropic')
5368
- ? 'Claude'
5369
- : (apiType.startsWith('openai') ? 'Codex' : '模型');
5405
+ const typeLabel = testTarget.typeLabel;
5370
5406
 
5371
5407
  if (!provider.apiKey) {
5372
5408
  console.log(chalk.yellow(`⚠️ ${typeLabel} API Key 未设置`));
@@ -5376,10 +5412,11 @@ async function testConnection(paths, args = {}) {
5376
5412
  // 获取 Gateway 配置
5377
5413
  const gatewayPort = config.gateway?.port || 18789;
5378
5414
 
5379
- console.log(chalk.gray(`当前激活: ${typeLabel}`));
5380
- console.log(chalk.gray(`中转节点: ${provider.baseUrl}`));
5381
- console.log(chalk.gray(`模型: ${primary}`));
5382
- console.log(chalk.gray(`Gateway: http://127.0.0.1:${gatewayPort}\n`));
5415
+ console.log(chalk.cyan(`当前测试: ${typeLabel}`));
5416
+ if (testTarget.agentId) {
5417
+ console.log(chalk.cyan(`测试入口: ${testTarget.agentId}${testTarget.agentName ? ` (${testTarget.agentName})` : ''}`));
5418
+ }
5419
+ console.log(chalk.cyan(`模型: ${primary}\n`));
5383
5420
  // 获取 Gateway token
5384
5421
  const gatewayToken = config.gateway?.auth?.token;
5385
5422
  if (!gatewayToken) {
@@ -5452,7 +5489,7 @@ async function testConnection(paths, args = {}) {
5452
5489
  console.log(chalk.cyan(`\n步骤 2/2: 测试 Gateway API 端点...`));
5453
5490
 
5454
5491
  try {
5455
- const cliResult = await testGatewayViaAgent(primary);
5492
+ const cliResult = await testGatewayViaAgent(primary, testTarget.agentId);
5456
5493
  let cliPassed = false;
5457
5494
 
5458
5495
  if (cliResult.usedCli) {
@@ -5477,7 +5514,7 @@ async function testConnection(paths, args = {}) {
5477
5514
  console.log(chalk.red(` 期望: ${primary}`));
5478
5515
  console.log(chalk.cyan(` 实际: ${actualModelKey}`));
5479
5516
  console.log(chalk.gray(` 这意味着 ${primary} 无法正常工作,请检查该模型的中转配置`));
5480
- const configuredFallbacks = config.agents?.defaults?.model?.fallbacks || [];
5517
+ const configuredFallbacks = testTarget.fallbacks || [];
5481
5518
  if (configuredFallbacks.length > 0 && !configuredFallbacks.includes(actualModelKey)) {
5482
5519
  console.log(chalk.yellow(` ⚠️ 实际回退模型不在当前配置的 fallbacks 中,疑似读到了另一份配置`));
5483
5520
  console.log(chalk.gray(` 当前 fallbacks: ${configuredFallbacks.join(', ')}`));
@@ -5506,17 +5543,6 @@ async function testConnection(paths, args = {}) {
5506
5543
  console.log(chalk.cyan(` Provider: ${cliResult.provider}`));
5507
5544
  console.log(chalk.cyan(` Model: ${cliResult.model}`));
5508
5545
  }
5509
- if (cliResult.message) {
5510
- const reply = sanitizeModelReply(cliResult.message, {
5511
- provider: cliResult.provider,
5512
- model: cliResult.model,
5513
- modelKey: primary
5514
- });
5515
- console.log(chalk.yellow(` 模型回复: ${reply}`));
5516
- }
5517
- if (!isFallback) {
5518
- console.log(chalk.gray(' 将继续验证 Web 鉴权端点(避免"CLI 正常但网页 401")...'));
5519
- }
5520
5546
  }
5521
5547
  }
5522
5548
 
@@ -5547,7 +5573,6 @@ async function testConnection(paths, args = {}) {
5547
5573
  const primaryApi = config.models?.providers?.[primaryProvider]?.api || '';
5548
5574
  const isAnthropic = primaryApi.startsWith('anthropic');
5549
5575
  const testEndpoint = isAnthropic ? '/v1/messages' : '/v1/chat/completions';
5550
- console.log(chalk.gray(` 端点: http://127.0.0.1:${gatewayPort}${testEndpoint}`));
5551
5576
  const startTime = Date.now();
5552
5577
  let result = await testGatewayApi(gatewayPort, gatewayToken, primary, testEndpoint);
5553
5578
  const latency = Date.now() - startTime;
@@ -5555,26 +5580,17 @@ async function testConnection(paths, args = {}) {
5555
5580
  // 回退:如果首选端点返回 404/405,尝试另一个
5556
5581
  if (!result.success && result.reachable && [404, 405].includes(result.status)) {
5557
5582
  const fallbackEndpoint = isAnthropic ? '/v1/chat/completions' : '/v1/responses';
5558
- console.log(chalk.gray(` ${testEndpoint} 不支持,回退测试 ${fallbackEndpoint}...`));
5559
5583
  result = await testGatewayApi(gatewayPort, gatewayToken, primary, fallbackEndpoint);
5560
5584
  }
5561
5585
 
5562
5586
  // CLI 对话已成功 + Gateway 可达(404/405)= Dashboard 通过 WebSocket 工作,视为通过
5563
5587
  if (!result.success && cliPassed && result.reachable && [404, 405].includes(result.status)) {
5564
5588
  console.log(chalk.green(`\n✅ Gateway 测试通过`));
5565
- console.log(chalk.cyan(` CLI 对话正常,Gateway 可达`));
5566
- console.log(chalk.gray(` 注: Gateway Dashboard 通过 WebSocket 通信,REST 端点返回 405 属正常现象`));
5567
5589
  console.log(chalk.green(`\n🌐 Web Dashboard 访问地址:`));
5568
5590
  console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}/#token=${gatewayToken}`));
5569
5591
  } else if (result.success) {
5570
- console.log(chalk.green(`\n✅ Gateway 测试成功!Web Dashboard 可正常使用`));
5592
+ console.log(chalk.green(`\n✅ Gateway 测试通过`));
5571
5593
  console.log(chalk.cyan(` 响应时间: ${latency}ms`));
5572
- const reply = sanitizeModelReply(result.message, {
5573
- provider: providerName,
5574
- model: primary.includes('/') ? primary.split('/')[1] : '',
5575
- modelKey: primary
5576
- });
5577
- console.log(chalk.yellow(` 模型回复: ${reply}`));
5578
5594
  console.log(chalk.green(`\n🌐 Web Dashboard 访问地址:`));
5579
5595
  console.log(chalk.cyan(` http://127.0.0.1:${gatewayPort}/#token=${gatewayToken}`));
5580
5596
  } else {
@@ -5968,7 +5984,7 @@ function testGatewayApi(port, token, model, endpoint = '/v1/chat/completions') {
5968
5984
  });
5969
5985
  }
5970
5986
 
5971
- function testGatewayViaAgent(model) {
5987
+ function testGatewayViaAgent(model, agentId = '') {
5972
5988
  return new Promise((resolve) => {
5973
5989
  const gwEnv = detectGatewayEnv();
5974
5990
  const sessionId = `yymaxapi-test-${Date.now()}`;
@@ -5979,11 +5995,12 @@ function testGatewayViaAgent(model) {
5979
5995
  if (gwEnv === 'wsl') {
5980
5996
  // Gateway 在 WSL 中,agent 也要在 WSL 中执行
5981
5997
  const wslCli = getWslCliBinary();
5998
+ const subcommand = buildGatewayAgentSubcommand({ sessionId, agentId });
5982
5999
  if (wslCli) {
5983
- const agentCmd = `${wslCli} agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120`;
6000
+ const agentCmd = `${wslCli} ${subcommand}`;
5984
6001
  cmd = `wsl -- bash -c '${agentCmd.replace(/'/g, "'\\''")}'`;
5985
6002
  } else {
5986
- const agentCmd = `openclaw agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120 2>/dev/null || clawdbot agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120 2>/dev/null || moltbot agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120`;
6003
+ const agentCmd = `openclaw ${subcommand} 2>/dev/null || clawdbot ${subcommand} 2>/dev/null || moltbot ${subcommand}`;
5987
6004
  cmd = `wsl -- bash -lc '${agentCmd.replace(/'/g, "'\\''")}'`;
5988
6005
  }
5989
6006
  execOpts = { timeout: 120000 };
@@ -6001,9 +6018,13 @@ function testGatewayViaAgent(model) {
6001
6018
  delete env.OPENAI_API_KEY;
6002
6019
  delete env.OPENCLAW_CODEX_KEY;
6003
6020
  const useNode = nodeInfo && isNodeShebang(cliBinary);
6004
- cmd = useNode
6005
- ? `"${nodeInfo.path}" "${cliBinary}" agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120`
6006
- : `"${cliBinary}" agent --session-id ${sessionId} --message "请回复你的模型名称" --json --timeout 120`;
6021
+ cmd = buildGatewayAgentCliCommand({
6022
+ cliBinary,
6023
+ nodeInfo,
6024
+ useNode,
6025
+ sessionId,
6026
+ agentId
6027
+ });
6007
6028
  execOpts = { timeout: 120000, env };
6008
6029
  }
6009
6030
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yymaxapi",
3
- "version": "1.0.85",
3
+ "version": "1.0.87",
4
4
  "description": "跨平台 OpenClaw/Clawdbot 配置管理工具 - 管理中转地址、模型切换、API Keys、测速优化",
5
5
  "main": "bin/yymaxapi.js",
6
6
  "bin": {