@aiyiran/myclaw 1.1.114 → 1.1.118

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.
@@ -5,16 +5,11 @@
5
5
  *
6
6
  * 注入 MiniMax 模型配置到 openclaw.json,并为所有 agent 写入 API Key。
7
7
  *
8
- * 做以下事情:
9
- * 1. 设置 minimax auth profile (openclaw.json)
10
- * 2. 注册 minimax provider + 模型定义 (openclaw.json)
11
- * 3. 设置默认聊天模型为 MiniMax (openclaw.json)
12
- * 4. MiniMax 模型加入白名单 (openclaw.json)
13
- * 5. 为所有 agent 写入 API Key (auth-profiles.json,不存在则创建)
14
- *
15
- * 不触碰: 图片模型、其他 provider、onboard 流程
16
- *
17
- * 入口: myclaw inject-minimax [--key sk-xxx]
8
+ * 用法:
9
+ * myclaw inject-minimax # 仅追加 minimax provider,不改默认,副作用最小
10
+ * myclaw inject-minimax --default # 追加 + 设为默认 + 全部对话迁移到 MiniMax-M3
11
+ * myclaw inject-minimax --only # 追加 + 设为默认 + 全部对话迁移 + 清掉所有其他 provider
12
+ * myclaw inject-minimax --key sk-xxx # 使用指定 API Key
18
13
  */
19
14
 
20
15
  const fs = require('fs');
@@ -24,25 +19,33 @@ const { readConfig, writeConfig } = require('../find-config');
24
19
 
25
20
  const DEFAULT_MINIMAX_KEY = "sk-cp-DC5lWd2Stt9CBFzLIT2awP4K-ZEn5AkYwjl3Cdj-mIBmgjxod518F2LaVF2L9c35Wv5-Eox0F1ctJD5vXtB9p3OmxoWLd9ge9zIUIMrCVuqBYdL_s6kb8Qs";
26
21
 
22
+ const PROVIDER_ID = "minimax";
23
+ const DEFAULT_MODEL = "minimax/MiniMax-M3";
24
+
27
25
  function run(cliArgs) {
28
- // 解析参数
26
+ // ── 解析参数 ──
29
27
  let apiKey = null;
30
- let forceDefault = false;
28
+ let setDefault = false;
29
+ let onlyMode = false;
30
+
31
31
  for (let i = 0; i < cliArgs.length; i++) {
32
32
  if (cliArgs[i] === '--key' && cliArgs[i + 1]) {
33
33
  apiKey = cliArgs[i + 1];
34
34
  i++;
35
- } else if (cliArgs[i] === '--force') {
36
- forceDefault = true;
35
+ } else if (cliArgs[i] === '--default') {
36
+ setDefault = true;
37
+ } else if (cliArgs[i] === '--only') {
38
+ onlyMode = true;
39
+ setDefault = true; // --only 隐含 --default
37
40
  }
38
41
  }
39
42
 
40
43
  if (!apiKey) {
41
44
  apiKey = DEFAULT_MINIMAX_KEY;
42
- console.log('💡 未传入 --key 参数,使用默认 API Key');
45
+ console.log('💡 未传入 --key,使用默认 API Key');
43
46
  }
44
47
 
45
- // 读取配置
48
+ // ── 读取配置 ──
46
49
  let config, configPath;
47
50
  try {
48
51
  ({ config, configPath } = readConfig());
@@ -52,16 +55,47 @@ function run(cliArgs) {
52
55
  }
53
56
 
54
57
  console.log('📍 找到配置: ' + configPath);
58
+ console.log('📌 模式: ' + (onlyMode ? '--only (独占)' : setDefault ? '--default (设默认)' : '追加'));
59
+
60
+ // ── Step 1:--only 清掉所有其他 provider ──
61
+ if (onlyMode) {
62
+ console.log('');
63
+ console.log('🧹 [--only] 清理其他所有 provider...');
64
+
65
+ if (config.models?.providers) {
66
+ for (const key of Object.keys(config.models.providers)) {
67
+ if (key !== PROVIDER_ID) {
68
+ delete config.models.providers[key];
69
+ console.log(' ✓ 删除 provider: ' + key);
70
+ }
71
+ }
72
+ }
73
+ if (config.auth?.profiles) {
74
+ for (const key of Object.keys(config.auth.profiles)) {
75
+ if (!key.startsWith(PROVIDER_ID + ':')) {
76
+ delete config.auth.profiles[key];
77
+ console.log(' ✓ 删除 auth profile: ' + key);
78
+ }
79
+ }
80
+ }
81
+ if (config.agents?.defaults?.models) {
82
+ for (const key of Object.keys(config.agents.defaults.models)) {
83
+ if (!key.startsWith(PROVIDER_ID + '/')) {
84
+ delete config.agents.defaults.models[key];
85
+ console.log(' ✓ 删除白名单: ' + key);
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ // ── Step 2:注入 minimax provider 配置 ──
92
+ console.log('');
93
+ console.log('📝 [Step 2] 注入 MiniMax 配置...');
55
94
 
56
- // ─── 1. auth profile ───
57
95
  if (!config.auth) config.auth = {};
58
96
  if (!config.auth.profiles) config.auth.profiles = {};
59
- config.auth.profiles["minimax:cn"] = {
60
- provider: "minimax",
61
- mode: "api_key"
62
- };
97
+ config.auth.profiles["minimax:cn"] = { provider: "minimax", mode: "api_key" };
63
98
 
64
- // ─── 2. minimax provider + 模型定义 ───
65
99
  if (!config.models) config.models = {};
66
100
  if (!config.models.mode) config.models.mode = "merge";
67
101
  if (!config.models.providers) config.models.providers = {};
@@ -76,74 +110,82 @@ function run(cliArgs) {
76
110
  name: "MiniMax M3",
77
111
  reasoning: true,
78
112
  input: ["text"],
79
- cost: {
80
- input: 0.3,
81
- output: 1.2,
82
- cacheRead: 0.06,
83
- cacheWrite: 0.375
84
- },
113
+ cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 },
114
+ contextWindow: 204800,
115
+ maxTokens: 131072
116
+ },
117
+ {
118
+ id: "MiniMax-M2.7-highspeed",
119
+ name: "MiniMax M2.7 Highspeed",
120
+ reasoning: true,
121
+ input: ["text"],
122
+ cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 },
85
123
  contextWindow: 204800,
86
124
  maxTokens: 131072
87
125
  }
88
126
  ]
89
127
  };
90
128
 
91
- // ─── 3. 默认聊天模型 ───
92
129
  if (!config.agents) config.agents = {};
93
130
  if (!config.agents.defaults) config.agents.defaults = {};
94
- if (forceDefault) {
95
- config.agents.defaults.model = {
96
- primary: "minimax/MiniMax-M3"
97
- };
98
- console.log('⚡ --force: 已覆盖默认模型为 minimax/MiniMax-M3');
131
+ if (!config.agents.defaults.models) config.agents.defaults.models = {};
132
+
133
+ // 清理 onboard 残留的无 -highspeed 版本
134
+ delete config.agents.defaults.models["minimax/MiniMax-M2.7"];
135
+ // 白名单:M3 + M2.7-highspeed
136
+ config.agents.defaults.models["minimax/MiniMax-M3"] = {};
137
+ config.agents.defaults.models["minimax/MiniMax-M2.7-highspeed"] = {};
138
+
139
+ // ── Step 3:--default 设默认模型 ──
140
+ if (setDefault) {
141
+ config.agents.defaults.model = { primary: DEFAULT_MODEL };
142
+ console.log('⚡ 默认模型 → ' + DEFAULT_MODEL);
99
143
  } else {
100
- console.log('⊘ 跳过默认模型设置 (传入 --force 可覆盖)');
144
+ console.log('⊘ 未传 --default,保留现有默认模型');
101
145
  }
102
146
 
103
- // ─── 4. 白名单,清理残留 ───
104
- if (!config.agents.defaults.models) config.agents.defaults.models = {};
105
- config.agents.defaults.models["minimax/MiniMax-M3"] = {};
106
- delete config.agents.defaults.models["minimax/MiniMax-M2.7"];
107
- delete config.agents.defaults.models["minimax/MiniMax-M2.7-highspeed"];
147
+ // ── --only 额外清除 per-agent 覆盖 ──
148
+ if (onlyMode) {
149
+ let overrideCount = 0;
150
+ for (const agent of (config.agents.list || [])) {
151
+ if (agent.model && agent.model !== DEFAULT_MODEL) {
152
+ delete agent.model;
153
+ overrideCount++;
154
+ }
155
+ }
156
+ if (overrideCount > 0) console.log('🧹 --only: 已清除 ' + overrideCount + ' 个 agent 的独立 model 覆盖');
157
+ }
108
158
 
109
- // ─── 写入 openclaw.json ───
110
159
  writeConfig(config, configPath);
111
160
  console.log('✅ openclaw.json 已更新');
112
161
 
113
- // ─── 5. 为所有 agent 写入 auth-profiles.json ───
114
- // 始终包含 main agent 默认路径,防止 fresh onboard 后 agents.list 为空
162
+ // ── Step 4:为所有 agent 写入 API Key ──
163
+ console.log('');
164
+ console.log('🔑 [Step 4] 写入 API Key 到所有 agent...');
165
+
115
166
  const DEFAULT_MAIN_DIR = path.join(os.homedir(), '.openclaw', 'agents', 'main', 'agent');
116
167
  const agentList = (config.agents && config.agents.list) || [];
117
168
 
118
- // 构建去重的 agentDir 列表,main 默认路径始终存在
119
169
  const agentDirs = new Map();
120
170
  agentDirs.set(DEFAULT_MAIN_DIR, 'main');
121
171
  for (const agent of agentList) {
122
172
  if (agent.agentDir) agentDirs.set(agent.agentDir, agent.id);
123
173
  }
124
174
 
125
- let okCount = 0;
126
- let skipCount = 0;
175
+ let okCount = 0, skipCount = 0;
127
176
 
128
177
  for (const [agentDir, agentId] of agentDirs) {
129
178
  const profilesPath = path.join(agentDir, 'auth-profiles.json');
130
-
131
- // 读取现有文件,不存在则初始化骨架
132
179
  let profiles = { version: 1, profiles: {}, lastGood: {} };
133
180
  if (fs.existsSync(profilesPath)) {
134
181
  try {
135
182
  const parsed = JSON.parse(fs.readFileSync(profilesPath, 'utf8'));
136
183
  if (parsed.profiles) profiles = parsed;
137
184
  if (!profiles.lastGood) profiles.lastGood = {};
138
- } catch { /* 解析失败则用空骨架 */ }
185
+ } catch { /* 解析失败用空骨架 */ }
139
186
  }
140
187
 
141
- // 写入 minimax:cn,保留其他 profile 不动
142
- profiles.profiles["minimax:cn"] = {
143
- type: "api_key",
144
- provider: "minimax",
145
- key: apiKey
146
- };
188
+ profiles.profiles["minimax:cn"] = { type: "api_key", provider: "minimax", key: apiKey };
147
189
  profiles.lastGood["minimax"] = "minimax:cn";
148
190
 
149
191
  try {
@@ -157,11 +199,46 @@ function run(cliArgs) {
157
199
  }
158
200
  }
159
201
 
202
+ // ── Step 5:--default / --only 迁移全部对话 ──
203
+ if (setDefault) {
204
+ console.log('');
205
+ console.log('🔄 [Step 5] 迁移全部对话 → ' + DEFAULT_MODEL + ' ...');
206
+ let sessionOk = 0, sessionSkip = 0, sessionChanged = 0;
207
+
208
+ for (const [agentDir] of agentDirs) {
209
+ const sessionsPath = path.join(agentDir, '..', 'sessions', 'sessions.json');
210
+ if (!fs.existsSync(sessionsPath)) continue;
211
+ try {
212
+ const sessions = JSON.parse(fs.readFileSync(sessionsPath, 'utf8'));
213
+ let changed = 0;
214
+ for (const key of Object.keys(sessions)) {
215
+ const m = sessions[key]?.model;
216
+ if (!m) continue;
217
+ // 修复无前缀的旧格式残留
218
+ if (m === 'MiniMax-M2.7-highspeed') { sessions[key].model = 'minimax/MiniMax-M3'; changed++; continue; }
219
+ if (m === 'glm-5.1') { sessions[key].model = 'zai/glm-5.1'; changed++; continue; }
220
+ // 统一迁移到新默认
221
+ if (m !== DEFAULT_MODEL) { sessions[key].model = DEFAULT_MODEL; changed++; }
222
+ }
223
+ if (changed > 0) {
224
+ fs.writeFileSync(sessionsPath, JSON.stringify(sessions, null, 2) + '\n', 'utf8');
225
+ sessionChanged += changed;
226
+ }
227
+ sessionOk++;
228
+ } catch {
229
+ sessionSkip++;
230
+ }
231
+ }
232
+ console.log(' 对话迁移: ' + sessionChanged + ' 条,文件: ' + sessionOk + ' 个,跳过: ' + sessionSkip + ' 个');
233
+ }
234
+
235
+ // ── 汇总 ──
160
236
  console.log('');
161
237
  console.log('✅ MiniMax 注入完成');
162
- console.log(' 模型: MiniMax-M3');
163
- console.log(' 默认: minimax/MiniMax-M3');
164
- console.log(' Agent: ' + okCount + ' 个写入,' + skipCount + ' 个跳过');
238
+ console.log(' 默认模型: ' + (setDefault ? DEFAULT_MODEL : '(未修改)'));
239
+ console.log(' 备选模型: minimax/MiniMax-M2.7-highspeed');
240
+ console.log(' Agent: ' + okCount + ' 个写入,' + skipCount + ' 个跳过');
241
+ if (onlyMode) console.log(' 其他 provider 已清除');
165
242
  console.log('');
166
243
  }
167
244
 
@@ -3,14 +3,13 @@
3
3
  /**
4
4
  * inject-zai.js
5
5
  *
6
- * 增量注入智谱 GLM 模型配置到 openclaw.json,不影响已有的其他 provider
7
- * 同时写入 API Key 到 auth-profiles.json。
6
+ * 注入智谱 GLM 模型配置到 openclaw.json,并为所有 agent 写入 API Key
8
7
  *
9
- * 流程:
10
- * 1. 写入 API Key 到 auth-profiles.json
11
- * 2. 增量写入 zai provider + 白名单 + 默认聊天模型
12
- *
13
- * 入口: myclaw zai [--key xxx]
8
+ * 用法:
9
+ * myclaw inject-zai # 仅追加 zai provider,不改默认,副作用最小
10
+ * myclaw inject-zai --default # 追加 + 设为默认 + 全部对话迁移到 glm-5.1
11
+ * myclaw inject-zai --only # 追加 + 设为默认 + 全部对话迁移 + 清掉所有其他 provider
12
+ * myclaw inject-zai --key xxx # 使用指定 API Key
14
13
  */
15
14
 
16
15
  const { readConfig, writeConfig } = require('../find-config');
@@ -18,12 +17,11 @@ const fs = require('fs');
18
17
  const path = require('path');
19
18
  const os = require('os');
20
19
 
21
- // ============================================================
22
- // 默认智谱 API Key
23
- // ============================================================
24
- const DEFAULT_ZAI_KEY = "122435800204471f83045b53aaf5c54e.StwsrQVMlYXkLcJ1";
20
+ const DEFAULT_ZAI_KEY = "a7ae7806dea8406bb85eea5d859c00ad.pVnBuagTz6942JHp";
21
+
22
+ const PROVIDER_ID = "zai";
23
+ const DEFAULT_MODEL = "zai/glm-5.1";
25
24
 
26
- // 智谱模型列表
27
25
  const ZAI_MODELS = [
28
26
  {
29
27
  id: "glm-5.1",
@@ -145,127 +143,79 @@ const ZAI_MODELS = [
145
143
  ];
146
144
 
147
145
  function run(cliArgs) {
148
- // 解析参数
146
+ // ── 解析参数 ──
149
147
  let apiKey = null;
150
- let forceClean = false;
148
+ let setDefault = false;
149
+ let onlyMode = false;
151
150
 
152
151
  for (let i = 0; i < cliArgs.length; i++) {
153
152
  if (cliArgs[i] === '--key' && cliArgs[i + 1]) {
154
153
  apiKey = cliArgs[i + 1];
155
154
  i++;
156
- }
157
- if (cliArgs[i] === '-f' || cliArgs[i] === '--force') {
158
- forceClean = true;
155
+ } else if (cliArgs[i] === '--default') {
156
+ setDefault = true;
157
+ } else if (cliArgs[i] === '--only') {
158
+ onlyMode = true;
159
+ setDefault = true; // --only 隐含 --default
159
160
  }
160
161
  }
161
162
 
162
- // 如果没有传参数,使用默认 Key
163
- if (!apiKey && DEFAULT_ZAI_KEY) {
163
+ if (!apiKey) {
164
164
  apiKey = DEFAULT_ZAI_KEY;
165
- console.log('💡 未传入 --key 参数,自动使用默认的 API Key');
165
+ console.log('💡 未传入 --key,使用默认 API Key');
166
166
  }
167
167
 
168
- // 如果启用了强制清理模式
169
- if (forceClean) {
170
- console.log('');
171
- console.log('🧹 [强制清理] 清理其他大模型配置...');
172
- // 清理 minimax provider
173
- if (config.models?.providers?.minimax) {
174
- delete config.models.providers.minimax;
175
- console.log(' ✓ 已删除 models.providers.minimax');
176
- }
177
- // 清理 minimax auth profile
178
- if (config.auth?.profiles?.['minimax:cn']) {
179
- delete config.auth.profiles['minimax:cn'];
180
- console.log(' ✓ 已删除 auth.profiles["minimax:cn"]');
181
- }
182
- // 清理 minimax 白名单模型
183
- if (config.agents?.defaults?.models) {
184
- const minimaxKeys = Object.keys(config.agents.defaults.models).filter(k => k.startsWith('minimax/'));
185
- for (const key of minimaxKeys) {
186
- delete config.agents.defaults.models[key];
187
- console.log(' ✓ 已删除 agents.defaults.models["' + key + '"]');
188
- }
189
- }
190
- // 如果默认模型是 minimax,清除它
191
- if (config.agents?.defaults?.model?.primary?.startsWith('minimax/')) {
192
- delete config.agents.defaults.model;
193
- console.log(' ✓ 已清除默认模型 (原为 minimax)');
194
- }
195
- // 如果图片模型是 minimax,清除它
196
- if (config.agents?.defaults?.imageGenerationModel?.primary?.startsWith('minimax/')) {
197
- delete config.agents.defaults.imageGenerationModel;
198
- console.log(' ✓ 已删除 agents.defaults.imageGenerationModel');
199
- }
200
- }
201
-
202
- // 查找配置
203
- let configPath;
168
+ // ── 读取配置 ──
169
+ let config, configPath;
204
170
  try {
205
- ({ configPath } = readConfig());
171
+ ({ config, configPath } = readConfig());
206
172
  } catch (err) {
207
173
  console.error('❌ ' + err.message);
208
174
  process.exit(1);
209
175
  }
210
176
 
211
177
  console.log('📍 找到配置: ' + configPath);
178
+ console.log('📌 模式: ' + (onlyMode ? '--only (独占)' : setDefault ? '--default (设默认)' : '追加'));
212
179
 
213
- // ============================================================
214
- // 第一步:写入 API Key 到 auth-profiles.json
215
- // ============================================================
216
-
217
- console.log('');
218
- console.log('🔑 [Step 1] 写入智谱 API Key 到 auth-profiles.json...');
219
-
220
- const authProfilePath = path.join(os.homedir(), '.openclaw', 'agents', 'main', 'agent', 'auth-profiles.json');
221
- let authProfiles = {};
222
-
223
- if (fs.existsSync(authProfilePath)) {
224
- try {
225
- authProfiles = JSON.parse(fs.readFileSync(authProfilePath, 'utf8'));
226
- } catch {
227
- authProfiles = {};
180
+ // ── Step 1:--only 清掉所有其他 provider ──
181
+ if (onlyMode) {
182
+ console.log('');
183
+ console.log('🧹 [--only] 清理其他所有 provider...');
184
+
185
+ if (config.models?.providers) {
186
+ for (const key of Object.keys(config.models.providers)) {
187
+ if (key !== PROVIDER_ID) {
188
+ delete config.models.providers[key];
189
+ console.log(' ✓ 删除 provider: ' + key);
190
+ }
191
+ }
192
+ }
193
+ if (config.auth?.profiles) {
194
+ for (const key of Object.keys(config.auth.profiles)) {
195
+ if (!key.startsWith(PROVIDER_ID + ':')) {
196
+ delete config.auth.profiles[key];
197
+ console.log(' ✓ 删除 auth profile: ' + key);
198
+ }
199
+ }
200
+ }
201
+ if (config.agents?.defaults?.models) {
202
+ for (const key of Object.keys(config.agents.defaults.models)) {
203
+ if (!key.startsWith(PROVIDER_ID + '/')) {
204
+ delete config.agents.defaults.models[key];
205
+ console.log(' ✓ 删除白名单: ' + key);
206
+ }
207
+ }
228
208
  }
229
209
  }
230
210
 
231
- if (!authProfiles.profiles) authProfiles.profiles = {};
232
- if (!authProfiles.lastGood) authProfiles.lastGood = {};
233
-
234
- authProfiles.profiles["zai:default"] = {
235
- type: "api_key",
236
- provider: "zai",
237
- key: apiKey
238
- };
239
- authProfiles.lastGood["zai"] = "zai:default";
240
-
241
- // 确保目录存在
242
- const authDir = path.dirname(authProfilePath);
243
- if (!fs.existsSync(authDir)) {
244
- fs.mkdirSync(authDir, { recursive: true });
245
- }
246
-
247
- fs.writeFileSync(authProfilePath, JSON.stringify(authProfiles, null, 2) + '\n', 'utf8');
248
- console.log(' ✅ API Key 已写入');
249
-
250
- // ============================================================
251
- // 第二步:写入 openclaw.json 配置
252
- // ============================================================
253
-
211
+ // ── Step 2:注入 zai provider 配置 ──
254
212
  console.log('');
255
- console.log('📝 [Step 2] 注入智谱模型配置...');
256
-
257
- // 重新读取(以防 Step 1 期间有变化)
258
- const { config } = readConfig();
213
+ console.log('📝 [Step 2] 注入智谱 GLM 配置...');
259
214
 
260
- // auth profile 声明
261
215
  if (!config.auth) config.auth = {};
262
216
  if (!config.auth.profiles) config.auth.profiles = {};
263
- config.auth.profiles["zai:default"] = {
264
- provider: "zai",
265
- mode: "api_key"
266
- };
217
+ config.auth.profiles["zai:default"] = { provider: "zai", mode: "api_key" };
267
218
 
268
- // models provider
269
219
  if (!config.models) config.models = {};
270
220
  if (!config.models.mode) config.models.mode = "merge";
271
221
  if (!config.models.providers) config.models.providers = {};
@@ -276,31 +226,116 @@ function run(cliArgs) {
276
226
  models: ZAI_MODELS
277
227
  };
278
228
 
279
- // agents 默认配置
280
229
  if (!config.agents) config.agents = {};
281
230
  if (!config.agents.defaults) config.agents.defaults = {};
231
+ if (!config.agents.defaults.models) config.agents.defaults.models = {};
282
232
 
283
- // 默认聊天模型
284
- config.agents.defaults.model = {
285
- primary: "zai/glm-5"
286
- };
233
+ // 白名单:仅 glm-5.1(其余按需选)
234
+ config.agents.defaults.models["zai/glm-5.1"] = {};
287
235
 
288
- // 白名单: 增量添加,不覆盖已有模型
289
- if (!config.agents.defaults.models) config.agents.defaults.models = {};
290
- config.agents.defaults.models["zai/glm-5"] = {};
236
+ // ── Step 3:--default 设默认模型 ──
237
+ if (setDefault) {
238
+ config.agents.defaults.model = { primary: DEFAULT_MODEL };
239
+ console.log('⚡ 默认模型 → ' + DEFAULT_MODEL);
240
+ } else {
241
+ console.log('⊘ 未传 --default,保留现有默认模型');
242
+ }
243
+
244
+ // ── --only 额外清除 per-agent 覆盖 ──
245
+ if (onlyMode) {
246
+ let overrideCount = 0;
247
+ for (const agent of (config.agents.list || [])) {
248
+ if (agent.model && agent.model !== DEFAULT_MODEL) {
249
+ delete agent.model;
250
+ overrideCount++;
251
+ }
252
+ }
253
+ if (overrideCount > 0) console.log('🧹 --only: 已清除 ' + overrideCount + ' 个 agent 的独立 model 覆盖');
254
+ }
291
255
 
292
256
  writeConfig(config, configPath);
257
+ console.log('✅ openclaw.json 已更新');
293
258
 
294
- // 验证写入
295
- const verify = readConfig();
296
- const writtenModelId = verify.config.models?.providers?.zai?.models?.[0]?.id || '???';
297
- const writtenDefault = verify.config.agents?.defaults?.model?.primary || '???';
259
+ // ── Step 4:为所有 agent 写入 API Key ──
260
+ console.log('');
261
+ console.log('🔑 [Step 4] 写入 API Key 到所有 agent...');
298
262
 
299
- console.log(' 配置已注入');
300
- console.log(' [验证] model ID: ' + writtenModelId);
301
- console.log(' [验证] default: ' + writtenDefault);
302
- console.log(' [验证] 模型数量: ' + verify.config.models?.providers?.zai?.models?.length);
263
+ const DEFAULT_MAIN_DIR = path.join(os.homedir(), '.openclaw', 'agents', 'main', 'agent');
264
+ const agentList = (config.agents && config.agents.list) || [];
303
265
 
266
+ const agentDirs = new Map();
267
+ agentDirs.set(DEFAULT_MAIN_DIR, 'main');
268
+ for (const agent of agentList) {
269
+ if (agent.agentDir) agentDirs.set(agent.agentDir, agent.id);
270
+ }
271
+
272
+ let okCount = 0, skipCount = 0;
273
+
274
+ for (const [agentDir, agentId] of agentDirs) {
275
+ const profilesPath = path.join(agentDir, 'auth-profiles.json');
276
+ let profiles = { version: 1, profiles: {}, lastGood: {} };
277
+ if (fs.existsSync(profilesPath)) {
278
+ try {
279
+ const parsed = JSON.parse(fs.readFileSync(profilesPath, 'utf8'));
280
+ if (parsed.profiles) profiles = parsed;
281
+ if (!profiles.lastGood) profiles.lastGood = {};
282
+ } catch { /* 解析失败用空骨架 */ }
283
+ }
284
+
285
+ profiles.profiles["zai:default"] = { type: "api_key", provider: "zai", key: apiKey };
286
+ profiles.lastGood["zai"] = "zai:default";
287
+
288
+ try {
289
+ if (!fs.existsSync(agentDir)) fs.mkdirSync(agentDir, { recursive: true });
290
+ fs.writeFileSync(profilesPath, JSON.stringify(profiles, null, 2) + '\n', 'utf8');
291
+ console.log(' ✅ ' + agentId);
292
+ okCount++;
293
+ } catch (err) {
294
+ console.log(' ⚠ ' + agentId + ': ' + err.message);
295
+ skipCount++;
296
+ }
297
+ }
298
+
299
+ // ── Step 5:--default / --only 迁移全部对话 ──
300
+ if (setDefault) {
301
+ console.log('');
302
+ console.log('🔄 [Step 5] 迁移全部对话 → ' + DEFAULT_MODEL + ' ...');
303
+ let sessionOk = 0, sessionSkip = 0, sessionChanged = 0;
304
+
305
+ for (const [agentDir] of agentDirs) {
306
+ const sessionsPath = path.join(agentDir, '..', 'sessions', 'sessions.json');
307
+ if (!fs.existsSync(sessionsPath)) continue;
308
+ try {
309
+ const sessions = JSON.parse(fs.readFileSync(sessionsPath, 'utf8'));
310
+ let changed = 0;
311
+ for (const key of Object.keys(sessions)) {
312
+ const m = sessions[key]?.model;
313
+ if (!m) continue;
314
+ // 修复无前缀的旧格式残留
315
+ if (m === 'glm-5.1') { sessions[key].model = 'zai/glm-5.1'; changed++; continue; }
316
+ if (m === 'MiniMax-M2.7-highspeed') { sessions[key].model = 'minimax/MiniMax-M3'; changed++; continue; }
317
+ // 统一迁移到新默认
318
+ if (m !== DEFAULT_MODEL) { sessions[key].model = DEFAULT_MODEL; changed++; }
319
+ }
320
+ if (changed > 0) {
321
+ fs.writeFileSync(sessionsPath, JSON.stringify(sessions, null, 2) + '\n', 'utf8');
322
+ sessionChanged += changed;
323
+ }
324
+ sessionOk++;
325
+ } catch {
326
+ sessionSkip++;
327
+ }
328
+ }
329
+ console.log(' 对话迁移: ' + sessionChanged + ' 条,文件: ' + sessionOk + ' 个,跳过: ' + sessionSkip + ' 个');
330
+ }
331
+
332
+ // ── 汇总 ──
333
+ console.log('');
334
+ console.log('✅ GLM 注入完成');
335
+ console.log(' 默认模型: ' + (setDefault ? DEFAULT_MODEL : '(未修改)'));
336
+ console.log(' 模型数量: ' + ZAI_MODELS.length + ' 个可选');
337
+ console.log(' Agent: ' + okCount + ' 个写入,' + skipCount + ' 个跳过');
338
+ if (onlyMode) console.log(' 其他 provider 已清除');
304
339
  console.log('');
305
340
  }
306
341
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiyiran/myclaw",
3
- "version": "1.1.114",
3
+ "version": "1.1.118",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -92,15 +92,12 @@ console.log('📝 [Step 2] 清理 onboard 残留的 MiniMax-M2.7 条目...');
92
92
 
93
93
  const config = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
94
94
 
95
- // onboard 会写入 minimax/MiniMax-M2.7(带 alias),清理掉避免干扰
95
+ // onboard 会写入 minimax/MiniMax-M2.7(无 -highspeed 的 alias),清理掉避免干扰
96
+ // 注意:MiniMax-M2.7-highspeed 保留为备选模型,不删除
96
97
  if (config.agents?.defaults?.models?.["minimax/MiniMax-M2.7"]) {
97
98
  delete config.agents.defaults.models["minimax/MiniMax-M2.7"];
98
99
  console.log(' 🧹 已删除 onboard 残留的 minimax/MiniMax-M2.7');
99
100
  }
100
- if (config.agents?.defaults?.models?.["minimax/MiniMax-M2.7-highspeed"]) {
101
- delete config.agents.defaults.models["minimax/MiniMax-M2.7-highspeed"];
102
- console.log(' 🧹 已删除旧条目 minimax/MiniMax-M2.7-highspeed');
103
- }
104
101
 
105
102
  // ============================================================================
106
103
  // 第三步:写入我们的 JSON 配置(覆盖 onboard 的修改)
@@ -140,6 +137,20 @@ config.models.providers.minimax = {
140
137
  },
141
138
  contextWindow: 204800,
142
139
  maxTokens: 131072
140
+ },
141
+ {
142
+ id: "MiniMax-M2.7-highspeed",
143
+ name: "MiniMax M2.7 Highspeed",
144
+ reasoning: true,
145
+ input: ["text"],
146
+ cost: {
147
+ input: 0.3,
148
+ output: 1.2,
149
+ cacheRead: 0.06,
150
+ cacheWrite: 0.375
151
+ },
152
+ contextWindow: 204800,
153
+ maxTokens: 131072
143
154
  }
144
155
  ]
145
156
  };
@@ -152,9 +163,10 @@ config.agents.defaults.model = {
152
163
  primary: "minimax/MiniMax-M3"
153
164
  };
154
165
 
155
- // 白名单: 增量添加
166
+ // 白名单: M3(默认) + M2.7-highspeed(备选)
156
167
  if (!config.agents.defaults.models) config.agents.defaults.models = {};
157
168
  config.agents.defaults.models["minimax/MiniMax-M3"] = {};
169
+ config.agents.defaults.models["minimax/MiniMax-M2.7-highspeed"] = {};
158
170
 
159
171
  fs.writeFileSync(targetPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
160
172
 
@@ -167,6 +179,41 @@ console.log('✅ 配置已注入');
167
179
  console.log(' [验证] model ID: ' + writtenModelId);
168
180
  console.log(' [验证] default: ' + writtenDefault);
169
181
 
182
+ // ============================================================================
183
+ // 第四步:升级老对话 sessions.json:MiniMax-M2.7-highspeed → MiniMax-M3
184
+ // ============================================================================
185
+
186
+ console.log('');
187
+ console.log('📝 [Step 4] 升级老对话模型 (MiniMax-M2.7-highspeed → MiniMax-M3)...');
188
+
189
+ const agentsDir = path.join(openclawDir, 'agents');
190
+ let sessionOk = 0, sessionSkip = 0;
191
+
192
+ if (fs.existsSync(agentsDir)) {
193
+ for (const agentName of fs.readdirSync(agentsDir)) {
194
+ const sessionsPath = path.join(agentsDir, agentName, 'sessions', 'sessions.json');
195
+ if (!fs.existsSync(sessionsPath)) continue;
196
+ try {
197
+ const sessions = JSON.parse(fs.readFileSync(sessionsPath, 'utf8'));
198
+ let changed = false;
199
+ for (const key of Object.keys(sessions)) {
200
+ if (sessions[key]?.model === 'MiniMax-M2.7-highspeed') {
201
+ sessions[key].model = 'MiniMax-M3';
202
+ changed = true;
203
+ }
204
+ }
205
+ if (changed) {
206
+ fs.writeFileSync(sessionsPath, JSON.stringify(sessions, null, 2) + '\n', 'utf8');
207
+ sessionOk++;
208
+ }
209
+ } catch {
210
+ sessionSkip++;
211
+ }
212
+ }
213
+ }
214
+
215
+ console.log(' sessions.json 更新: ' + sessionOk + ' 个,跳过: ' + sessionSkip + ' 个');
216
+
170
217
  // ============================================================================
171
218
  // 重启 Gateway
172
219
  // ============================================================================