yymaxapi 1.0.123 → 1.0.125
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 +68 -23
- package/package.json +1 -1
package/bin/yymaxapi.js
CHANGED
|
@@ -1248,13 +1248,39 @@ function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.5') {
|
|
|
1248
1248
|
} catch { /* 非关键,静默失败 */ }
|
|
1249
1249
|
}
|
|
1250
1250
|
|
|
1251
|
-
function
|
|
1251
|
+
function extractTomlProviderBearerToken(content, providerKey) {
|
|
1252
|
+
const escapedProviderKey = escapeRegExp(providerKey);
|
|
1253
|
+
const match = String(content || '').match(new RegExp(`\\[model_providers\\.${escapedProviderKey}\\][\\s\\S]*?experimental_bearer_token\\s*=\\s*"([^"]*)"`, 'm'));
|
|
1254
|
+
return String(match?.[1] || '').trim();
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
function readOpenClawProviderApiKey(providerKey) {
|
|
1258
|
+
try {
|
|
1259
|
+
const paths = getConfigPath();
|
|
1260
|
+
const config = readConfig(paths.openclawConfig);
|
|
1261
|
+
return String(config?.models?.providers?.[providerKey]?.apiKey || '').trim();
|
|
1262
|
+
} catch {
|
|
1263
|
+
return '';
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
function writeOpencodeConfig(claudeBaseUrl, codexBaseUrl, apiKey, defaultModelKey = getExternalModelKey('claude', getDefaultClaudeModel().id), options = {}) {
|
|
1252
1268
|
const home = os.homedir();
|
|
1253
1269
|
const claudeUrl = claudeBaseUrl.replace(/\/+$/, '');
|
|
1254
1270
|
const codexUrl = (codexBaseUrl || '').replace(/\/+$/, '');
|
|
1271
|
+
const claudeApiKey = String(apiKey || '').trim();
|
|
1255
1272
|
const claudeProviderKey = getExternalClaudeProviderKey();
|
|
1256
1273
|
const codexProviderKey = getExternalCodexProviderKey();
|
|
1274
|
+
const openClawCodexProviderKey = String(API_CONFIG?.codex?.providerName || codexProviderKey).trim() || codexProviderKey;
|
|
1257
1275
|
const brandPrefix = getProviderBrandPrefix();
|
|
1276
|
+
const codexDir = path.join(home, '.codex');
|
|
1277
|
+
const codexConfigPath = path.join(codexDir, 'config.toml');
|
|
1278
|
+
const codexAuthPath = path.join(codexDir, 'auth.json');
|
|
1279
|
+
const existingCodexToml = readTextIfExists(codexConfigPath);
|
|
1280
|
+
let existingCodexAuth = {};
|
|
1281
|
+
if (fs.existsSync(codexAuthPath)) {
|
|
1282
|
+
try { existingCodexAuth = JSON.parse(fs.readFileSync(codexAuthPath, 'utf8')); } catch { existingCodexAuth = {}; }
|
|
1283
|
+
}
|
|
1258
1284
|
|
|
1259
1285
|
// ---- 1. opencode.json (CLI + 桌面版) ----
|
|
1260
1286
|
const configDir = process.platform === 'win32'
|
|
@@ -1268,13 +1294,21 @@ function writeOpencodeConfig(claudeBaseUrl, codexBaseUrl, apiKey, defaultModelKe
|
|
|
1268
1294
|
try { existing = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch { existing = {}; }
|
|
1269
1295
|
}
|
|
1270
1296
|
if (!existing.provider) existing.provider = {};
|
|
1297
|
+
const codexApiKey = String(
|
|
1298
|
+
options.codexApiKey || options.codexKey || options.gptApiKey || options.gptKey || ''
|
|
1299
|
+
).trim()
|
|
1300
|
+
|| readOpenClawProviderApiKey(openClawCodexProviderKey)
|
|
1301
|
+
|| extractTomlProviderBearerToken(existingCodexToml, codexProviderKey)
|
|
1302
|
+
|| String(existingCodexAuth.OPENAI_API_KEY || '').trim()
|
|
1303
|
+
|| String(existing.provider?.[codexProviderKey]?.options?.apiKey || '').trim()
|
|
1304
|
+
|| claudeApiKey;
|
|
1271
1305
|
|
|
1272
1306
|
// Claude provider (@ai-sdk/anthropic)
|
|
1273
1307
|
existing.provider[claudeProviderKey] = {
|
|
1274
1308
|
name: `${brandPrefix} Claude`,
|
|
1275
1309
|
npm: '@ai-sdk/anthropic',
|
|
1276
1310
|
models: buildProviderModelMap(CLAUDE_MODELS),
|
|
1277
|
-
options: { apiKey, baseURL: `${claudeUrl}/v1` }
|
|
1311
|
+
options: { apiKey: claudeApiKey, baseURL: `${claudeUrl}/v1` }
|
|
1278
1312
|
};
|
|
1279
1313
|
|
|
1280
1314
|
// Codex provider (@ai-sdk/openai)
|
|
@@ -1283,7 +1317,7 @@ function writeOpencodeConfig(claudeBaseUrl, codexBaseUrl, apiKey, defaultModelKe
|
|
|
1283
1317
|
name: `${brandPrefix} Codex`,
|
|
1284
1318
|
npm: '@ai-sdk/openai',
|
|
1285
1319
|
models: buildProviderModelMap(CODEX_MODELS),
|
|
1286
|
-
options: { apiKey, baseURL: codexUrl }
|
|
1320
|
+
options: { apiKey: codexApiKey, baseURL: codexUrl }
|
|
1287
1321
|
};
|
|
1288
1322
|
}
|
|
1289
1323
|
|
|
@@ -1308,15 +1342,21 @@ function writeOpencodeConfig(claudeBaseUrl, codexBaseUrl, apiKey, defaultModelKe
|
|
|
1308
1342
|
} catch { /* 非关键,静默失败 */ }
|
|
1309
1343
|
|
|
1310
1344
|
// ---- 2. ~/.codex/config.toml (opencode 也读此格式) ----
|
|
1311
|
-
const codexDir = path.join(home, '.codex');
|
|
1312
|
-
const codexConfigPath = path.join(codexDir, 'config.toml');
|
|
1313
1345
|
try {
|
|
1314
1346
|
if (!fs.existsSync(codexDir)) fs.mkdirSync(codexDir, { recursive: true });
|
|
1315
1347
|
|
|
1316
|
-
let content =
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1348
|
+
let content = existingCodexToml;
|
|
1349
|
+
const existingOpencodeConfig = fs.existsSync(configPath)
|
|
1350
|
+
? (() => { try { return JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch { return {}; } })()
|
|
1351
|
+
: {};
|
|
1352
|
+
const codexApiKey = String(
|
|
1353
|
+
options.codexApiKey || options.codexKey || options.gptApiKey || options.gptKey || ''
|
|
1354
|
+
).trim()
|
|
1355
|
+
|| readOpenClawProviderApiKey(openClawCodexProviderKey)
|
|
1356
|
+
|| extractTomlProviderBearerToken(existingCodexToml, codexProviderKey)
|
|
1357
|
+
|| String(existingCodexAuth.OPENAI_API_KEY || '').trim()
|
|
1358
|
+
|| String(existingOpencodeConfig.provider?.[codexProviderKey]?.options?.apiKey || '').trim()
|
|
1359
|
+
|| claudeApiKey;
|
|
1320
1360
|
|
|
1321
1361
|
// 移除旧标记块(仅移除 opencode 自己写入的兼容 provider)
|
|
1322
1362
|
content = content.replace(/# >>> yunyi opencode >>>[\s\S]*?# <<< yunyi opencode <<<\n?/g, '');
|
|
@@ -1352,14 +1392,14 @@ function writeOpencodeConfig(claudeBaseUrl, codexBaseUrl, apiKey, defaultModelKe
|
|
|
1352
1392
|
`name = "${brandPrefix} Claude"`,
|
|
1353
1393
|
`base_url = "${claudeUrl}/v1"`,
|
|
1354
1394
|
`wire_api = "anthropic"`,
|
|
1355
|
-
`experimental_bearer_token = "${
|
|
1395
|
+
`experimental_bearer_token = "${claudeApiKey}"`,
|
|
1356
1396
|
...(normalizedCodexTomlUrl ? [
|
|
1357
1397
|
'',
|
|
1358
1398
|
`[model_providers.${codexProviderKey}]`,
|
|
1359
1399
|
`name = "${brandPrefix} Codex"`,
|
|
1360
1400
|
`base_url = "${normalizedCodexTomlUrl}"`,
|
|
1361
1401
|
`wire_api = "responses"`,
|
|
1362
|
-
`experimental_bearer_token = "${
|
|
1402
|
+
`experimental_bearer_token = "${codexApiKey}"`
|
|
1363
1403
|
] : []),
|
|
1364
1404
|
markerEnd
|
|
1365
1405
|
].join('\n');
|
|
@@ -1368,14 +1408,10 @@ function writeOpencodeConfig(claudeBaseUrl, codexBaseUrl, apiKey, defaultModelKe
|
|
|
1368
1408
|
fs.writeFileSync(codexConfigPath, nextContent, 'utf8');
|
|
1369
1409
|
|
|
1370
1410
|
// ---- 3. ~/.codex/auth.json ----
|
|
1371
|
-
const
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1376
|
-
auth.ANTHROPIC_API_KEY = apiKey;
|
|
1377
|
-
auth.OPENAI_API_KEY = apiKey;
|
|
1378
|
-
fs.writeFileSync(authPath, JSON.stringify(auth, null, 2), 'utf8');
|
|
1411
|
+
const auth = { ...existingCodexAuth };
|
|
1412
|
+
auth.ANTHROPIC_API_KEY = claudeApiKey;
|
|
1413
|
+
auth.OPENAI_API_KEY = codexApiKey;
|
|
1414
|
+
fs.writeFileSync(codexAuthPath, JSON.stringify(auth, null, 2), 'utf8');
|
|
1379
1415
|
} catch { /* 非关键,静默失败 */ }
|
|
1380
1416
|
|
|
1381
1417
|
return configPath;
|
|
@@ -3070,21 +3106,30 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
|
|
|
3070
3106
|
ensureConfigStructure(config);
|
|
3071
3107
|
|
|
3072
3108
|
const endpointUrl = inferManagedYunyiEndpointUrl(config, options.endpointUrl);
|
|
3073
|
-
const
|
|
3109
|
+
const sharedApiKey = String(options.apiKey || '').trim();
|
|
3110
|
+
const fallbackApiKey = inferManagedYunyiApiKey(config, sharedApiKey);
|
|
3074
3111
|
if (!endpointUrl) {
|
|
3075
3112
|
return { changed: false, applied: false, claudeAgentId: null, preservedMain: false };
|
|
3076
3113
|
}
|
|
3077
3114
|
|
|
3078
3115
|
let changed = false;
|
|
3079
3116
|
const providers = config.models.providers;
|
|
3080
|
-
|
|
3081
|
-
|
|
3117
|
+
const claudeApiKey = sharedApiKey
|
|
3118
|
+
|| String(options.claudeApiKey || options.claudeKey || '').trim()
|
|
3119
|
+
|| String(providers[YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER]?.apiKey || '').trim()
|
|
3120
|
+
|| fallbackApiKey;
|
|
3121
|
+
const gptApiKey = sharedApiKey
|
|
3122
|
+
|| String(options.codexApiKey || options.codexKey || options.gptApiKey || options.gptKey || '').trim()
|
|
3123
|
+
|| String(providers[YYMAXAPI_OPENCLAW_GPT_PROVIDER]?.apiKey || '').trim()
|
|
3124
|
+
|| fallbackApiKey;
|
|
3125
|
+
|
|
3126
|
+
const nextClaudeProvider = buildManagedYunyiProviderConfig('claude', endpointUrl, claudeApiKey, providers[YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER] || {});
|
|
3082
3127
|
if (JSON.stringify(nextClaudeProvider) !== JSON.stringify(providers[YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER] || {})) {
|
|
3083
3128
|
providers[YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER] = nextClaudeProvider;
|
|
3084
3129
|
changed = true;
|
|
3085
3130
|
}
|
|
3086
3131
|
|
|
3087
|
-
const nextGptProvider = buildManagedYunyiProviderConfig('codex', endpointUrl,
|
|
3132
|
+
const nextGptProvider = buildManagedYunyiProviderConfig('codex', endpointUrl, gptApiKey, providers[YYMAXAPI_OPENCLAW_GPT_PROVIDER] || {});
|
|
3088
3133
|
if (JSON.stringify(nextGptProvider) !== JSON.stringify(providers[YYMAXAPI_OPENCLAW_GPT_PROVIDER] || {})) {
|
|
3089
3134
|
providers[YYMAXAPI_OPENCLAW_GPT_PROVIDER] = nextGptProvider;
|
|
3090
3135
|
changed = true;
|