yymaxapi 1.0.120 → 1.0.123

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/README.md CHANGED
@@ -47,22 +47,22 @@ set OPENCLAW_CODEX_KEY=你的Key && npx yymaxapi@latest preset-codex
47
47
  **方式四:完全自动化(无交互)**
48
48
  ```bash
49
49
  # macOS/Linux
50
- OPENCLAW_CLAUDE_KEY="你的Key" npx yymaxapi@latest preset-claude --model claude-opus-4-7 --set-primary true --force --test true
50
+ OPENCLAW_CLAUDE_KEY="你的Key" npx yymaxapi@latest preset-claude --model claude-opus-4-8 --set-primary true --force --test true
51
51
 
52
52
  # Windows PowerShell
53
- $env:OPENCLAW_CLAUDE_KEY="你的Key"; npx yymaxapi@latest preset-claude --model claude-opus-4-7 --set-primary true --force --test true
53
+ $env:OPENCLAW_CLAUDE_KEY="你的Key"; npx yymaxapi@latest preset-claude --model claude-opus-4-8 --set-primary true --force --test true
54
54
 
55
55
  # Windows CMD
56
- set OPENCLAW_CLAUDE_KEY=你的Key && npx yymaxapi@latest preset-claude --model claude-opus-4-7 --set-primary true --force --test true
56
+ set OPENCLAW_CLAUDE_KEY=你的Key && npx yymaxapi@latest preset-claude --model claude-opus-4-8 --set-primary true --force --test true
57
57
 
58
58
  # macOS/Linux
59
- OPENCLAW_CODEX_KEY="你的Key" npx yymaxapi@latest preset-codex --model gpt-5.4 --set-primary true --force --test true
59
+ OPENCLAW_CODEX_KEY="你的Key" npx yymaxapi@latest preset-codex --model gpt-5.5 --set-primary true --force --test true
60
60
 
61
61
  # Windows PowerShell
62
- $env:OPENCLAW_CODEX_KEY="你的Key"; npx yymaxapi@latest preset-codex --model gpt-5.4 --set-primary true --force --test true
62
+ $env:OPENCLAW_CODEX_KEY="你的Key"; npx yymaxapi@latest preset-codex --model gpt-5.5 --set-primary true --force --test true
63
63
 
64
64
  # Windows CMD
65
- set OPENCLAW_CODEX_KEY=你的Key && npx yymaxapi@latest preset-codex --model gpt-5.4 --set-primary true --force --test true
65
+ set OPENCLAW_CODEX_KEY=你的Key && npx yymaxapi@latest preset-codex --model gpt-5.5 --set-primary true --force --test true
66
66
  ```
67
67
 
68
68
  ## 重要说明
package/bin/yymaxapi.js CHANGED
@@ -99,13 +99,17 @@ const FALLBACK_ENDPOINTS = [
99
99
 
100
100
  const DEFAULT_CLAUDE_MODELS = [
101
101
  {
102
- "id": "claude-sonnet-4-6",
103
- "name": "Claude Sonnet 4.6"
102
+ "id": "claude-opus-4-8",
103
+ "name": "Claude Opus 4.8"
104
104
  },
105
105
  {
106
106
  "id": "claude-opus-4-7",
107
107
  "name": "Claude Opus 4.7"
108
108
  },
109
+ {
110
+ "id": "claude-sonnet-4-6",
111
+ "name": "Claude Sonnet 4.6"
112
+ },
109
113
  {
110
114
  "id": "claude-haiku-4-5",
111
115
  "name": "Claude Haiku 4.5"
@@ -113,6 +117,10 @@ const DEFAULT_CLAUDE_MODELS = [
113
117
  ];
114
118
 
115
119
  const DEFAULT_CODEX_MODELS = [
120
+ {
121
+ "id": "gpt-5.5",
122
+ "name": "GPT 5.5"
123
+ },
116
124
  {
117
125
  "id": "gpt-5.4",
118
126
  "name": "GPT 5.4"
@@ -127,8 +135,8 @@ const DEFAULT_API_CONFIG = {
127
135
  "claude": {
128
136
  "urlSuffix": "/claude",
129
137
  "api": "anthropic-messages",
130
- "contextWindow": 200000,
131
- "maxTokens": 8192,
138
+ "contextWindow": 1000000,
139
+ "maxTokens": 128000,
132
140
  "providerName": "yunyi-claude"
133
141
  },
134
142
  "codex": {
@@ -243,11 +251,11 @@ const CODEX_MODELS = PRESETS.models.codex;
243
251
  const API_CONFIG = PRESETS.apiConfig;
244
252
 
245
253
  function getDefaultClaudeModel() {
246
- return CLAUDE_MODELS[0] || { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6' };
254
+ return CLAUDE_MODELS[0] || { id: 'claude-opus-4-8', name: 'Claude Opus 4.8' };
247
255
  }
248
256
 
249
257
  function getDefaultCodexModel() {
250
- return CODEX_MODELS[0] || { id: 'gpt-5.4', name: 'GPT 5.4' };
258
+ return CODEX_MODELS[0] || { id: 'gpt-5.5', name: 'GPT 5.5' };
251
259
  }
252
260
 
253
261
  function getExternalClaudeProviderKey() {
@@ -337,6 +345,12 @@ function resolveHermesModelType(modelId, preferredType = '') {
337
345
  return requestedType || 'claude';
338
346
  }
339
347
 
348
+ function getKnownModelName(modelId) {
349
+ const normalized = String(modelId || '').trim();
350
+ const model = [...CLAUDE_MODELS, ...CODEX_MODELS].find(item => item.id === normalized);
351
+ return model?.name || normalized || '未选择模型';
352
+ }
353
+
340
354
  async function promptHermesModelSelection(args = {}, message = '选择 Hermes 默认模型:') {
341
355
  const requestedModel = (args['model-id'] || args.model || '').toString().trim();
342
356
  const requestedType = normalizeHermesModelType(
@@ -1131,7 +1145,7 @@ function writeClaudeCodeSettings(baseUrl, apiKey, modelId = getDefaultClaudeMode
1131
1145
  }
1132
1146
  const normalizedBaseUrl = baseUrl.replace(/\/+$/, '');
1133
1147
  const normalizedModelId = String(modelId || getDefaultClaudeModel().id).trim() || getDefaultClaudeModel().id;
1134
- const pinnedOpusModel = (CLAUDE_MODELS.find(model => /opus/i.test(model.id)) || {}).id || 'claude-opus-4-7';
1148
+ const pinnedOpusModel = (CLAUDE_MODELS.find(model => /opus/i.test(model.id)) || {}).id || 'claude-opus-4-8';
1135
1149
  const pinnedSonnetModel = (CLAUDE_MODELS.find(model => /sonnet/i.test(model.id)) || {}).id || 'claude-sonnet-4-6';
1136
1150
  const pinnedHaikuModel = (CLAUDE_MODELS.find(model => /haiku/i.test(model.id)) || {}).id || 'claude-haiku-4-5';
1137
1151
  settings.apiBaseUrl = normalizedBaseUrl;
@@ -1150,7 +1164,7 @@ function writeClaudeCodeSettings(baseUrl, apiKey, modelId = getDefaultClaudeMode
1150
1164
  } catch { /* 非关键,静默失败 */ }
1151
1165
  }
1152
1166
 
1153
- function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.4') {
1167
+ function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.5') {
1154
1168
  const codexDir = path.join(os.homedir(), '.codex');
1155
1169
  if (!fs.existsSync(codexDir)) fs.mkdirSync(codexDir, { recursive: true });
1156
1170
 
@@ -1185,6 +1199,7 @@ function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.4') {
1185
1199
  }
1186
1200
  existing = existing.replace(/\[model_providers\.openclaw-relay\]\n(?:(?!\[)[^\n]*\n?)*/g, '');
1187
1201
  existing = existing.replace(/# >>> yunyi opencode >>>[\s\S]*?# <<< yunyi opencode <<<\n?/g, '');
1202
+ existing = existing.replace(/# >>> maxapi opencode >>>[\s\S]*?# <<< maxapi opencode <<<\n?/g, '');
1188
1203
  existing = existing.replace(/\n{3,}/g, '\n\n').trim();
1189
1204
  }
1190
1205
  const hasExistingTopLevelModelConfig = /^model\s*=\s*"[^"]*"\s*$/m.test(existing)
@@ -1303,19 +1318,54 @@ function writeOpencodeConfig(claudeBaseUrl, codexBaseUrl, apiKey, defaultModelKe
1303
1318
  content = fs.readFileSync(codexConfigPath, 'utf8');
1304
1319
  }
1305
1320
 
1306
- // 移除旧标记块(仅移除 yunyi opencode 自己的)
1321
+ // 移除旧标记块(仅移除 opencode 自己写入的兼容 provider)
1307
1322
  content = content.replace(/# >>> yunyi opencode >>>[\s\S]*?# <<< yunyi opencode <<<\n?/g, '');
1308
-
1309
- // 移除旧版 yunyi-cli 写入的 [model_providers.yunyi] 和 [model_providers.yunyi-claude](不动 yunyi-codex,由 writeCodexConfig 管理)
1310
- content = content.replace(/\[model_providers\.yunyi\]\n(?:(?!\[)[^\n]*\n?)*/g, '');
1311
- content = content.replace(/\[model_providers\.yunyi-claude\]\n(?:(?!\[)[^\n]*\n?)*/g, '');
1323
+ content = content.replace(/# >>> maxapi opencode >>>[\s\S]*?# <<< maxapi opencode <<<\n?/g, '');
1324
+
1325
+ // 移除旧版 yunyi-cli / maxai-cli 写入的同名 provider,随后写入当前受管块
1326
+ const removableProviderKeys = [
1327
+ 'yunyi',
1328
+ 'yunyi-claude',
1329
+ 'yunyi-codex',
1330
+ 'maxapi',
1331
+ 'maxapi-codex',
1332
+ claudeProviderKey,
1333
+ codexProviderKey
1334
+ ];
1335
+ for (const providerKey of [...new Set(removableProviderKeys)]) {
1336
+ const escapedProviderKey = escapeRegExp(providerKey);
1337
+ content = content.replace(new RegExp(`\\[model_providers\\.${escapedProviderKey}\\]\\n(?:(?!\\[)[^\\n]*\\n?)*`, 'g'), '');
1338
+ }
1312
1339
 
1313
1340
  // 清理多余空行
1314
1341
  content = content.replace(/\n{3,}/g, '\n\n').trim();
1315
1342
 
1316
- // yunyi-codex provider writeCodexConfig 统一管理,此处不再重复写入
1343
+ const markerPrefix = claudeProviderKey.startsWith('maxapi') || codexProviderKey.startsWith('maxapi') ? 'maxapi' : 'yunyi';
1344
+ const marker = `# >>> ${markerPrefix} opencode >>>`;
1345
+ const markerEnd = `# <<< ${markerPrefix} opencode <<<`;
1346
+ let normalizedCodexTomlUrl = codexUrl;
1347
+ if (normalizedCodexTomlUrl && !normalizedCodexTomlUrl.endsWith('/v1')) normalizedCodexTomlUrl += '/v1';
1348
+
1349
+ const opencodeProviderBlock = [
1350
+ marker,
1351
+ `[model_providers.${claudeProviderKey}]`,
1352
+ `name = "${brandPrefix} Claude"`,
1353
+ `base_url = "${claudeUrl}/v1"`,
1354
+ `wire_api = "anthropic"`,
1355
+ `experimental_bearer_token = "${apiKey}"`,
1356
+ ...(normalizedCodexTomlUrl ? [
1357
+ '',
1358
+ `[model_providers.${codexProviderKey}]`,
1359
+ `name = "${brandPrefix} Codex"`,
1360
+ `base_url = "${normalizedCodexTomlUrl}"`,
1361
+ `wire_api = "responses"`,
1362
+ `experimental_bearer_token = "${apiKey}"`
1363
+ ] : []),
1364
+ markerEnd
1365
+ ].join('\n');
1317
1366
 
1318
- fs.writeFileSync(codexConfigPath, content, 'utf8');
1367
+ const nextContent = [content, opencodeProviderBlock].filter(Boolean).join('\n\n') + '\n';
1368
+ fs.writeFileSync(codexConfigPath, nextContent, 'utf8');
1319
1369
 
1320
1370
  // ---- 3. ~/.codex/auth.json ----
1321
1371
  const authPath = path.join(codexDir, 'auth.json');
@@ -2319,15 +2369,15 @@ const YYMAXAPI_OPENCLAW_MAIN_AGENT_ID = 'main';
2319
2369
  const YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID = 'yunyi-claude';
2320
2370
  const YYMAXAPI_OPENCLAW_GPT_AGENT_ID = 'yunyi-gpt';
2321
2371
  const YYMAXAPI_OPENCLAW_LEGACY_GPT_AGENT_IDS = ['gpt'];
2322
- const YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY = `${YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER}/claude-sonnet-4-6`;
2372
+ const YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY = `${YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER}/claude-opus-4-8`;
2323
2373
  const YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK = `${YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER}/claude-opus-4-7`;
2324
- const YYMAXAPI_OPENCLAW_GPT_PRIMARY = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.4`;
2325
- const YYMAXAPI_OPENCLAW_GPT_FALLBACK = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.3-codex`;
2374
+ const YYMAXAPI_OPENCLAW_GPT_PRIMARY = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.5`;
2375
+ const YYMAXAPI_OPENCLAW_GPT_FALLBACK = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.4`;
2326
2376
  const YYMAXAPI_MANAGED_MAIN_NAMES = new Set(['Claude', 'claude', 'yunyi-claude', 'claude-yunyi']);
2327
2377
  const YYMAXAPI_MANAGED_GPT_NAMES = new Set(['GPT', 'Codex', 'gpt', 'yunyi-gpt', 'yunyi-codex']);
2328
2378
  const YYMAXAPI_MANAGED_MULTIMODAL_MODELS = {
2329
- claude: new Set(['claude-sonnet-4-6', 'claude-opus-4-7', 'claude-haiku-4-5']),
2330
- codex: new Set(['gpt-5.4', 'gpt-5.3-codex'])
2379
+ claude: new Set(['claude-opus-4-8', 'claude-opus-4-7', 'claude-sonnet-4-6', 'claude-haiku-4-5']),
2380
+ codex: new Set(['gpt-5.5', 'gpt-5.4', 'gpt-5.3-codex'])
2331
2381
  };
2332
2382
 
2333
2383
  function isYymaxapiOpenClawBuild() {
@@ -2380,7 +2430,7 @@ function getManagedYunyiModelInput(type, modelId) {
2380
2430
 
2381
2431
  function getManagedYunyiProviderModels(type) {
2382
2432
  const apiConfig = type === 'claude'
2383
- ? { contextWindow: API_CONFIG.claude?.contextWindow || 200000, maxTokens: API_CONFIG.claude?.maxTokens || 8192 }
2433
+ ? { contextWindow: API_CONFIG.claude?.contextWindow || 1000000, maxTokens: API_CONFIG.claude?.maxTokens || 128000 }
2384
2434
  : { contextWindow: API_CONFIG.codex?.contextWindow || 1000000, maxTokens: API_CONFIG.codex?.maxTokens || 128000 };
2385
2435
 
2386
2436
  return getManagedYunyiModelCatalog(type).map(model => ({
@@ -2449,7 +2499,7 @@ function normalizeManagedYunyiModelState(type, modelState = {}, options = {}) {
2449
2499
  const canPreserve = !options.force && currentPrimary && knownKeys.includes(currentPrimary);
2450
2500
  const primary = canPreserve ? currentPrimary : fallbackPrimary;
2451
2501
 
2452
- let fallbacks = Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
2502
+ let fallbacks = !options.force && Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
2453
2503
  fallbacks = [...new Set(
2454
2504
  fallbacks
2455
2505
  .map(item => canonicalizeManagedYunyiModelKey(item, type))
@@ -2470,7 +2520,7 @@ function normalizeManagedYunyiDefaultsModel(modelState = {}, options = {}) {
2470
2520
  ? canonicalizeManagedYunyiModelKey(currentPrimary)
2471
2521
  : YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY;
2472
2522
 
2473
- let fallbacks = Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
2523
+ let fallbacks = !options.force && Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
2474
2524
  fallbacks = [...new Set(
2475
2525
  fallbacks
2476
2526
  .map(item => {
@@ -2962,7 +3012,7 @@ function normalizeManagedYunyiImageModel(modelState = {}, options = {}) {
2962
3012
  ? canonicalizeManagedYunyiModelKey(currentPrimary)
2963
3013
  : YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY;
2964
3014
 
2965
- let fallbacks = Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
3015
+ let fallbacks = !options.force && Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
2966
3016
  fallbacks = [...new Set(
2967
3017
  fallbacks
2968
3018
  .map(item => {
@@ -3071,7 +3121,16 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
3071
3121
  }
3072
3122
 
3073
3123
  if (shouldManageYunyiImageDefaults(config)) {
3074
- const currentImageModel = normalizeDefaultModelSelection(config.agents.defaults.imageModel, config);
3124
+ const hasExplicitImageModel = config.agents.defaults.imageModel
3125
+ && typeof config.agents.defaults.imageModel === 'object'
3126
+ && !Array.isArray(config.agents.defaults.imageModel)
3127
+ && (
3128
+ typeof config.agents.defaults.imageModel.primary === 'string'
3129
+ || Array.isArray(config.agents.defaults.imageModel.fallbacks)
3130
+ );
3131
+ const currentImageModel = hasExplicitImageModel
3132
+ ? normalizeDefaultModelSelection(config.agents.defaults.imageModel, config)
3133
+ : {};
3075
3134
  const nextImageModel = normalizeManagedYunyiImageModel(currentImageModel, options);
3076
3135
  if (JSON.stringify(currentImageModel) !== JSON.stringify(nextImageModel)) {
3077
3136
  config.agents.defaults.imageModel = nextImageModel;
@@ -5591,10 +5650,10 @@ async function autoActivate(paths, args = {}) {
5591
5650
  const isClaudePrimary = selectedType === 'claude';
5592
5651
  const claudeModelId = isClaudePrimary
5593
5652
  ? selectedModelId
5594
- : CLAUDE_MODELS[0]?.id || 'claude-sonnet-4-6';
5653
+ : CLAUDE_MODELS[0]?.id || 'claude-opus-4-8';
5595
5654
  const codexModelId = !isClaudePrimary
5596
5655
  ? selectedModelId
5597
- : CODEX_MODELS[0]?.id || 'gpt-5.4';
5656
+ : CODEX_MODELS[0]?.id || 'gpt-5.5';
5598
5657
 
5599
5658
  const claudeModel = CLAUDE_MODELS.find(m => m.id === claudeModelId) || { id: claudeModelId, name: claudeModelId };
5600
5659
  const codexModel = CODEX_MODELS.find(m => m.id === codexModelId) || { id: codexModelId, name: codexModelId };
@@ -5957,10 +6016,11 @@ async function activateHermes(paths, args = {}) {
5957
6016
  async function main() {
5958
6017
  console.clear();
5959
6018
 
5960
- console.log(chalk.cyan.bold('\n🔧 OpenClaw API 配置工具\n'));
6019
+ console.log(chalk.cyan.bold('\n🔧 yymaxapi 配置工具\n'));
5961
6020
 
5962
6021
  const paths = getConfigPath();
5963
- console.log(chalk.gray(`配置文件: ${paths.openclawConfig}\n`));
6022
+ console.log(chalk.gray(`OpenClaw 配置: ${paths.openclawConfig}`));
6023
+ console.log(chalk.gray(`Hermes 配置: ${getHermesConfigPath()}\n`));
5964
6024
 
5965
6025
  // 首次运行备份
5966
6026
  if (backupOriginalConfig(paths.openclawConfig, paths.configDir)) {
@@ -5999,10 +6059,15 @@ async function main() {
5999
6059
 
6000
6060
  while (true) {
6001
6061
  // 显示当前状态
6002
- const statusLine = getConfigStatusLine(paths);
6003
- if (statusLine) {
6062
+ const statusLines = [
6063
+ getConfigStatusLine(paths),
6064
+ getHermesStatusLine()
6065
+ ].filter(Boolean);
6066
+ if (statusLines.length > 0) {
6004
6067
  console.log(chalk.gray('─'.repeat(40)));
6005
- console.log(statusLine);
6068
+ for (const statusLine of statusLines) {
6069
+ console.log(statusLine);
6070
+ }
6006
6071
  console.log(chalk.gray('─'.repeat(40)) + '\n');
6007
6072
  }
6008
6073
 
@@ -6125,7 +6190,7 @@ function getConfigStatusLine(paths) {
6125
6190
  }
6126
6191
 
6127
6192
  if (parts.length === 0 && otherCount === 0) {
6128
- return chalk.gray('当前状态: 未配置任何模型');
6193
+ return chalk.gray('OpenClaw: 未配置任何模型');
6129
6194
  }
6130
6195
 
6131
6196
  const primaryModelId = primary.split('/')[1] || '';
@@ -6133,7 +6198,39 @@ function getConfigStatusLine(paths) {
6133
6198
 
6134
6199
  const gwEnv = detectGatewayEnv();
6135
6200
  const envTag = gwEnv === 'wsl' ? chalk.cyan(' [WSL]') : '';
6136
- return chalk.gray('当前状态: ') + parts.join(' ') + chalk.gray(' (✓ 主模型 ○ 已配置)') + modelTag + envTag;
6201
+ return chalk.gray('OpenClaw: ') + parts.join(' ') + chalk.gray(' (✓ 主模型 ○ 已配置)') + modelTag + envTag;
6202
+ } catch {
6203
+ return null;
6204
+ }
6205
+ }
6206
+
6207
+ function getHermesStatusLine() {
6208
+ try {
6209
+ let config = readHermesCliConfig();
6210
+ let wslMirror = null;
6211
+
6212
+ if (process.platform === 'win32') {
6213
+ wslMirror = getHermesWslMirrorInfo();
6214
+ if (!config.configured && (wslMirror.configPath || wslMirror.envPath)) {
6215
+ config = readHermesWslCliConfig(wslMirror);
6216
+ }
6217
+ }
6218
+
6219
+ if (!config.configured) return null;
6220
+
6221
+ const modelName = getKnownModelName(config.modelId);
6222
+ const readyMark = config.apiKey ? chalk.green('✓') : chalk.yellow('○');
6223
+ const modelTag = config.modelId ? chalk.cyan(` [模型: ${config.modelId}]`) : '';
6224
+ const protocolTag = config.type === 'codex' ? chalk.cyan(' [GPT]') : chalk.cyan(' [Claude]');
6225
+ const hasWslTarget = !!(wslMirror?.sourceConfigPath || wslMirror?.commandPath);
6226
+ let envTag = '';
6227
+ if (hasWslTarget && wslMirror?.target?.user) {
6228
+ envTag = chalk.cyan(` [WSL ${wslMirror.target.user}]`);
6229
+ } else if (hasWslTarget) {
6230
+ envTag = chalk.cyan(' [WSL]');
6231
+ }
6232
+
6233
+ return chalk.gray('Hermes-Agent: ') + chalk.green(`${modelName} ${readyMark}`) + protocolTag + modelTag + envTag;
6137
6234
  } catch {
6138
6235
  return null;
6139
6236
  }
@@ -7414,7 +7511,7 @@ function testClaudeApi(baseUrl, apiKey, model) {
7414
7511
  const protocol = urlObj.protocol === 'https:' ? https : http;
7415
7512
 
7416
7513
  const postData = JSON.stringify({
7417
- model: model || 'claude-sonnet-4-6',
7514
+ model: model || 'claude-opus-4-8',
7418
7515
  max_tokens: 150,
7419
7516
  messages: [{ role: 'user', content: '你是哪个模型?请用一句话回答你的模型名称和版本。' }]
7420
7517
  });
@@ -7474,7 +7571,7 @@ function testCodexApi(baseUrl, apiKey, model) {
7474
7571
  const protocol = urlObj.protocol === 'https:' ? https : http;
7475
7572
 
7476
7573
  const postData = JSON.stringify({
7477
- model: model || 'gpt-5.4',
7574
+ model: model || 'gpt-5.5',
7478
7575
  input: '你是哪个模型?请用一句话回答你的模型名称和版本。'
7479
7576
  });
7480
7577
 
@@ -14,7 +14,8 @@
14
14
  {
15
15
  "endpoints": [
16
16
  { "name": "默认主节点", "url": "https://yunyi.yun" },
17
- { "name": "CF国外节点1", "url": "https://cdn2.yunyi.yun" }
17
+ { "name": "备用 CDN 域名 1", "url": "https://cdn1.yunyi.yun" },
18
+ { "name": "备用 CDN 域名 2", "url": "https://cdn2.yunyi.yun" }
18
19
  ],
19
20
  "fallbackEndpoints": [
20
21
  { "name": "备用节点1", "url": "http://47.99.42.193" },
@@ -22,11 +23,13 @@
22
23
  ],
23
24
  "models": {
24
25
  "claude": [
25
- { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6" },
26
+ { "id": "claude-opus-4-8", "name": "Claude Opus 4.8" },
26
27
  { "id": "claude-opus-4-7", "name": "Claude Opus 4.7" },
28
+ { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6" },
27
29
  { "id": "claude-haiku-4-5", "name": "Claude Haiku 4.5" }
28
30
  ],
29
31
  "codex": [
32
+ { "id": "gpt-5.5", "name": "GPT 5.5" },
30
33
  { "id": "gpt-5.4", "name": "GPT 5.4" },
31
34
  { "id": "gpt-5.3-codex", "name": "GPT 5.3 Codex" }
32
35
  ]
@@ -35,8 +38,8 @@
35
38
  "claude": {
36
39
  "urlSuffix": "/claude",
37
40
  "api": "anthropic-messages",
38
- "contextWindow": 200000,
39
- "maxTokens": 8192,
41
+ "contextWindow": 1000000,
42
+ "maxTokens": 128000,
40
43
  "providerName": "yunyi-claude"
41
44
  },
42
45
  "codex": {
@@ -70,7 +73,7 @@ npx yymaxapi@latest
70
73
 
71
74
  在腾讯云 OpenClaw 部署中,使用「自定义模型」接入云翼中转,已验证可用的配置:
72
75
 
73
- ### Claude Sonnet 4.6
76
+ ### Claude Opus 4.8
74
77
 
75
78
  ```json
76
79
  {
@@ -79,13 +82,13 @@ npx yymaxapi@latest
79
82
  "api": "anthropic-messages",
80
83
  "api_key": "<你的云翼 API Key>",
81
84
  "model": {
82
- "id": "claude-sonnet-4-6",
83
- "name": "Claude Sonnet 4.6"
85
+ "id": "claude-opus-4-8",
86
+ "name": "Claude Opus 4.8"
84
87
  }
85
88
  }
86
89
  ```
87
90
 
88
- ### GPT 5.4
91
+ ### GPT 5.5
89
92
 
90
93
  ```json
91
94
  {
@@ -94,8 +97,8 @@ npx yymaxapi@latest
94
97
  "api": "openai-completions",
95
98
  "api_key": "<你的云翼 API Key>",
96
99
  "model": {
97
- "id": "gpt-5.4",
98
- "name": "GPT 5.4"
100
+ "id": "gpt-5.5",
101
+ "name": "GPT 5.5"
99
102
  }
100
103
  }
101
104
  ```
@@ -103,8 +106,11 @@ npx yymaxapi@latest
103
106
  **注意事项:**
104
107
  - `base_url` 不要加 `/v1`,平台会自动拼接路径
105
108
  - 如需临时切到其他云翼域名,可直接把域名部分替换掉;`yymaxapi` 也支持在预设/一键激活命令中传 `--endpoint-url https://你的域名` 或 `--base-url https://你的域名/claude`
106
- - Claude 可用模型:`claude-sonnet-4-6`、`claude-opus-4-7`、`claude-haiku-4-5`
107
- - GPT 可用模型:`gpt-5.4`
109
+ - Claude 可用模型:`claude-opus-4-8`、`claude-opus-4-7`、`claude-sonnet-4-6`、`claude-haiku-4-5`
110
+ - Claude 默认模型:`claude-opus-4-8`
111
+ - `claude-opus-4-8` 按当前官方规格声明为 1M context / 128K max output
112
+ - GPT 可用模型:`gpt-5.5`、`gpt-5.4`、`gpt-5.3-codex`
113
+ - GPT 默认模型:`gpt-5.5`
108
114
  - 已验证环境:腾讯云 OpenCloudOS,OpenClaw `2026.2.3-1`
109
115
  - 参考文档:https://cloud.tencent.com/developer/article/2624003
110
116
 
@@ -116,7 +122,7 @@ npx yymaxapi@latest
116
122
 
117
123
  在腾讯云 OpenClaw 的「自定义模型」里添加**两条**,`api_key` 用同一云翼 Key 即可。
118
124
 
119
- 第一条 — Claude Sonnet 4.6
125
+ 第一条 — Claude Opus 4.8
120
126
 
121
127
  ```json
122
128
  {
@@ -125,13 +131,13 @@ npx yymaxapi@latest
125
131
  "api": "anthropic-messages",
126
132
  "api_key": "<你的云翼 API Key>",
127
133
  "model": {
128
- "id": "claude-sonnet-4-6",
129
- "name": "Claude Sonnet 4.6"
134
+ "id": "claude-opus-4-8",
135
+ "name": "Claude Opus 4.8"
130
136
  }
131
137
  }
132
138
  ```
133
139
 
134
- 第二条 — GPT 5.4
140
+ 第二条 — GPT 5.5
135
141
 
136
142
  ```json
137
143
  {
@@ -140,8 +146,8 @@ npx yymaxapi@latest
140
146
  "api": "openai-completions",
141
147
  "api_key": "<你的云翼 API Key>",
142
148
  "model": {
143
- "id": "gpt-5.4",
144
- "name": "GPT 5.4"
149
+ "id": "gpt-5.5",
150
+ "name": "GPT 5.5"
145
151
  }
146
152
  }
147
153
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yymaxapi",
3
- "version": "1.0.120",
3
+ "version": "1.0.123",
4
4
  "description": "跨平台 OpenClaw/Clawdbot 配置管理工具 - 管理中转地址、模型切换、API Keys、测速优化",
5
5
  "main": "bin/yymaxapi.js",
6
6
  "bin": {