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-
|
|
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-
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
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-
|
|
103
|
-
"name": "Claude
|
|
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":
|
|
131
|
-
"maxTokens":
|
|
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-
|
|
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.
|
|
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-
|
|
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.
|
|
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
|
-
// 移除旧标记块(仅移除
|
|
1321
|
+
// 移除旧标记块(仅移除 opencode 自己写入的兼容 provider)
|
|
1307
1322
|
content = content.replace(/# >>> yunyi opencode >>>[\s\S]*?# <<< yunyi opencode <<<\n?/g, '');
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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.
|
|
2325
|
-
const YYMAXAPI_OPENCLAW_GPT_FALLBACK = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.
|
|
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-
|
|
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 ||
|
|
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
|
|
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-
|
|
5653
|
+
: CLAUDE_MODELS[0]?.id || 'claude-opus-4-8';
|
|
5595
5654
|
const codexModelId = !isClaudePrimary
|
|
5596
5655
|
? selectedModelId
|
|
5597
|
-
: CODEX_MODELS[0]?.id || 'gpt-5.
|
|
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🔧
|
|
6019
|
+
console.log(chalk.cyan.bold('\n🔧 yymaxapi 配置工具\n'));
|
|
5961
6020
|
|
|
5962
6021
|
const paths = getConfigPath();
|
|
5963
|
-
console.log(chalk.gray(
|
|
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
|
|
6003
|
-
|
|
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
|
-
|
|
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('
|
|
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-
|
|
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.
|
|
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": "
|
|
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-
|
|
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":
|
|
39
|
-
"maxTokens":
|
|
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
|
|
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-
|
|
83
|
-
"name": "Claude
|
|
85
|
+
"id": "claude-opus-4-8",
|
|
86
|
+
"name": "Claude Opus 4.8"
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
```
|
|
87
90
|
|
|
88
|
-
### GPT 5.
|
|
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.
|
|
98
|
-
"name": "GPT 5.
|
|
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-
|
|
107
|
-
-
|
|
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
|
|
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-
|
|
129
|
-
"name": "Claude
|
|
134
|
+
"id": "claude-opus-4-8",
|
|
135
|
+
"name": "Claude Opus 4.8"
|
|
130
136
|
}
|
|
131
137
|
}
|
|
132
138
|
```
|
|
133
139
|
|
|
134
|
-
第二条 — GPT 5.
|
|
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.
|
|
144
|
-
"name": "GPT 5.
|
|
149
|
+
"id": "gpt-5.5",
|
|
150
|
+
"name": "GPT 5.5"
|
|
145
151
|
}
|
|
146
152
|
}
|
|
147
153
|
```
|