yymaxapi 1.0.89 → 1.0.91
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
CHANGED
|
@@ -134,7 +134,7 @@ const DEFAULT_API_CONFIG = {
|
|
|
134
134
|
"codex": {
|
|
135
135
|
"urlSuffix": "/codex",
|
|
136
136
|
"api": "openai-completions",
|
|
137
|
-
"contextWindow":
|
|
137
|
+
"contextWindow": 1000000,
|
|
138
138
|
"maxTokens": 128000,
|
|
139
139
|
"providerName": "yunyi"
|
|
140
140
|
}
|
|
@@ -881,6 +881,7 @@ function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.4') {
|
|
|
881
881
|
if (!normalizedUrl.endsWith('/v1')) normalizedUrl += '/v1';
|
|
882
882
|
try {
|
|
883
883
|
let existing = '';
|
|
884
|
+
const escapedProviderKey = providerKey.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
884
885
|
if (fs.existsSync(configPath)) {
|
|
885
886
|
existing = fs.readFileSync(configPath, 'utf8');
|
|
886
887
|
// 移除旧的 maxapi section(provider block)
|
|
@@ -889,13 +890,14 @@ function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.4') {
|
|
|
889
890
|
// 移除旧的 maxapi top-level block
|
|
890
891
|
const topRe = new RegExp(`${topMarker.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\s\\S]*?${topMarkerEnd.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n?`, 'g');
|
|
891
892
|
existing = existing.replace(topRe, '');
|
|
892
|
-
//
|
|
893
|
-
existing = existing.replace(
|
|
894
|
-
existing = existing.replace(/^model_provider\s*=\s*"[^"]*"\s*$/gm, '');
|
|
893
|
+
// 兼容旧版:移除历史遗留的未标记 yunyi-codex provider、旧 openclaw-relay、旧 yunyi opencode 标记块
|
|
894
|
+
existing = existing.replace(new RegExp(`\\[model_providers\\.${escapedProviderKey}\\]\\n(?:(?!\\[)[^\\n]*\\n?)*`, 'g'), '');
|
|
895
895
|
existing = existing.replace(/\[model_providers\.openclaw-relay\]\n(?:(?!\[)[^\n]*\n?)*/g, '');
|
|
896
896
|
existing = existing.replace(/# >>> yunyi opencode >>>[\s\S]*?# <<< yunyi opencode <<<\n?/g, '');
|
|
897
897
|
existing = existing.replace(/\n{3,}/g, '\n\n').trim();
|
|
898
898
|
}
|
|
899
|
+
const hasExistingTopLevelModelConfig = /^model\s*=\s*"[^"]*"\s*$/m.test(existing)
|
|
900
|
+
|| /^model_provider\s*=\s*"[^"]*"\s*$/m.test(existing);
|
|
899
901
|
|
|
900
902
|
// 顶层设置(MUST 在所有 [section] 之前)
|
|
901
903
|
const topBlock = [
|
|
@@ -919,7 +921,9 @@ function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.4') {
|
|
|
919
921
|
// 组装:顶层设置 → 原有内容 → provider section
|
|
920
922
|
let content;
|
|
921
923
|
if (existing) {
|
|
922
|
-
content =
|
|
924
|
+
content = hasExistingTopLevelModelConfig
|
|
925
|
+
? `${existing}\n\n${providerBlock}\n`
|
|
926
|
+
: `${topBlock}\n\n${existing}\n\n${providerBlock}\n`;
|
|
923
927
|
} else {
|
|
924
928
|
content = `${topBlock}\n\n${providerBlock}\n`;
|
|
925
929
|
}
|
|
@@ -1933,6 +1937,10 @@ const YYMAXAPI_OPENCLAW_GPT_PRIMARY = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.4
|
|
|
1933
1937
|
const YYMAXAPI_OPENCLAW_GPT_FALLBACK = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.3-codex`;
|
|
1934
1938
|
const YYMAXAPI_MANAGED_MAIN_NAMES = new Set(['Claude', 'claude', 'yunyi-claude', 'claude-yunyi']);
|
|
1935
1939
|
const YYMAXAPI_MANAGED_GPT_NAMES = new Set(['GPT', 'Codex', 'gpt', 'yunyi-gpt', 'yunyi-codex']);
|
|
1940
|
+
const YYMAXAPI_MANAGED_MULTIMODAL_MODELS = {
|
|
1941
|
+
claude: new Set(['claude-sonnet-4-6', 'claude-opus-4-6']),
|
|
1942
|
+
codex: new Set(['gpt-5.4', 'gpt-5.3-codex'])
|
|
1943
|
+
};
|
|
1936
1944
|
|
|
1937
1945
|
function isYymaxapiOpenClawBuild() {
|
|
1938
1946
|
return isLikelyYunyiBaseUrl(ENDPOINTS[0]?.url || '')
|
|
@@ -1982,14 +1990,21 @@ function resolveManagedYunyiModelName(type, modelId, fallbackName) {
|
|
|
1982
1990
|
return catalog.find(model => model.id === modelId)?.name || fallbackName;
|
|
1983
1991
|
}
|
|
1984
1992
|
|
|
1993
|
+
function getManagedYunyiModelInput(type, modelId) {
|
|
1994
|
+
return YYMAXAPI_MANAGED_MULTIMODAL_MODELS[type]?.has(modelId)
|
|
1995
|
+
? ['text', 'image']
|
|
1996
|
+
: ['text'];
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1985
1999
|
function getManagedYunyiProviderModels(type) {
|
|
1986
2000
|
const apiConfig = type === 'claude'
|
|
1987
2001
|
? { contextWindow: API_CONFIG.claude?.contextWindow || 200000, maxTokens: API_CONFIG.claude?.maxTokens || 8192 }
|
|
1988
|
-
: { contextWindow: API_CONFIG.codex?.contextWindow ||
|
|
2002
|
+
: { contextWindow: API_CONFIG.codex?.contextWindow || 1000000, maxTokens: API_CONFIG.codex?.maxTokens || 128000 };
|
|
1989
2003
|
|
|
1990
2004
|
return getManagedYunyiModelCatalog(type).map(model => ({
|
|
1991
2005
|
id: model.id,
|
|
1992
2006
|
name: resolveManagedYunyiModelName(type, model.id, model.name),
|
|
2007
|
+
input: getManagedYunyiModelInput(type, model.id),
|
|
1993
2008
|
contextWindow: apiConfig.contextWindow,
|
|
1994
2009
|
maxTokens: apiConfig.maxTokens
|
|
1995
2010
|
}));
|
|
@@ -2389,6 +2404,39 @@ function shouldManageYunyiDefaults(config) {
|
|
|
2389
2404
|
return fallbacks.some(isManagedYunyiModelKey);
|
|
2390
2405
|
}
|
|
2391
2406
|
|
|
2407
|
+
function shouldManageYunyiImageDefaults(config) {
|
|
2408
|
+
const imageModelState = normalizeDefaultModelSelection(config?.agents?.defaults?.imageModel, config);
|
|
2409
|
+
const primary = typeof imageModelState.primary === 'string' ? imageModelState.primary.trim() : '';
|
|
2410
|
+
const fallbacks = Array.isArray(imageModelState.fallbacks) ? imageModelState.fallbacks : [];
|
|
2411
|
+
if (!primary) return true;
|
|
2412
|
+
if (isManagedYunyiModelKey(primary)) return true;
|
|
2413
|
+
return fallbacks.some(isManagedYunyiModelKey);
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
function normalizeManagedYunyiImageModel(modelState = {}, options = {}) {
|
|
2417
|
+
const currentPrimary = String(modelState.primary || '').trim();
|
|
2418
|
+
const canPreserve = !options.force && currentPrimary && isManagedYunyiModelKey(currentPrimary);
|
|
2419
|
+
const primary = canPreserve
|
|
2420
|
+
? canonicalizeManagedYunyiModelKey(currentPrimary)
|
|
2421
|
+
: YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY;
|
|
2422
|
+
|
|
2423
|
+
let fallbacks = Array.isArray(modelState.fallbacks) ? modelState.fallbacks : [];
|
|
2424
|
+
fallbacks = [...new Set(
|
|
2425
|
+
fallbacks
|
|
2426
|
+
.map(item => {
|
|
2427
|
+
const text = String(item || '').trim();
|
|
2428
|
+
return isManagedYunyiModelKey(text) ? canonicalizeManagedYunyiModelKey(text) : text;
|
|
2429
|
+
})
|
|
2430
|
+
.filter(item => item && item !== primary)
|
|
2431
|
+
)];
|
|
2432
|
+
|
|
2433
|
+
if (fallbacks.length === 0) {
|
|
2434
|
+
fallbacks = [isManagedYunyiClaudeModelKey(primary) ? YYMAXAPI_OPENCLAW_GPT_PRIMARY : YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY];
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
return { primary, fallbacks };
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2392
2440
|
function applyManagedYunyiOpenClawLayout(config, options = {}) {
|
|
2393
2441
|
if (!isYymaxapiOpenClawBuild()) {
|
|
2394
2442
|
return { changed: false, applied: false, claudeAgentId: null, preservedMain: false };
|
|
@@ -2491,6 +2539,15 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
|
|
|
2491
2539
|
}
|
|
2492
2540
|
}
|
|
2493
2541
|
|
|
2542
|
+
if (shouldManageYunyiImageDefaults(config)) {
|
|
2543
|
+
const currentImageModel = normalizeDefaultModelSelection(config.agents.defaults.imageModel, config);
|
|
2544
|
+
const nextImageModel = normalizeManagedYunyiImageModel(currentImageModel, options);
|
|
2545
|
+
if (JSON.stringify(currentImageModel) !== JSON.stringify(nextImageModel)) {
|
|
2546
|
+
config.agents.defaults.imageModel = nextImageModel;
|
|
2547
|
+
changed = true;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2494
2551
|
return { changed, applied: true, claudeAgentId, preservedMain };
|
|
2495
2552
|
}
|
|
2496
2553
|
|