yymaxapi 1.0.97 → 1.0.99

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
@@ -23,6 +23,8 @@ $env:OPENCLAW_CLAUDE_KEY="你的Key"; npx yymaxapi@latest preset-claude
23
23
  set OPENCLAW_CLAUDE_KEY=你的Key && npx yymaxapi@latest preset-claude
24
24
  ```
25
25
 
26
+ 说明:`preset-claude` 现在只写 Claude Code CLI 自身配置,不会改动 OpenClaw、Codex CLI、Opencode。
27
+
26
28
  **方式三:一键配置 Codex**
27
29
  ```bash
28
30
  # macOS/Linux
@@ -38,22 +40,22 @@ set OPENCLAW_CODEX_KEY=你的Key && npx yymaxapi@latest preset-codex
38
40
  **方式四:完全自动化(无交互)**
39
41
  ```bash
40
42
  # macOS/Linux
41
- OPENCLAW_CLAUDE_KEY="你的Key" npx yymaxapi@latest preset-claude --model claude-opus-4-5 --set-primary true --force --test true
43
+ OPENCLAW_CLAUDE_KEY="你的Key" npx yymaxapi@latest preset-claude --model claude-opus-4-6 --set-primary true --force --test true
42
44
 
43
45
  # Windows PowerShell
44
- $env:OPENCLAW_CLAUDE_KEY="你的Key"; npx yymaxapi@latest preset-claude --model claude-opus-4-5 --set-primary true --force --test true
46
+ $env:OPENCLAW_CLAUDE_KEY="你的Key"; npx yymaxapi@latest preset-claude --model claude-opus-4-6 --set-primary true --force --test true
45
47
 
46
48
  # Windows CMD
47
- set OPENCLAW_CLAUDE_KEY=你的Key && npx yymaxapi@latest preset-claude --model claude-opus-4-5 --set-primary true --force --test true
49
+ set OPENCLAW_CLAUDE_KEY=你的Key && npx yymaxapi@latest preset-claude --model claude-opus-4-6 --set-primary true --force --test true
48
50
 
49
51
  # macOS/Linux
50
- OPENCLAW_CODEX_KEY="你的Key" npx yymaxapi@latest preset-codex --model gpt-5.2 --set-primary true --force --test true
52
+ OPENCLAW_CODEX_KEY="你的Key" npx yymaxapi@latest preset-codex --model gpt-5.4 --set-primary true --force --test true
51
53
 
52
54
  # Windows PowerShell
53
- $env:OPENCLAW_CODEX_KEY="你的Key"; npx yymaxapi@latest preset-codex --model gpt-5.2 --set-primary true --force --test true
55
+ $env:OPENCLAW_CODEX_KEY="你的Key"; npx yymaxapi@latest preset-codex --model gpt-5.4 --set-primary true --force --test true
54
56
 
55
57
  # Windows CMD
56
- set OPENCLAW_CODEX_KEY=你的Key && npx yymaxapi@latest preset-codex --model gpt-5.2 --set-primary true --force --test true
58
+ set OPENCLAW_CODEX_KEY=你的Key && npx yymaxapi@latest preset-codex --model gpt-5.4 --set-primary true --force --test true
57
59
  ```
58
60
 
59
61
  ## 重要说明
package/bin/yymaxapi.js CHANGED
@@ -108,7 +108,11 @@ const DEFAULT_CLAUDE_MODELS = [
108
108
  },
109
109
  {
110
110
  "id": "claude-opus-4-6",
111
- "name": "Claude Opus 4.6 (待稳定)"
111
+ "name": "Claude Opus 4.6"
112
+ },
113
+ {
114
+ "id": "claude-opus-4-6-thinking",
115
+ "name": "Claude Opus 4.6 Thinking"
112
116
  }
113
117
  ];
114
118
 
@@ -829,82 +833,23 @@ function writeConfig(configPath, config) {
829
833
  // ============ 多工具配置同步 ============
830
834
 
831
835
  function writeClaudeCodeSettings(baseUrl, apiKey, modelId = getDefaultClaudeModel().id) {
832
- const home = os.homedir();
833
836
  // ~/.claude/settings.json
834
- const claudeDir = path.join(home, '.claude');
835
- const settingsPath = path.join(claudeDir, 'settings.json');
837
+ const settingsPath = getClaudeCodeSettingsPath();
838
+ const claudeDir = path.dirname(settingsPath);
836
839
  try {
837
840
  let settings = {};
838
841
  if (fs.existsSync(settingsPath)) {
839
842
  try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch { settings = {}; }
840
843
  }
841
844
  settings.apiBaseUrl = baseUrl.replace(/\/+$/, '');
842
- settings.model = modelId;
843
- settings.availableModels = CLAUDE_MODELS.map(model => model.id);
844
845
  if (!settings.env) settings.env = {};
845
- settings.env.ANTHROPIC_BASE_URL = baseUrl.replace(/\/+$/, '');
846
846
  settings.env.ANTHROPIC_AUTH_TOKEN = apiKey;
847
- settings.env.ANTHROPIC_MODEL = modelId;
847
+ delete settings.availableModels;
848
+ delete settings.env.ANTHROPIC_BASE_URL;
849
+ delete settings.env.ANTHROPIC_MODEL;
848
850
  if (!fs.existsSync(claudeDir)) fs.mkdirSync(claudeDir, { recursive: true });
849
851
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
850
852
  } catch { /* 非关键,静默失败 */ }
851
-
852
- // ~/.claude.json — 跳过 onboarding
853
- const claudeJsonPath = path.join(home, '.claude.json');
854
- try {
855
- let claudeJson = {};
856
- if (fs.existsSync(claudeJsonPath)) {
857
- try { claudeJson = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf8')); } catch { claudeJson = {}; }
858
- }
859
- if (!claudeJson.hasCompletedOnboarding) {
860
- claudeJson.hasCompletedOnboarding = true;
861
- fs.writeFileSync(claudeJsonPath, JSON.stringify(claudeJson, null, 2), 'utf8');
862
- }
863
- } catch { /* 非关键,静默失败 */ }
864
-
865
- // 写入 shell 环境变量
866
- if (process.platform === 'win32') {
867
- try {
868
- const cleanUrl = baseUrl.replace(/\/+$/, '');
869
- execSync(
870
- `powershell -NoProfile -Command "[Environment]::SetEnvironmentVariable('ANTHROPIC_BASE_URL','${cleanUrl}','User'); [Environment]::SetEnvironmentVariable('ANTHROPIC_AUTH_TOKEN','${apiKey}','User'); [Environment]::SetEnvironmentVariable('ANTHROPIC_MODEL','${modelId}','User')"`,
871
- { stdio: 'pipe' }
872
- );
873
- } catch { /* best-effort */ }
874
- } else {
875
- const marker = '# >>> yymaxapi claude >>>';
876
- const markerEnd = '# <<< yymaxapi claude <<<';
877
- const cleanUrl = baseUrl.replace(/\/+$/, '');
878
- // 只持久化工具本身需要的 Claude 变量,TLS 放宽只能留在进程内临时使用。
879
- const block = [
880
- marker,
881
- `export ANTHROPIC_BASE_URL="${cleanUrl}"`,
882
- `export ANTHROPIC_AUTH_TOKEN="${apiKey}"`,
883
- `export ANTHROPIC_MODEL="${modelId}"`,
884
- markerEnd
885
- ].join('\n');
886
-
887
- const shellEnv = process.env.SHELL || '';
888
- const rcFiles = [];
889
- if (shellEnv.includes('zsh') || !shellEnv) rcFiles.push(path.join(home, '.zshrc'));
890
- if (shellEnv.includes('bash') || !shellEnv) rcFiles.push(path.join(home, '.bashrc'));
891
- if (rcFiles.length === 0) rcFiles.push(path.join(home, '.profile'));
892
-
893
- for (const rcFile of rcFiles) {
894
- try {
895
- let content = '';
896
- if (fs.existsSync(rcFile)) {
897
- content = fs.readFileSync(rcFile, 'utf8');
898
- const re = new RegExp(
899
- `${marker.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\s\\S]*?${markerEnd.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n?`,
900
- 'g'
901
- );
902
- content = content.replace(re, '').trimEnd();
903
- }
904
- fs.writeFileSync(rcFile, content ? `${content}\n\n${block}\n` : `${block}\n`, 'utf8');
905
- } catch { /* best-effort */ }
906
- }
907
- }
908
853
  }
909
854
 
910
855
  function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.4') {
@@ -1995,7 +1940,7 @@ const YYMAXAPI_OPENCLAW_GPT_FALLBACK = `${YYMAXAPI_OPENCLAW_GPT_PROVIDER}/gpt-5.
1995
1940
  const YYMAXAPI_MANAGED_MAIN_NAMES = new Set(['Claude', 'claude', 'yunyi-claude', 'claude-yunyi']);
1996
1941
  const YYMAXAPI_MANAGED_GPT_NAMES = new Set(['GPT', 'Codex', 'gpt', 'yunyi-gpt', 'yunyi-codex']);
1997
1942
  const YYMAXAPI_MANAGED_MULTIMODAL_MODELS = {
1998
- claude: new Set(['claude-sonnet-4-6', 'claude-opus-4-6']),
1943
+ claude: new Set(['claude-sonnet-4-6', 'claude-opus-4-6', 'claude-opus-4-6-thinking']),
1999
1944
  codex: new Set(['gpt-5.4', 'gpt-5.3-codex'])
2000
1945
  };
2001
1946
 
@@ -2031,15 +1976,9 @@ function stripManagedYunyiSuffix(baseUrl) {
2031
1976
 
2032
1977
  function getManagedYunyiModelCatalog(type) {
2033
1978
  if (type === 'claude') {
2034
- return [
2035
- { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6' },
2036
- { id: 'claude-opus-4-6', name: 'Claude Opus 4.6' }
2037
- ];
1979
+ return CLAUDE_MODELS;
2038
1980
  }
2039
- return [
2040
- { id: 'gpt-5.4', name: 'GPT 5.4' },
2041
- { id: 'gpt-5.3-codex', name: 'GPT 5.3 Codex' }
2042
- ];
1981
+ return CODEX_MODELS;
2043
1982
  }
2044
1983
 
2045
1984
  function resolveManagedYunyiModelName(type, modelId, fallbackName) {
@@ -2097,15 +2036,29 @@ function canonicalizeManagedYunyiModelKey(modelKey, preferredType = '') {
2097
2036
  return text;
2098
2037
  }
2099
2038
 
2039
+ function getManagedYunyiProviderName(type) {
2040
+ return type === 'claude' ? YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER : YYMAXAPI_OPENCLAW_GPT_PROVIDER;
2041
+ }
2042
+
2043
+ function getManagedYunyiDefaultPrimaryModelKey(type) {
2044
+ return type === 'claude' ? YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY : YYMAXAPI_OPENCLAW_GPT_PRIMARY;
2045
+ }
2046
+
2100
2047
  function getManagedYunyiKnownModelKeys(type) {
2101
- return type === 'claude'
2102
- ? [YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY, YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK]
2103
- : [YYMAXAPI_OPENCLAW_GPT_PRIMARY, YYMAXAPI_OPENCLAW_GPT_FALLBACK];
2048
+ const providerName = getManagedYunyiProviderName(type);
2049
+ return getManagedYunyiModelCatalog(type).map(model => `${providerName}/${model.id}`);
2050
+ }
2051
+
2052
+ function getManagedYunyiModelAliasEntries() {
2053
+ return {
2054
+ ...Object.fromEntries(getManagedYunyiKnownModelKeys('claude').map(modelKey => [modelKey, YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER])),
2055
+ ...Object.fromEntries(getManagedYunyiKnownModelKeys('codex').map(modelKey => [modelKey, YYMAXAPI_OPENCLAW_GPT_PROVIDER]))
2056
+ };
2104
2057
  }
2105
2058
 
2106
2059
  function normalizeManagedYunyiModelState(type, modelState = {}, options = {}) {
2107
2060
  const knownKeys = getManagedYunyiKnownModelKeys(type);
2108
- const fallbackPrimary = knownKeys[0];
2061
+ const fallbackPrimary = knownKeys[0] || getManagedYunyiDefaultPrimaryModelKey(type);
2109
2062
  const currentPrimary = canonicalizeManagedYunyiModelKey(modelState.primary || '', type);
2110
2063
  const canPreserve = !options.force && currentPrimary && knownKeys.includes(currentPrimary);
2111
2064
  const primary = canPreserve ? currentPrimary : fallbackPrimary;
@@ -2195,12 +2148,7 @@ function applyManagedYunyiModelSelection(config, selectedModelKey) {
2195
2148
  changed = true;
2196
2149
  }
2197
2150
 
2198
- const managedModelAliases = {
2199
- [YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY]: YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER,
2200
- [YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK]: YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER,
2201
- [YYMAXAPI_OPENCLAW_GPT_PRIMARY]: YYMAXAPI_OPENCLAW_GPT_PROVIDER,
2202
- [YYMAXAPI_OPENCLAW_GPT_FALLBACK]: YYMAXAPI_OPENCLAW_GPT_PROVIDER
2203
- };
2151
+ const managedModelAliases = getManagedYunyiModelAliasEntries();
2204
2152
  for (const [modelKey, alias] of Object.entries(managedModelAliases)) {
2205
2153
  const nextEntry = { alias };
2206
2154
  if (JSON.stringify(config.agents.defaults.models[modelKey] || {}) !== JSON.stringify(nextEntry)) {
@@ -2587,12 +2535,7 @@ function applyManagedYunyiOpenClawLayout(config, options = {}) {
2587
2535
  }
2588
2536
 
2589
2537
  const defaultsModels = config.agents.defaults.models;
2590
- const managedModelAliases = {
2591
- [YYMAXAPI_OPENCLAW_CLAUDE_PRIMARY]: YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER,
2592
- [YYMAXAPI_OPENCLAW_CLAUDE_FALLBACK]: YYMAXAPI_OPENCLAW_CLAUDE_PROVIDER,
2593
- [YYMAXAPI_OPENCLAW_GPT_PRIMARY]: YYMAXAPI_OPENCLAW_GPT_PROVIDER,
2594
- [YYMAXAPI_OPENCLAW_GPT_FALLBACK]: YYMAXAPI_OPENCLAW_GPT_PROVIDER
2595
- };
2538
+ const managedModelAliases = getManagedYunyiModelAliasEntries();
2596
2539
  for (const [modelKey, alias] of Object.entries(managedModelAliases)) {
2597
2540
  const nextEntry = { alias };
2598
2541
  if (JSON.stringify(defaultsModels[modelKey] || {}) !== JSON.stringify(nextEntry)) {
@@ -4817,9 +4760,8 @@ async function activateClaudeCode(paths, args = {}) {
4817
4760
  console.log(chalk.gray(' API Key: 已设置'));
4818
4761
  console.log(chalk.gray('\n 已写入:'));
4819
4762
  console.log(chalk.gray(' • ~/.claude/settings.json'));
4820
- console.log(chalk.gray(' • ~/.claude.json (跳过 onboarding)'));
4821
- console.log(chalk.gray(' shell 环境变量 (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_MODEL)'));
4822
- console.log(chalk.yellow('\n 提示: 请重新打开终端或执行 source ~/.zshrc 使环境变量生效'));
4763
+ console.log(chalk.gray(' • 最小字段: apiBaseUrl + env.ANTHROPIC_AUTH_TOKEN'));
4764
+ console.log(chalk.yellow('\n 提示: 如果 Claude Code 已在运行,重新打开一个会话即可读取新配置'));
4823
4765
 
4824
4766
  if (await confirmImmediateTest(args, '是否立即测试 Claude Code CLI 连接?')) {
4825
4767
  await testAdditionalCliConnections(args, { only: ['claude'] });
@@ -5200,7 +5142,7 @@ async function main() {
5200
5142
  return;
5201
5143
  }
5202
5144
  if (args.preset === 'claude' || args._.includes('preset-claude') || args._.includes('claude-preset')) {
5203
- await autoActivate(paths, { ...args, primary: 'claude' });
5145
+ await activateClaudeCode(paths, args);
5204
5146
  return;
5205
5147
  }
5206
5148
  if (args.preset === 'codex' || args._.includes('preset-codex') || args._.includes('codex-preset')) {
@@ -25,7 +25,8 @@
25
25
  "models": {
26
26
  "claude": [
27
27
  { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6" },
28
- { "id": "claude-opus-4-6", "name": "Claude Opus 4.6 (待稳定)" }
28
+ { "id": "claude-opus-4-6", "name": "Claude Opus 4.6" },
29
+ { "id": "claude-opus-4-6-thinking", "name": "Claude Opus 4.6 Thinking" }
29
30
  ],
30
31
  "codex": [
31
32
  { "id": "gpt-5.4", "name": "GPT 5.4" },
@@ -103,7 +104,7 @@ npx yymaxapi@latest
103
104
 
104
105
  **注意事项:**
105
106
  - `base_url` 不要加 `/v1`,平台会自动拼接路径
106
- - Claude 可用模型:`claude-sonnet-4-6`、`claude-opus-4-6`
107
+ - Claude 可用模型:`claude-sonnet-4-6`、`claude-opus-4-6`、`claude-opus-4-6-thinking`
107
108
  - GPT 可用模型:`gpt-5.4`
108
109
  - 已验证环境:腾讯云 OpenCloudOS,OpenClaw `2026.2.3-1`
109
110
  - 参考文档:https://cloud.tencent.com/developer/article/2624003
@@ -148,21 +149,20 @@ npx yymaxapi@latest
148
149
 
149
150
  **2. Claude Code CLI(本机终端)**
150
151
 
151
- 在终端执行一次,或写入 `~/.zshrc` / `~/.bashrc` 后 `source`,Claude Code 即走云翼 Claude:
152
+ 推荐直接写 `settings.json` 最小配置:
152
153
 
153
- ```bash
154
- export ANTHROPIC_BASE_URL="https://yunyi.rdzhvip.com/claude"
155
- export ANTHROPIC_AUTH_TOKEN="<你的云翼 API Key>"
156
- # 若遇证书报错可加:
157
- export NODE_TLS_REJECT_UNAUTHORIZED=0
154
+ ```json
155
+ {
156
+ "apiBaseUrl": "https://yunyi.rdzhvip.com/claude",
157
+ "env": {
158
+ "ANTHROPIC_AUTH_TOKEN": "<你的云翼 API Key>"
159
+ }
160
+ }
158
161
  ```
159
162
 
160
- Windows(PowerShell,用户级环境变量):
163
+ 文件位置:
161
164
 
162
- ```powershell
163
- [Environment]::SetEnvironmentVariable('ANTHROPIC_BASE_URL', 'https://yunyi.rdzhvip.com/claude', 'User')
164
- [Environment]::SetEnvironmentVariable('ANTHROPIC_AUTH_TOKEN', '<你的云翼 API Key>', 'User')
165
- [Environment]::SetEnvironmentVariable('NODE_TLS_REJECT_UNAUTHORIZED', '0', 'User')
166
- ```
165
+ - macOS / Linux:`~/.claude/settings.json`
166
+ - Windows:`%USERPROFILE%\\.claude\\settings.json`
167
167
 
168
168
  完成后:腾讯云 OpenClaw 里可选 Claude 或 GPT;本机 Claude Code CLI 使用同一 Key 走云翼 Claude。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yymaxapi",
3
- "version": "1.0.97",
3
+ "version": "1.0.99",
4
4
  "description": "跨平台 OpenClaw/Clawdbot 配置管理工具 - 管理中转地址、模型切换、API Keys、测速优化",
5
5
  "main": "bin/yymaxapi.js",
6
6
  "bin": {