yymaxapi 1.0.99 → 1.0.100

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.
Files changed (2) hide show
  1. package/bin/yymaxapi.js +175 -66
  2. package/package.json +1 -1
package/bin/yymaxapi.js CHANGED
@@ -2115,9 +2115,146 @@ function getManagedClaudeAgentId(config) {
2115
2115
  return mainAgent ? YYMAXAPI_OPENCLAW_MAIN_AGENT_ID : (sideAgent ? YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID : null);
2116
2116
  }
2117
2117
 
2118
+ function getManagedYunyiActiveType(config) {
2119
+ const defaultsPrimary = canonicalizeManagedYunyiModelKey(String(config?.agents?.defaults?.model?.primary || '').trim());
2120
+ if (isManagedYunyiClaudeModelKey(defaultsPrimary)) return 'claude';
2121
+ if (isManagedYunyiGptModelKey(defaultsPrimary)) return 'codex';
2122
+
2123
+ const mainState = getAgentModelState(findAgentById(config, YYMAXAPI_OPENCLAW_MAIN_AGENT_ID));
2124
+ const mainPrimary = canonicalizeManagedYunyiModelKey(mainState.primary || '');
2125
+ if (isManagedYunyiClaudeModelKey(mainPrimary)) return 'claude';
2126
+ if (isManagedYunyiGptModelKey(mainPrimary)) return 'codex';
2127
+
2128
+ return 'claude';
2129
+ }
2130
+
2131
+ function findManagedYunyiAgentState(config, type) {
2132
+ const candidateIds = type === 'claude'
2133
+ ? [YYMAXAPI_OPENCLAW_MAIN_AGENT_ID, YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID]
2134
+ : [YYMAXAPI_OPENCLAW_MAIN_AGENT_ID, YYMAXAPI_OPENCLAW_GPT_AGENT_ID, ...YYMAXAPI_OPENCLAW_LEGACY_GPT_AGENT_IDS];
2135
+
2136
+ const matcher = type === 'claude' ? isManagedYunyiClaudeModelKey : isManagedYunyiGptModelKey;
2137
+
2138
+ for (const agentId of candidateIds) {
2139
+ const state = getAgentModelState(findAgentById(config, agentId));
2140
+ const primary = canonicalizeManagedYunyiModelKey(state.primary || '', type);
2141
+ if (matcher(primary)) return state;
2142
+ }
2143
+
2144
+ return {};
2145
+ }
2146
+
2147
+ function getManagedYunyiDesiredPrimaryModelKey(config, type, explicitModelKey = '') {
2148
+ const explicitPrimary = canonicalizeManagedYunyiModelKey(explicitModelKey, type);
2149
+ if (type === 'claude' ? isManagedYunyiClaudeModelKey(explicitPrimary) : isManagedYunyiGptModelKey(explicitPrimary)) {
2150
+ return explicitPrimary;
2151
+ }
2152
+
2153
+ const defaultsPrimary = canonicalizeManagedYunyiModelKey(String(config?.agents?.defaults?.model?.primary || '').trim(), type);
2154
+ if (type === 'claude' ? isManagedYunyiClaudeModelKey(defaultsPrimary) : isManagedYunyiGptModelKey(defaultsPrimary)) {
2155
+ return defaultsPrimary;
2156
+ }
2157
+
2158
+ return '';
2159
+ }
2160
+
2161
+ function resolveManagedYunyiAgentAssignments(config, preferredType = '') {
2162
+ const mainAgent = findAgentById(config, YYMAXAPI_OPENCLAW_MAIN_AGENT_ID);
2163
+ const preservedMain = Boolean(mainAgent) && !isManagedMainAgent(mainAgent);
2164
+ const activeType = preferredType || getManagedYunyiActiveType(config);
2165
+
2166
+ if (preservedMain) {
2167
+ return {
2168
+ preservedMain: true,
2169
+ activeType,
2170
+ mainAgentType: '',
2171
+ claudeAgentId: YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID,
2172
+ gptAgentId: YYMAXAPI_OPENCLAW_GPT_AGENT_ID
2173
+ };
2174
+ }
2175
+
2176
+ return activeType === 'codex'
2177
+ ? {
2178
+ preservedMain: false,
2179
+ activeType,
2180
+ mainAgentType: 'codex',
2181
+ claudeAgentId: YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID,
2182
+ gptAgentId: YYMAXAPI_OPENCLAW_MAIN_AGENT_ID
2183
+ }
2184
+ : {
2185
+ preservedMain: false,
2186
+ activeType: 'claude',
2187
+ mainAgentType: 'claude',
2188
+ claudeAgentId: YYMAXAPI_OPENCLAW_MAIN_AGENT_ID,
2189
+ gptAgentId: YYMAXAPI_OPENCLAW_GPT_AGENT_ID
2190
+ };
2191
+ }
2192
+
2193
+ function syncManagedYunyiAgents(config, options = {}) {
2194
+ ensureConfigStructure(config);
2195
+
2196
+ const assignments = resolveManagedYunyiAgentAssignments(config, options.preferredType);
2197
+ const agentList = ensureAgentList(config);
2198
+ const claudeDesiredPrimary = getManagedYunyiDesiredPrimaryModelKey(config, 'claude', options.selectedModelKey);
2199
+ const gptDesiredPrimary = getManagedYunyiDesiredPrimaryModelKey(config, 'codex', options.selectedModelKey);
2200
+ const claudeState = normalizeManagedYunyiModelState('claude', {
2201
+ ...findManagedYunyiAgentState(config, 'claude'),
2202
+ ...(claudeDesiredPrimary ? { primary: claudeDesiredPrimary } : {})
2203
+ }, options);
2204
+ const gptState = normalizeManagedYunyiModelState('codex', {
2205
+ ...findManagedYunyiAgentState(config, 'codex'),
2206
+ ...(gptDesiredPrimary ? { primary: gptDesiredPrimary } : {})
2207
+ }, options);
2208
+ let changed = false;
2209
+
2210
+ if (!assignments.preservedMain) {
2211
+ const mainType = assignments.mainAgentType === 'codex' ? 'codex' : 'claude';
2212
+ const mainState = mainType === 'codex' ? gptState : claudeState;
2213
+ const mainResult = upsertManagedAgent(agentList, {
2214
+ id: YYMAXAPI_OPENCLAW_MAIN_AGENT_ID,
2215
+ default: true,
2216
+ name: mainType === 'codex' ? 'yunyi-gpt' : 'yunyi-claude',
2217
+ model: mainState
2218
+ }, isManagedMainAgent);
2219
+ if (mainResult.changed) changed = true;
2220
+ }
2221
+
2222
+ if (assignments.claudeAgentId === YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID) {
2223
+ const sideClaudeResult = upsertManagedAgent(agentList, {
2224
+ id: YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID,
2225
+ default: false,
2226
+ name: 'yunyi-claude',
2227
+ model: claudeState
2228
+ }, isManagedClaudeSideAgent);
2229
+ if (sideClaudeResult.changed) changed = true;
2230
+ } else if (removeManagedAgent(agentList, YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID, isManagedClaudeSideAgent)) {
2231
+ changed = true;
2232
+ }
2233
+
2234
+ if (assignments.gptAgentId === YYMAXAPI_OPENCLAW_GPT_AGENT_ID) {
2235
+ const gptResult = upsertManagedAgent(agentList, {
2236
+ id: YYMAXAPI_OPENCLAW_GPT_AGENT_ID,
2237
+ default: false,
2238
+ name: 'yunyi-gpt',
2239
+ model: gptState
2240
+ }, isManagedGptAgent);
2241
+ if (gptResult.changed) changed = true;
2242
+ } else if (removeManagedAgent(agentList, YYMAXAPI_OPENCLAW_GPT_AGENT_ID, isManagedGptAgent)) {
2243
+ changed = true;
2244
+ }
2245
+
2246
+ for (const legacyAgentId of YYMAXAPI_OPENCLAW_LEGACY_GPT_AGENT_IDS) {
2247
+ if (legacyAgentId === YYMAXAPI_OPENCLAW_GPT_AGENT_ID) continue;
2248
+ if (removeManagedAgent(agentList, legacyAgentId, isManagedGptAgent)) changed = true;
2249
+ }
2250
+
2251
+ return { changed, ...assignments };
2252
+ }
2253
+
2118
2254
  function inferManagedYunyiAgentIdForModelKey(config, modelKey) {
2119
- if (isManagedYunyiGptModelKey(modelKey)) return YYMAXAPI_OPENCLAW_GPT_AGENT_ID;
2120
- if (isManagedYunyiClaudeModelKey(modelKey)) return getManagedClaudeAgentId(config);
2255
+ const assignments = resolveManagedYunyiAgentAssignments(config);
2256
+ if (isManagedYunyiGptModelKey(modelKey)) return assignments.gptAgentId;
2257
+ if (isManagedYunyiClaudeModelKey(modelKey)) return assignments.claudeAgentId || getManagedClaudeAgentId(config);
2121
2258
  return null;
2122
2259
  }
2123
2260
 
@@ -2157,20 +2294,15 @@ function applyManagedYunyiModelSelection(config, selectedModelKey) {
2157
2294
  }
2158
2295
  }
2159
2296
 
2160
- const agentId = inferManagedYunyiAgentIdForModelKey(config, normalizedSelected)
2161
- || (selectedType === 'codex' ? YYMAXAPI_OPENCLAW_GPT_AGENT_ID : YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID);
2162
- const agentList = ensureAgentList(config);
2163
- const nextAgent = {
2164
- id: agentId,
2165
- default: agentId === YYMAXAPI_OPENCLAW_MAIN_AGENT_ID,
2166
- name: selectedType === 'codex' ? 'yunyi-gpt' : 'yunyi-claude',
2167
- model: normalizeManagedYunyiModelState(selectedType, { primary: normalizedSelected })
2168
- };
2169
- const shouldManage = selectedType === 'codex'
2170
- ? isManagedGptAgent
2171
- : (agentId === YYMAXAPI_OPENCLAW_MAIN_AGENT_ID ? isManagedMainAgent : isManagedClaudeSideAgent);
2172
- const updateResult = upsertManagedAgent(agentList, nextAgent, shouldManage);
2173
- if (updateResult.changed) changed = true;
2297
+ const syncResult = syncManagedYunyiAgents(config, {
2298
+ preferredType: selectedType,
2299
+ selectedModelKey: normalizedSelected
2300
+ });
2301
+ if (syncResult.changed) changed = true;
2302
+
2303
+ const agentId = selectedType === 'codex'
2304
+ ? syncResult.gptAgentId
2305
+ : syncResult.claudeAgentId;
2174
2306
 
2175
2307
  return { changed, selectedModelKey: normalizedSelected, agentId };
2176
2308
  }
@@ -2544,45 +2676,6 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
2544
2676
  }
2545
2677
  }
2546
2678
 
2547
- const agentList = ensureAgentList(config);
2548
- const currentMainAgentState = getAgentModelState(findAgentById(config, YYMAXAPI_OPENCLAW_MAIN_AGENT_ID));
2549
- const mainAgentResult = upsertManagedAgent(agentList, {
2550
- id: YYMAXAPI_OPENCLAW_MAIN_AGENT_ID,
2551
- default: true,
2552
- name: 'yunyi-claude',
2553
- model: normalizeManagedYunyiModelState('claude', currentMainAgentState, options)
2554
- }, isManagedMainAgent);
2555
- if (mainAgentResult.changed) changed = true;
2556
-
2557
- let claudeAgentId = YYMAXAPI_OPENCLAW_MAIN_AGENT_ID;
2558
- let preservedMain = !mainAgentResult.managed;
2559
- if (!mainAgentResult.managed) {
2560
- const currentClaudeSideState = getAgentModelState(findAgentById(config, YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID));
2561
- const fallbackClaudeAgentResult = upsertManagedAgent(agentList, {
2562
- id: YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID,
2563
- default: false,
2564
- name: 'yunyi-claude',
2565
- model: normalizeManagedYunyiModelState('claude', currentClaudeSideState, options)
2566
- }, isManagedClaudeSideAgent);
2567
- if (fallbackClaudeAgentResult.changed) changed = true;
2568
- claudeAgentId = fallbackClaudeAgentResult.managed ? YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID : null;
2569
- } else if (removeManagedAgent(agentList, YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID, isManagedClaudeSideAgent)) {
2570
- changed = true;
2571
- }
2572
-
2573
- const currentGptAgentState = getAgentModelState(findAgentById(config, YYMAXAPI_OPENCLAW_GPT_AGENT_ID));
2574
- const gptAgentResult = upsertManagedAgent(agentList, {
2575
- id: YYMAXAPI_OPENCLAW_GPT_AGENT_ID,
2576
- default: false,
2577
- name: 'yunyi-gpt',
2578
- model: normalizeManagedYunyiModelState('codex', currentGptAgentState, options)
2579
- }, isManagedGptAgent);
2580
- if (gptAgentResult.changed) changed = true;
2581
- for (const legacyAgentId of YYMAXAPI_OPENCLAW_LEGACY_GPT_AGENT_IDS) {
2582
- if (legacyAgentId === YYMAXAPI_OPENCLAW_GPT_AGENT_ID) continue;
2583
- if (removeManagedAgent(agentList, legacyAgentId, isManagedGptAgent)) changed = true;
2584
- }
2585
-
2586
2679
  if (shouldManageYunyiDefaults(config)) {
2587
2680
  const nextDefaultsModel = normalizeManagedYunyiDefaultsModel(config.agents.defaults.model, options);
2588
2681
  if (JSON.stringify(config.agents.defaults.model) !== JSON.stringify(nextDefaultsModel)) {
@@ -2604,14 +2697,26 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
2604
2697
  changed = true;
2605
2698
  }
2606
2699
 
2607
- return { changed, applied: true, claudeAgentId, preservedMain };
2700
+ const syncResult = syncManagedYunyiAgents(config, options);
2701
+ if (syncResult.changed) changed = true;
2702
+
2703
+ return {
2704
+ changed,
2705
+ applied: true,
2706
+ claudeAgentId: syncResult.claudeAgentId,
2707
+ gptAgentId: syncResult.gptAgentId,
2708
+ preservedMain: syncResult.preservedMain,
2709
+ mainAgentType: syncResult.mainAgentType
2710
+ };
2608
2711
  }
2609
2712
 
2610
2713
  function printYunyiOpenClawSwitchHint(result = {}) {
2611
2714
  if (!result?.applied) return;
2612
2715
  const summary = result.preservedMain && result.claudeAgentId === YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID
2613
2716
  ? 'OpenClaw: main 已保留, Claude=yunyi-claude, GPT=yunyi-gpt'
2614
- : 'OpenClaw: main=yunyi-claude, GPT=yunyi-gpt';
2717
+ : (result.mainAgentType === 'codex'
2718
+ ? 'OpenClaw: main=yunyi-gpt, Claude=yunyi-claude'
2719
+ : 'OpenClaw: main=yunyi-claude, GPT=yunyi-gpt');
2615
2720
  console.log(chalk.cyan(` ${summary}`));
2616
2721
  }
2617
2722
 
@@ -4628,7 +4733,10 @@ async function autoActivate(paths, args = {}) {
4628
4733
  endpointUrl: selectedEndpoint.url,
4629
4734
  apiKey
4630
4735
  });
4631
- applyManagedYunyiModelSelection(config, primaryModelKey);
4736
+ const selectionResult = applyManagedYunyiModelSelection(config, primaryModelKey);
4737
+ const finalYunyiLayoutResult = yunyiLayoutResult.applied
4738
+ ? { ...yunyiLayoutResult, ...resolveManagedYunyiAgentAssignments(config, selectedType), applied: true }
4739
+ : yunyiLayoutResult;
4632
4740
 
4633
4741
  // ---- 写入配置 ----
4634
4742
  const writeSpinner = ora({ text: '正在写入配置...', spinner: 'dots' }).start();
@@ -4641,10 +4749,10 @@ async function autoActivate(paths, args = {}) {
4641
4749
  if (yunyiLayoutResult.applied) {
4642
4750
  syncManagedYunyiAuthProfiles(paths, config);
4643
4751
  }
4644
- if (!isClaudePrimary) {
4645
- const resetResult = resetManagedAgentSessionsWithSync(paths, YYMAXAPI_OPENCLAW_GPT_AGENT_ID);
4752
+ if (selectionResult.agentId) {
4753
+ const resetResult = resetManagedAgentSessionsWithSync(paths, selectionResult.agentId);
4646
4754
  if (resetResult.changed) {
4647
- console.log(chalk.gray(` 已重置 ${YYMAXAPI_OPENCLAW_GPT_AGENT_ID} 的活动会话映射`));
4755
+ console.log(chalk.gray(` 已重置 ${selectionResult.agentId} 的活动会话映射`));
4648
4756
  }
4649
4757
  }
4650
4758
  const opencodeDefaultModelKey = isClaudePrimary ? `yunyi-claude/${claudeModelId}` : `yunyi-codex/${codexModelId}`;
@@ -4656,7 +4764,7 @@ async function autoActivate(paths, args = {}) {
4656
4764
  const selectedModel = isClaudePrimary ? claudeModel : codexModel;
4657
4765
  console.log(chalk.green('\n✅ 配置完成!'));
4658
4766
  console.log(chalk.cyan(` 外部工具默认: ${selectedModel.name}`));
4659
- printYunyiOpenClawSwitchHint(yunyiLayoutResult);
4767
+ printYunyiOpenClawSwitchHint(finalYunyiLayoutResult);
4660
4768
 
4661
4769
  const gwPort = config.gateway?.port || 18789;
4662
4770
  const gwToken = config.gateway?.auth?.token;
@@ -4677,9 +4785,10 @@ async function autoActivate(paths, args = {}) {
4677
4785
  }]);
4678
4786
 
4679
4787
  if (nextAction === 'test') {
4680
- const selectedOpenClawAgentId = isClaudePrimary
4681
- ? (yunyiLayoutResult.claudeAgentId || YYMAXAPI_OPENCLAW_MAIN_AGENT_ID)
4682
- : YYMAXAPI_OPENCLAW_GPT_AGENT_ID;
4788
+ const selectedOpenClawAgentId = selectionResult.agentId
4789
+ || (isClaudePrimary
4790
+ ? (finalYunyiLayoutResult.claudeAgentId || YYMAXAPI_OPENCLAW_MAIN_AGENT_ID)
4791
+ : (finalYunyiLayoutResult.gptAgentId || YYMAXAPI_OPENCLAW_GPT_AGENT_ID));
4683
4792
  await testConnection(paths, { ...args, agent: selectedOpenClawAgentId });
4684
4793
  } else {
4685
4794
  console.log(chalk.cyan('👋 再见!\n'));
@@ -5619,7 +5728,7 @@ async function switchModel(paths) {
5619
5728
  primary = finalSelected;
5620
5729
  ensureGatewaySettings(config);
5621
5730
  writeConfigWithSync(paths, config);
5622
- if (selectedAgentId === YYMAXAPI_OPENCLAW_GPT_AGENT_ID) {
5731
+ if (selectedAgentId && [YYMAXAPI_OPENCLAW_MAIN_AGENT_ID, YYMAXAPI_OPENCLAW_ALT_CLAUDE_AGENT_ID, YYMAXAPI_OPENCLAW_GPT_AGENT_ID].includes(selectedAgentId)) {
5623
5732
  const resetResult = resetManagedAgentSessionsWithSync(paths, selectedAgentId);
5624
5733
  if (resetResult.changed) {
5625
5734
  console.log(chalk.gray(` 已重置 ${selectedAgentId} 的活动会话映射`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yymaxapi",
3
- "version": "1.0.99",
3
+ "version": "1.0.100",
4
4
  "description": "跨平台 OpenClaw/Clawdbot 配置管理工具 - 管理中转地址、模型切换、API Keys、测速优化",
5
5
  "main": "bin/yymaxapi.js",
6
6
  "bin": {