yymaxapi 1.0.87 → 1.0.89
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 +223 -84
- package/package.json +1 -1
package/bin/yymaxapi.js
CHANGED
|
@@ -56,6 +56,20 @@ function safeExec(cmd, options = {}) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
function shouldSuppressProcessWarning(warning) {
|
|
60
|
+
const message = typeof warning === 'string' ? warning : String(warning?.message || '');
|
|
61
|
+
return message.includes("Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0'");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!process.__yymaxapiWarningFilterInstalled && typeof process.emitWarning === 'function') {
|
|
65
|
+
const originalEmitWarning = process.emitWarning.bind(process);
|
|
66
|
+
process.emitWarning = function patchedEmitWarning(warning, ...args) {
|
|
67
|
+
if (shouldSuppressProcessWarning(warning)) return;
|
|
68
|
+
return originalEmitWarning(warning, ...args);
|
|
69
|
+
};
|
|
70
|
+
process.__yymaxapiWarningFilterInstalled = true;
|
|
71
|
+
}
|
|
72
|
+
|
|
59
73
|
// ============ 预设 (由 build.js 从 provider config 生成) ============
|
|
60
74
|
const DEFAULT_ENDPOINTS = [
|
|
61
75
|
{
|
|
@@ -493,41 +507,8 @@ async function validateApiKey(nodeUrl, apiKey) {
|
|
|
493
507
|
try {
|
|
494
508
|
const res = await httpGetJson(verifyUrl, { Authorization: `Bearer ${apiKey}` });
|
|
495
509
|
if (res.status === 200 && res.data) {
|
|
496
|
-
spinner.succeed('API Key
|
|
497
|
-
|
|
498
|
-
// 基本信息
|
|
499
|
-
if (d.service_type) console.log(chalk.gray(` 服务类型: ${d.service_type}`));
|
|
500
|
-
if (d.billing_mode) console.log(chalk.gray(` 计费模式: ${d.billing_mode}`));
|
|
501
|
-
if (d.status && d.status !== 'active') console.log(chalk.yellow(` ⚠ 状态: ${d.status}`));
|
|
502
|
-
// 配额信息
|
|
503
|
-
if (d.total_quota !== undefined || d.remaining_quota !== undefined) {
|
|
504
|
-
const total = d.total_quota || 0;
|
|
505
|
-
const remaining = d.remaining_quota !== undefined ? d.remaining_quota : total;
|
|
506
|
-
const used = total - remaining;
|
|
507
|
-
const pct = total > 0 ? Math.round((used / total) * 100) : 0;
|
|
508
|
-
const barLen = 20;
|
|
509
|
-
const filled = Math.round(barLen * pct / 100);
|
|
510
|
-
const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(barLen - filled));
|
|
511
|
-
console.log(chalk.gray(` 总配额: ${total}`) + (d.max_requests ? chalk.gray(` | 最大请求: ${d.max_requests}`) : ''));
|
|
512
|
-
console.log(chalk.gray(` 已用/剩余: ${used} / ${remaining}`));
|
|
513
|
-
console.log(` [${bar}] ${pct}%`);
|
|
514
|
-
}
|
|
515
|
-
// 每日配额
|
|
516
|
-
if (d.daily_quota !== undefined || d.daily_remaining !== undefined) {
|
|
517
|
-
const dTotal = d.daily_quota || 0;
|
|
518
|
-
const dRemain = d.daily_remaining !== undefined ? d.daily_remaining : dTotal;
|
|
519
|
-
const dUsed = d.daily_used !== undefined ? d.daily_used : (dTotal - dRemain);
|
|
520
|
-
console.log(chalk.gray(` 今日配额: ${dTotal} | 已用: ${dUsed} | 剩余: ${dRemain}`));
|
|
521
|
-
}
|
|
522
|
-
// 有效期
|
|
523
|
-
if (d.activated_at) console.log(chalk.gray(` 激活时间: ${new Date(d.activated_at).toLocaleDateString()}`));
|
|
524
|
-
if (d.expires_at) {
|
|
525
|
-
const exp = new Date(d.expires_at);
|
|
526
|
-
const daysLeft = Math.ceil((exp - Date.now()) / 86400000);
|
|
527
|
-
const expColor = daysLeft <= 7 ? chalk.red : daysLeft <= 30 ? chalk.yellow : chalk.gray;
|
|
528
|
-
console.log(expColor(` 有效期至: ${exp.toLocaleDateString()} (${daysLeft > 0 ? `剩余 ${daysLeft} 天` : '已过期'})`));
|
|
529
|
-
}
|
|
530
|
-
return { valid: true, data: d };
|
|
510
|
+
spinner.succeed('API Key 可用');
|
|
511
|
+
return { valid: true, data: res.data };
|
|
531
512
|
} else {
|
|
532
513
|
spinner.fail('API Key 验证失败');
|
|
533
514
|
console.log(chalk.red(` HTTP ${res.status}`));
|
|
@@ -2030,6 +2011,150 @@ function findAgentById(config, agentId) {
|
|
|
2030
2011
|
return config.agents.list.find(agent => agent && typeof agent === 'object' && agent.id === agentId) || null;
|
|
2031
2012
|
}
|
|
2032
2013
|
|
|
2014
|
+
function canonicalizeManagedYunyiModelKey(modelKey, preferredType = '') {
|
|
2015
|
+
const text = String(modelKey || '').trim();
|
|
2016
|
+
if (!text.includes('/')) return text;
|
|
2017
|
+
const [, modelId = ''] = text.split('/');
|
|
2018
|
+
if (!modelId) return text;
|
|
2019
|
+
if (preferredType === 'claude' || (!preferredType && isManagedYunyiClaudeModelKey(text))) {
|
|
2020
|
+
return `${YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER}/${modelId}`;
|
|
2021
|
+
}
|
|
2022
|
+
if (preferredType === 'codex' || preferredType === 'gpt' || (!preferredType && isManagedYunyiGptModelKey(text))) {
|
|
2023
|
+
return `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/${modelId}`;
|
|
2024
|
+
}
|
|
2025
|
+
return text;
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
function getManagedYunyiKnownModelKeys(type) {
|
|
2029
|
+
return type === 'claude'
|
|
2030
|
+
? [YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY, YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK]
|
|
2031
|
+
: [YYMAXAPI_OPENCLAW_GPT_PRIMARY, YYMAXAPI_OPENCLAW_GPT_FALLBACK];
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
function normalizeManagedYunyiModelState(type, modelState = {}, options = {}) {
|
|
2035
|
+
const knownKeys = getManagedYunyiKnownModelKeys(type);
|
|
2036
|
+
const fallbackPrimary = knownKeys[0];
|
|
2037
|
+
const currentPrimary = canonicalizeManagedYunyiModelKey(modelState.primary || '', type);
|
|
2038
|
+
const canPreserve = !options.force && currentPrimary && knownKeys.includes(currentPrimary);
|
|
2039
|
+
const primary = canPreserve ? currentPrimary : fallbackPrimary;
|
|
2040
|
+
|
|
2041
|
+
let fallbacks = Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
|
|
2042
|
+
fallbacks = [...new Set(
|
|
2043
|
+
fallbacks
|
|
2044
|
+
.map(item => canonicalizeManagedYunyiModelKey(item, type))
|
|
2045
|
+
.filter(item => item && item !== primary && knownKeys.includes(item))
|
|
2046
|
+
)];
|
|
2047
|
+
|
|
2048
|
+
if (fallbacks.length === 0) {
|
|
2049
|
+
fallbacks = knownKeys.filter(item => item !== primary);
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
return { primary, fallbacks };
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
function normalizeManagedYunyiDefaultsModel(modelState = {}, options = {}) {
|
|
2056
|
+
const currentPrimary = String(modelState.primary || '').trim();
|
|
2057
|
+
const canPreserve = !options.force && currentPrimary && isManagedYunyiModelKey(currentPrimary);
|
|
2058
|
+
const primary = canPreserve
|
|
2059
|
+
? canonicalizeManagedYunyiModelKey(currentPrimary)
|
|
2060
|
+
: YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY;
|
|
2061
|
+
|
|
2062
|
+
let fallbacks = Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
|
|
2063
|
+
fallbacks = [...new Set(
|
|
2064
|
+
fallbacks
|
|
2065
|
+
.map(item => {
|
|
2066
|
+
const text = String(item || '').trim();
|
|
2067
|
+
return isManagedYunyiModelKey(text) ? canonicalizeManagedYunyiModelKey(text) : text;
|
|
2068
|
+
})
|
|
2069
|
+
.filter(item => item && item !== primary)
|
|
2070
|
+
)];
|
|
2071
|
+
|
|
2072
|
+
if (fallbacks.length === 0) {
|
|
2073
|
+
fallbacks = [isManagedYunyiClaudeModelKey(primary) ? YYMAXAPI_OPENCLAW_GPT_PRIMARY : YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY];
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
return { primary, fallbacks };
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
function getManagedClaudeAgentId(config) {
|
|
2080
|
+
const mainAgent = findAgentById(config, YYMAXAPI_OPENCLAW_MAIN_AGENT_ID);
|
|
2081
|
+
if (mainAgent && isManagedMainAgent(mainAgent)) {
|
|
2082
|
+
return YYMAXAPI_OPENCLAW_MAIN_AGENT_ID;
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
const sideAgent = findAgentById(config, YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID);
|
|
2086
|
+
if (sideAgent && isManagedClaudeSideAgent(sideAgent)) {
|
|
2087
|
+
return YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
return mainAgent ? YYMAXAPI_OPENCLAW_MAIN_AGENT_ID : (sideAgent ? YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID : null);
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
function inferManagedYunyiAgentIdForModelKey(config, modelKey) {
|
|
2094
|
+
if (isManagedYunyiGptModelKey(modelKey)) return YYMAXAPI_OPENCLAW_GPT_AGENT_ID;
|
|
2095
|
+
if (isManagedYunyiClaudeModelKey(modelKey)) return getManagedClaudeAgentId(config);
|
|
2096
|
+
return null;
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
function applyManagedYunyiModelSelection(config, selectedModelKey) {
|
|
2100
|
+
ensureConfigStructure(config);
|
|
2101
|
+
|
|
2102
|
+
const normalizedSelected = canonicalizeManagedYunyiModelKey(selectedModelKey);
|
|
2103
|
+
const selectedType = isManagedYunyiClaudeModelKey(normalizedSelected)
|
|
2104
|
+
? 'claude'
|
|
2105
|
+
: (isManagedYunyiGptModelKey(normalizedSelected) ? 'codex' : '');
|
|
2106
|
+
|
|
2107
|
+
if (!selectedType) {
|
|
2108
|
+
return { changed: false, selectedModelKey: normalizedSelected, agentId: null };
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
let changed = false;
|
|
2112
|
+
const previousPrimary = String(config.agents?.defaults?.model?.primary || '').trim();
|
|
2113
|
+
const previousCanonical = isManagedYunyiModelKey(previousPrimary)
|
|
2114
|
+
? canonicalizeManagedYunyiModelKey(previousPrimary)
|
|
2115
|
+
: previousPrimary;
|
|
2116
|
+
const nextDefaultsModel = {
|
|
2117
|
+
primary: normalizedSelected,
|
|
2118
|
+
fallbacks: previousCanonical && previousCanonical !== normalizedSelected ? [previousCanonical] : []
|
|
2119
|
+
};
|
|
2120
|
+
|
|
2121
|
+
if (JSON.stringify(config.agents.defaults.model) !== JSON.stringify(nextDefaultsModel)) {
|
|
2122
|
+
config.agents.defaults.model = nextDefaultsModel;
|
|
2123
|
+
changed = true;
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
const managedModelAliases = {
|
|
2127
|
+
[YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY]: YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER,
|
|
2128
|
+
[YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK]: YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER,
|
|
2129
|
+
[YYMAXAPI_OPENCLAW_GPT_PRIMARY]: YYMAXAPI_OPENCLAW_GPT_PROVIDER,
|
|
2130
|
+
[YYMAXAPI_OPENCLAW_GPT_FALLBACK]: YYMAXAPI_OPENCLAW_GPT_PROVIDER
|
|
2131
|
+
};
|
|
2132
|
+
for (const [modelKey, alias] of Object.entries(managedModelAliases)) {
|
|
2133
|
+
const nextEntry = { alias };
|
|
2134
|
+
if (JSON.stringify(config.agents.defaults.models[modelKey] || {}) !== JSON.stringify(nextEntry)) {
|
|
2135
|
+
config.agents.defaults.models[modelKey] = nextEntry;
|
|
2136
|
+
changed = true;
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
const agentId = inferManagedYunyiAgentIdForModelKey(config, normalizedSelected)
|
|
2141
|
+
|| (selectedType === 'codex' ? YYMAXAPI_OPENCLAW_GPT_AGENT_ID : YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID);
|
|
2142
|
+
const agentList = ensureAgentList(config);
|
|
2143
|
+
const nextAgent = {
|
|
2144
|
+
id: agentId,
|
|
2145
|
+
default: agentId === YYMAXAPI_OPENCLAW_MAIN_AGENT_ID,
|
|
2146
|
+
name: selectedType === 'codex' ? 'yunyi-gpt' : 'yunyi-claude',
|
|
2147
|
+
model: normalizeManagedYunyiModelState(selectedType, { primary: normalizedSelected })
|
|
2148
|
+
};
|
|
2149
|
+
const shouldManage = selectedType === 'codex'
|
|
2150
|
+
? isManagedGptAgent
|
|
2151
|
+
: (agentId === YYMAXAPI_OPENCLAW_MAIN_AGENT_ID ? isManagedMainAgent : isManagedClaudeSideAgent);
|
|
2152
|
+
const updateResult = upsertManagedAgent(agentList, nextAgent, shouldManage);
|
|
2153
|
+
if (updateResult.changed) changed = true;
|
|
2154
|
+
|
|
2155
|
+
return { changed, selectedModelKey: normalizedSelected, agentId };
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2033
2158
|
function resolveOpenClawTestTarget(config, args = {}) {
|
|
2034
2159
|
const requestedAgentId = String(args.agent || args['agent-id'] || '').trim();
|
|
2035
2160
|
const requestedAgent = requestedAgentId ? findAgentById(config, requestedAgentId) : null;
|
|
@@ -2046,11 +2171,23 @@ function resolveOpenClawTestTarget(config, args = {}) {
|
|
|
2046
2171
|
if (requestedAgent) {
|
|
2047
2172
|
const agentState = getAgentModelState(requestedAgent);
|
|
2048
2173
|
if (agentState.primary) {
|
|
2049
|
-
primary = agentState.primary;
|
|
2174
|
+
primary = canonicalizeManagedYunyiModelKey(agentState.primary);
|
|
2050
2175
|
fallbacks = agentState.fallbacks;
|
|
2051
2176
|
agentId = requestedAgent.id;
|
|
2052
2177
|
agentName = String(requestedAgent.name || '').trim();
|
|
2053
2178
|
}
|
|
2179
|
+
} else {
|
|
2180
|
+
const inferredAgentId = inferManagedYunyiAgentIdForModelKey(config, primary);
|
|
2181
|
+
const inferredAgent = inferredAgentId ? findAgentById(config, inferredAgentId) : null;
|
|
2182
|
+
if (inferredAgent) {
|
|
2183
|
+
const agentState = getAgentModelState(inferredAgent);
|
|
2184
|
+
if (agentState.primary) {
|
|
2185
|
+
primary = canonicalizeManagedYunyiModelKey(agentState.primary);
|
|
2186
|
+
fallbacks = agentState.fallbacks.map(item => isManagedYunyiModelKey(item) ? canonicalizeManagedYunyiModelKey(item) : item);
|
|
2187
|
+
}
|
|
2188
|
+
agentId = inferredAgent.id;
|
|
2189
|
+
agentName = String(inferredAgent.name || '').trim();
|
|
2190
|
+
}
|
|
2054
2191
|
}
|
|
2055
2192
|
|
|
2056
2193
|
const providerName = primary.includes('/') ? primary.split('/')[0] : '';
|
|
@@ -2312,28 +2449,24 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
|
|
|
2312
2449
|
}
|
|
2313
2450
|
|
|
2314
2451
|
const agentList = ensureAgentList(config);
|
|
2452
|
+
const currentMainAgentState = getAgentModelState(findAgentById(config, YYMAXAPI_OPENCLAW_MAIN_AGENT_ID));
|
|
2315
2453
|
const mainAgentResult = upsertManagedAgent(agentList, {
|
|
2316
2454
|
id: YYMAXAPI_OPENCLAW_MAIN_AGENT_ID,
|
|
2317
2455
|
default: true,
|
|
2318
2456
|
name: 'yunyi-claude',
|
|
2319
|
-
model:
|
|
2320
|
-
primary: YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY,
|
|
2321
|
-
fallbacks: [YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK]
|
|
2322
|
-
}
|
|
2457
|
+
model: normalizeManagedYunyiModelState('claude', currentMainAgentState, options)
|
|
2323
2458
|
}, isManagedMainAgent);
|
|
2324
2459
|
if (mainAgentResult.changed) changed = true;
|
|
2325
2460
|
|
|
2326
2461
|
let claudeAgentId = YYMAXAPI_OPENCLAW_MAIN_AGENT_ID;
|
|
2327
2462
|
let preservedMain = !mainAgentResult.managed;
|
|
2328
2463
|
if (!mainAgentResult.managed) {
|
|
2464
|
+
const currentClaudeSideState = getAgentModelState(findAgentById(config, YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID));
|
|
2329
2465
|
const fallbackClaudeAgentResult = upsertManagedAgent(agentList, {
|
|
2330
2466
|
id: YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID,
|
|
2331
2467
|
default: false,
|
|
2332
2468
|
name: 'yunyi-claude',
|
|
2333
|
-
model:
|
|
2334
|
-
primary: YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY,
|
|
2335
|
-
fallbacks: [YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK]
|
|
2336
|
-
}
|
|
2469
|
+
model: normalizeManagedYunyiModelState('claude', currentClaudeSideState, options)
|
|
2337
2470
|
}, isManagedClaudeSideAgent);
|
|
2338
2471
|
if (fallbackClaudeAgentResult.changed) changed = true;
|
|
2339
2472
|
claudeAgentId = fallbackClaudeAgentResult.managed ? YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID : null;
|
|
@@ -2341,22 +2474,17 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
|
|
|
2341
2474
|
changed = true;
|
|
2342
2475
|
}
|
|
2343
2476
|
|
|
2477
|
+
const currentGptAgentState = getAgentModelState(findAgentById(config, YYMAXAPI_OPENCLAW_GPT_AGENT_ID));
|
|
2344
2478
|
const gptAgentResult = upsertManagedAgent(agentList, {
|
|
2345
2479
|
id: YYMAXAPI_OPENCLAW_GPT_AGENT_ID,
|
|
2346
2480
|
default: false,
|
|
2347
2481
|
name: 'yunyi-gpt',
|
|
2348
|
-
model:
|
|
2349
|
-
primary: YYMAXAPI_OPENCLAW_GPT_PRIMARY,
|
|
2350
|
-
fallbacks: [YYMAXAPI_OPENCLAW_GPT_FALLBACK]
|
|
2351
|
-
}
|
|
2482
|
+
model: normalizeManagedYunyiModelState('codex', currentGptAgentState, options)
|
|
2352
2483
|
}, isManagedGptAgent);
|
|
2353
2484
|
if (gptAgentResult.changed) changed = true;
|
|
2354
2485
|
|
|
2355
2486
|
if (shouldManageYunyiDefaults(config)) {
|
|
2356
|
-
const nextDefaultsModel =
|
|
2357
|
-
primary: YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY,
|
|
2358
|
-
fallbacks: [YYMAXAPI_OPENCLAW_GPT_PRIMARY]
|
|
2359
|
-
};
|
|
2487
|
+
const nextDefaultsModel = normalizeManagedYunyiDefaultsModel(config.agents.defaults.model, options);
|
|
2360
2488
|
if (JSON.stringify(config.agents.defaults.model) !== JSON.stringify(nextDefaultsModel)) {
|
|
2361
2489
|
config.agents.defaults.model = nextDefaultsModel;
|
|
2362
2490
|
changed = true;
|
|
@@ -5116,7 +5244,8 @@ async function switchModel(paths) {
|
|
|
5116
5244
|
|
|
5117
5245
|
const config = ensureConfigStructure(readConfig(paths.openclawConfig) || {});
|
|
5118
5246
|
applyConfigRepairsWithSync(config, paths);
|
|
5119
|
-
|
|
5247
|
+
applyManagedYunyiOpenClawLayout(config);
|
|
5248
|
+
let primary = config.agents?.defaults?.model?.primary || '';
|
|
5120
5249
|
const providers = config.models?.providers || {};
|
|
5121
5250
|
|
|
5122
5251
|
if (Object.keys(providers).length === 0) {
|
|
@@ -5214,6 +5343,7 @@ async function switchModel(paths) {
|
|
|
5214
5343
|
}]);
|
|
5215
5344
|
|
|
5216
5345
|
let finalSelected = selected;
|
|
5346
|
+
let selectedAgentId = '';
|
|
5217
5347
|
|
|
5218
5348
|
if (selected === '__other__') {
|
|
5219
5349
|
if (otherModels.length === 0) {
|
|
@@ -5244,42 +5374,51 @@ async function switchModel(paths) {
|
|
|
5244
5374
|
return;
|
|
5245
5375
|
}
|
|
5246
5376
|
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
const
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
contextWindow:
|
|
5269
|
-
maxTokens:
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5377
|
+
if (isManagedYunyiModelKey(finalSelected)) {
|
|
5378
|
+
const selectionResult = applyManagedYunyiModelSelection(config, finalSelected);
|
|
5379
|
+
finalSelected = selectionResult.selectedModelKey;
|
|
5380
|
+
selectedAgentId = selectionResult.agentId || '';
|
|
5381
|
+
} else {
|
|
5382
|
+
const selectedProviderKey = finalSelected.split('/')[0];
|
|
5383
|
+
const selectedModelId = finalSelected.split('/')[1];
|
|
5384
|
+
config.agents.defaults.model.primary = finalSelected;
|
|
5385
|
+
if (!config.agents.defaults.models[finalSelected]) {
|
|
5386
|
+
config.agents.defaults.models[finalSelected] = { alias: selectedProviderKey };
|
|
5387
|
+
}
|
|
5388
|
+
|
|
5389
|
+
// 同步更新 provider.models
|
|
5390
|
+
const providerConfig = providers[selectedProviderKey];
|
|
5391
|
+
if (providerConfig && selectedModelId) {
|
|
5392
|
+
const existingModel = (providerConfig.models || []).find(m => m.id === selectedModelId);
|
|
5393
|
+
if (!existingModel) {
|
|
5394
|
+
const allModels = [...CLAUDE_MODELS, ...CODEX_MODELS];
|
|
5395
|
+
const knownModel = allModels.find(m => m.id === selectedModelId);
|
|
5396
|
+
const apiType = providerConfig.api || '';
|
|
5397
|
+
const isAnthropic = apiType.startsWith('anthropic');
|
|
5398
|
+
const defaultCtx = isAnthropic ? (API_CONFIG.claude?.contextWindow || 200000) : (API_CONFIG.codex?.contextWindow || 200000);
|
|
5399
|
+
const defaultMax = isAnthropic ? (API_CONFIG.claude?.maxTokens || 8192) : (API_CONFIG.codex?.maxTokens || 8192);
|
|
5400
|
+
providerConfig.models = [{
|
|
5401
|
+
id: selectedModelId,
|
|
5402
|
+
name: knownModel ? knownModel.name : selectedModelId,
|
|
5403
|
+
contextWindow: defaultCtx,
|
|
5404
|
+
maxTokens: defaultMax
|
|
5405
|
+
}];
|
|
5406
|
+
} else {
|
|
5407
|
+
providerConfig.models = [existingModel];
|
|
5408
|
+
}
|
|
5273
5409
|
}
|
|
5274
|
-
}
|
|
5275
5410
|
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5411
|
+
config.agents.defaults.model.fallbacks = (config.agents.defaults.model.fallbacks || []).filter(k => k !== finalSelected);
|
|
5412
|
+
if (primary && primary !== finalSelected && !config.agents.defaults.model.fallbacks.includes(primary)) {
|
|
5413
|
+
config.agents.defaults.model.fallbacks.push(primary);
|
|
5414
|
+
}
|
|
5279
5415
|
}
|
|
5416
|
+
|
|
5417
|
+
primary = finalSelected;
|
|
5280
5418
|
ensureGatewaySettings(config);
|
|
5281
5419
|
writeConfigWithSync(paths, config);
|
|
5282
5420
|
|
|
5421
|
+
const selectedProviderKey = finalSelected.split('/')[0];
|
|
5283
5422
|
const selectedProviderConfig = providers[selectedProviderKey];
|
|
5284
5423
|
const selectedLabel = PROVIDER_LABELS[selectedProviderKey] || selectedProviderKey;
|
|
5285
5424
|
console.log(chalk.green(`\n✅ 已切换到 ${finalSelected}`));
|
|
@@ -5305,7 +5444,7 @@ async function switchModel(paths) {
|
|
|
5305
5444
|
|
|
5306
5445
|
// 重启后直接测试连接
|
|
5307
5446
|
console.log('');
|
|
5308
|
-
await testConnection(paths, {});
|
|
5447
|
+
await testConnection(paths, selectedAgentId ? { agent: selectedAgentId } : {});
|
|
5309
5448
|
}
|
|
5310
5449
|
// ============ 权限管理 (tools.profile) ============
|
|
5311
5450
|
const TOOLS_PROFILES = [
|