engine7 7.1.43 → 7.1.44

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/dist/cli.mjs CHANGED
@@ -138,6 +138,32 @@ var init_feishu_quick_register = __esm({
138
138
  }
139
139
  });
140
140
 
141
+ // src/qr-render.ts
142
+ var qr_render_exports = {};
143
+ __export(qr_render_exports, {
144
+ renderQrTerminal: () => renderQrTerminal
145
+ });
146
+ import { createRequire } from "node:module";
147
+ async function renderQrTerminal(url, options) {
148
+ return new Promise((resolve2, reject) => {
149
+ try {
150
+ const qt = require2("qrcode-terminal");
151
+ qt.generate(url, { small: options?.small ?? true }, (output) => {
152
+ resolve2(output);
153
+ });
154
+ } catch (err) {
155
+ reject(err);
156
+ }
157
+ });
158
+ }
159
+ var require2;
160
+ var init_qr_render = __esm({
161
+ "src/qr-render.ts"() {
162
+ "use strict";
163
+ require2 = createRequire(import.meta.url);
164
+ }
165
+ });
166
+
141
167
  // src/channels/wechat.ts
142
168
  var wechat_exports = {};
143
169
  __export(wechat_exports, {
@@ -425,20 +451,35 @@ async function wechatQrLogin(options) {
425
451
  console.error("[wechat] QR response missing qrcode field");
426
452
  return null;
427
453
  }
454
+ let pollQrValue = qrcodeValue;
428
455
  const qrScanData = qrcodeUrl || qrcodeValue;
429
- console.log("\n========== \u5FAE\u4FE1\u626B\u7801\u767B\u5F55 ==========");
430
- if (qrcodeUrl) {
431
- console.log(`\u626B\u7801\u94FE\u63A5: ${qrcodeUrl}`);
456
+ try {
457
+ const { renderQrTerminal: renderQrTerminal2 } = await Promise.resolve().then(() => (init_qr_render(), qr_render_exports));
458
+ const qrBlock = await renderQrTerminal2(qrScanData);
459
+ console.log("\n========== \u5FAE\u4FE1\u626B\u7801\u767B\u5F55 ==========");
460
+ if (qrcodeUrl) {
461
+ console.log(`\u626B\u7801\u94FE\u63A5: ${qrcodeUrl}`);
462
+ }
463
+ if (qrBlock) {
464
+ console.log("\u8BF7\u7528\u5FAE\u4FE1\u626B\u63CF\u4EE5\u4E0B\u4E8C\u7EF4\u7801:");
465
+ console.log(qrBlock);
466
+ } else {
467
+ console.log("\u4E8C\u7EF4\u7801\u6E32\u67D3\u5931\u8D25\uFF0C\u8BF7\u7528\u5FAE\u4FE1\u300C\u626B\u4E00\u626B\u300D\u6253\u5F00\u4E0A\u9762\u7684\u94FE\u63A5:");
468
+ }
469
+ console.log("===================================\n");
470
+ } catch {
471
+ console.log("\n========== \u5FAE\u4FE1\u626B\u7801\u767B\u5F55 ==========");
472
+ if (qrcodeUrl) console.log(`\u626B\u7801\u94FE\u63A5: ${qrcodeUrl}`);
473
+ console.log("\u8BF7\u7528\u5FAE\u4FE1\u626B\u63CF\u4E8C\u7EF4\u7801\uFF08\u6216\u6253\u5F00\u4E0A\u9762\u7684\u94FE\u63A5\uFF09:");
474
+ console.log("===================================\n");
432
475
  }
433
- console.log("\u8BF7\u7528\u5FAE\u4FE1\u626B\u63CF\u4E8C\u7EF4\u7801\uFF08\u6216\u6253\u5F00\u4E0A\u9762\u7684\u94FE\u63A5\uFF09:");
434
- console.log("===================================\n");
435
476
  const deadline = Date.now() + timeoutSeconds * 1e3;
436
477
  let currentBaseUrl = ILINK_BASE_URL;
437
478
  let refreshCount = 0;
438
479
  while (Date.now() < deadline) {
439
480
  let statusResp;
440
481
  try {
441
- statusResp = await apiGet(currentBaseUrl, `${EP_GET_QR_STATUS}?qrcode=${qrcodeValue}`, "", QR_TIMEOUT_MS);
482
+ statusResp = await apiGet(currentBaseUrl, `${EP_GET_QR_STATUS}?qrcode=${pollQrValue}`, "", QR_TIMEOUT_MS);
442
483
  } catch {
443
484
  await sleep2(1e3);
444
485
  continue;
@@ -463,7 +504,17 @@ async function wechatQrLogin(options) {
463
504
  qrResp = await apiGet(ILINK_BASE_URL, `${EP_GET_BOT_QR}?bot_type=${botType}`, "", QR_TIMEOUT_MS);
464
505
  const newQrValue = String(qrResp?.qrcode || "");
465
506
  const newQrUrl = String(qrResp?.qrcode_img_content || "");
466
- if (newQrUrl) console.log(`\u65B0\u626B\u7801\u94FE\u63A5: ${newQrUrl}`);
507
+ if (!newQrValue) throw new Error("refresh response missing qrcode");
508
+ pollQrValue = newQrValue;
509
+ console.log("\u65B0\u626B\u7801\u94FE\u63A5:" + (newQrUrl ? ` ${newQrUrl}` : " (\u89C1\u4E0A\u65B9\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u626B)"));
510
+ if (newQrUrl) {
511
+ try {
512
+ const { renderQrTerminal: renderQrTerminal2 } = await Promise.resolve().then(() => (init_qr_render(), qr_render_exports));
513
+ const qrBlock = await renderQrTerminal2(newQrUrl);
514
+ if (qrBlock) console.log(qrBlock);
515
+ } catch {
516
+ }
517
+ }
467
518
  } catch (err) {
468
519
  console.error(`[wechat] QR refresh failed: ${err.message}`);
469
520
  return null;
@@ -484,15 +535,6 @@ async function wechatQrLogin(options) {
484
535
  \u2705 \u5FAE\u4FE1\u767B\u5F55\u6210\u529F!`);
485
536
  console.log(` accountId: ${accountId}`);
486
537
  console.log(` \u51ED\u8BC1\u5DF2\u4FDD\u5B58: ${credFile}`);
487
- console.log(`
488
- \u8BF7\u5C06\u4EE5\u4E0B\u914D\u7F6E\u6DFB\u52A0\u5230 xiaoke.json:`);
489
- console.log(JSON.stringify({
490
- wechat: {
491
- token,
492
- accountId,
493
- baseUrl: baseUrl !== ILINK_BASE_URL ? baseUrl : void 0
494
- }
495
- }, null, 2));
496
538
  return { accountId, token, baseUrl, userId };
497
539
  }
498
540
  await sleep2(1e3);
@@ -1083,32 +1125,6 @@ var init_wechat = __esm({
1083
1125
  }
1084
1126
  });
1085
1127
 
1086
- // src/qr-render.ts
1087
- var qr_render_exports = {};
1088
- __export(qr_render_exports, {
1089
- renderQrTerminal: () => renderQrTerminal
1090
- });
1091
- import { createRequire } from "node:module";
1092
- async function renderQrTerminal(url, options) {
1093
- return new Promise((resolve2, reject) => {
1094
- try {
1095
- const qt = require2("qrcode-terminal");
1096
- qt.generate(url, { small: options?.small ?? true }, (output) => {
1097
- resolve2(output);
1098
- });
1099
- } catch (err) {
1100
- reject(err);
1101
- }
1102
- });
1103
- }
1104
- var require2;
1105
- var init_qr_render = __esm({
1106
- "src/qr-render.ts"() {
1107
- "use strict";
1108
- require2 = createRequire(import.meta.url);
1109
- }
1110
- });
1111
-
1112
1128
  // src/cli-travel.ts
1113
1129
  var cli_travel_exports = {};
1114
1130
  __export(cli_travel_exports, {
@@ -1860,7 +1876,7 @@ async function interactiveConfig(rl, defaults) {
1860
1876
  v.primaryProvider = providerMap[chosenProvider] || "dashscope";
1861
1877
  v.zhipuPlan = "";
1862
1878
  if (v.primaryProvider === "zhipu") {
1863
- const planOptions = ["coding-plan (GLM Coding \u8BA2\u9605)", "token-plan (\u666E\u901A\u6309\u91CF/TokenPlan)"];
1879
+ const planOptions = ["coding-plan (GLM Coding \u8BA2\u9605\uFF0C\u5305\u6708)", "api-pay (API \u6309\u91CF\u4ED8\u8D39)"];
1864
1880
  const chosenPlan = await askChoice(rl, "\u667A\u8C31\u8BA2\u9605\u7C7B\u578B:", planOptions, 0);
1865
1881
  v.zhipuPlan = chosenPlan.startsWith("coding") ? "coding" : "token";
1866
1882
  }
@@ -1874,7 +1890,7 @@ async function interactiveConfig(rl, defaults) {
1874
1890
  const modelMap = {
1875
1891
  dashscope: ["dashscope/qwen3.7-max", "dashscope/qwen3.7-plus"],
1876
1892
  minimax: ["minimax/MiniMax-M3", "minimax/MiniMax-M2.7"],
1877
- zhipu: ["zhipu/glm-5.1", "zhipu/glm-5v-turbo"],
1893
+ zhipu: ["zhipu/glm-5.3", "zhipu/glm-5v-turbo"],
1878
1894
  deepseek: ["deepseek/deepseek-v4-pro", "deepseek/deepseek-v4-flash"]
1879
1895
  };
1880
1896
  const models = modelMap[v.primaryProvider] || ["dashscope/qwen3.7-max"];
@@ -1884,7 +1900,7 @@ async function interactiveConfig(rl, defaults) {
1884
1900
  "dashscope/qwen3.7-plus": true,
1885
1901
  "minimax/MiniMax-M3": true,
1886
1902
  "zhipu/glm-5v-turbo": true,
1887
- "zhipu/glm-5.1": false,
1903
+ "zhipu/glm-5.3": false,
1888
1904
  "deepseek/deepseek-v4-pro": false,
1889
1905
  "deepseek/deepseek-v4-flash": false
1890
1906
  };
@@ -2107,8 +2123,8 @@ function generateConfig(v) {
2107
2123
  baseUrl: "https://open.bigmodel.cn/api/coding/paas/v4",
2108
2124
  api: "openai-completions",
2109
2125
  models: [
2110
- { id: "glm-5.1", name: "GLM-5.1", reasoning: true, input: ["text"], contextWindow: 204800, maxTokens: 131072 },
2111
- { id: "glm-5v-turbo", name: "GLM-5V-Turbo", reasoning: true, input: ["text", "image"], contextWindow: 2e5, maxTokens: 128e3 }
2126
+ { id: "glm-5.3", name: "GLM-5.3 (\u6700\u65B0\u4E3B\u529B)", reasoning: true, input: ["text"], contextWindow: 204800, maxTokens: 131072 },
2127
+ { id: "glm-5v-turbo", name: "GLM-5V-Turbo (\u89C6\u89C9)", reasoning: true, input: ["text", "image"], contextWindow: 2e5, maxTokens: 128e3 }
2112
2128
  ]
2113
2129
  },
2114
2130
  deepseek: {
@@ -2128,7 +2144,8 @@ function generateConfig(v) {
2128
2144
  }
2129
2145
  config.models.providers[v.primaryProvider] = {
2130
2146
  ...def,
2131
- apiKey: v.primaryApiKey
2147
+ apiKey: v.primaryApiKey.trim(),
2148
+ ...def.baseUrl ? { baseUrl: def.baseUrl.trim() } : {}
2132
2149
  };
2133
2150
  }
2134
2151
  return config;
@@ -2298,8 +2315,8 @@ async function main() {
2298
2315
  let stateDir = "";
2299
2316
  let configName = "";
2300
2317
  for (let i = 1; i < args.length; i++) {
2301
- if (args[i] === "--state-dir" && args[i + 1]) stateDir = args[++i];
2302
- else if (args[i] === "--config" && args[i + 1]) configName = args[++i];
2318
+ if (args[i] === "--state-dir" && args[i + 1]) stateDir = args[++i].trim();
2319
+ else if (args[i] === "--config" && args[i + 1]) configName = args[++i].trim();
2303
2320
  }
2304
2321
  if (!stateDir) stateDir = path3.resolve(process.cwd());
2305
2322
  if (!target && !isLegacyAddchannel) {
@@ -2226,9 +2226,19 @@ var init_compact2 = __esm({
2226
2226
  // src/config/live.ts
2227
2227
  var live_exports = {};
2228
2228
  __export(live_exports, {
2229
- liveConfig: () => liveConfig
2229
+ consumeSelfWrite: () => consumeSelfWrite,
2230
+ liveConfig: () => liveConfig,
2231
+ markSelfWrite: () => markSelfWrite
2230
2232
  });
2231
- var LiveConfigClass, liveConfig;
2233
+ function markSelfWrite() {
2234
+ selfWrite.pending = true;
2235
+ }
2236
+ function consumeSelfWrite() {
2237
+ const was = selfWrite.pending;
2238
+ selfWrite.pending = false;
2239
+ return was;
2240
+ }
2241
+ var LiveConfigClass, liveConfig, selfWrite;
2232
2242
  var init_live = __esm({
2233
2243
  "src/config/live.ts"() {
2234
2244
  "use strict";
@@ -2289,6 +2299,7 @@ var init_live = __esm({
2289
2299
  o[keys[keys.length - 1]] = val;
2290
2300
  fs48.writeFileSync(cfgPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
2291
2301
  console.log(`[liveConfig] persisted ${dotPath} = ${JSON.stringify(val)} to ${cfgPath}`);
2302
+ markSelfWrite();
2292
2303
  } catch (e) {
2293
2304
  console.warn(`[liveConfig] persist failed (${dotPath}): ${e.message}`);
2294
2305
  }
@@ -2299,6 +2310,7 @@ var init_live = __esm({
2299
2310
  }
2300
2311
  };
2301
2312
  liveConfig = new LiveConfigClass();
2313
+ selfWrite = { pending: false };
2302
2314
  }
2303
2315
  });
2304
2316
 
@@ -31890,6 +31902,7 @@ function createMemorySideProvider(sideConfig, mainProvider, providers) {
31890
31902
  console.log(`[memory] Side provider: ${sideConfig.provider}/${sideConfig.model} (thinking=${sideConfig.thinking || "default"})`);
31891
31903
  return { provider: sideProvider, model: sideConfig.model, disableThinking };
31892
31904
  }
31905
+ var lastLoadedConfigRaw = null;
31893
31906
  async function doReloadConfig(config, deps, provider) {
31894
31907
  try {
31895
31908
  const savedConfigPath = config._configFilePath;
@@ -31904,7 +31917,17 @@ async function doReloadConfig(config, deps, provider) {
31904
31917
  reloadConfigPath = altPath;
31905
31918
  }
31906
31919
  }
31920
+ let configRaw = "";
31921
+ try {
31922
+ configRaw = fs47.readFileSync(reloadConfigPath, "utf-8");
31923
+ } catch {
31924
+ }
31925
+ if (lastLoadedConfigRaw !== null && configRaw.trim() === lastLoadedConfigRaw) {
31926
+ console.log(`[reload] config content unchanged, skipping reload`);
31927
+ return { ok: true, changes: ["unchanged (skipped)"] };
31928
+ }
31907
31929
  const newConfig = loadConfig(reloadConfigPath);
31930
+ lastLoadedConfigRaw = configRaw.trim();
31908
31931
  const changes = [];
31909
31932
  const oldProviderKey = JSON.stringify({
31910
31933
  providers: config.providers,
@@ -32055,9 +32078,22 @@ function startConfigWatcher(config, deps, provider) {
32055
32078
  return null;
32056
32079
  }
32057
32080
  let debounceTimer = null;
32081
+ try {
32082
+ lastLoadedConfigRaw = fs47.readFileSync(configPath, "utf-8").trim();
32083
+ } catch {
32084
+ }
32058
32085
  const watcher = fs47.watch(configPath, { persistent: true }, (eventType) => {
32059
32086
  if (debounceTimer) clearTimeout(debounceTimer);
32060
32087
  debounceTimer = setTimeout(async () => {
32088
+ if (consumeSelfWrite()) {
32089
+ console.log(`[config-watch] self-write (liveConfig.set, memory already synced), skipping reload`);
32090
+ try {
32091
+ fs47.appendFileSync(path49.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] SELF-WRITE SKIP (liveConfig.set, memory synced)
32092
+ `);
32093
+ } catch {
32094
+ }
32095
+ return;
32096
+ }
32061
32097
  console.log(`[config-watch] file changed (${eventType}), reloading...`);
32062
32098
  try {
32063
32099
  fs47.appendFileSync(path49.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] CHANGE eventType=${eventType}, calling doReloadConfig
package/dist/main.mjs CHANGED
@@ -34,9 +34,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
34
34
  // src/config/live.ts
35
35
  var live_exports = {};
36
36
  __export(live_exports, {
37
- liveConfig: () => liveConfig
37
+ consumeSelfWrite: () => consumeSelfWrite,
38
+ liveConfig: () => liveConfig,
39
+ markSelfWrite: () => markSelfWrite
38
40
  });
39
- var LiveConfigClass, liveConfig;
41
+ function markSelfWrite() {
42
+ selfWrite.pending = true;
43
+ }
44
+ function consumeSelfWrite() {
45
+ const was = selfWrite.pending;
46
+ selfWrite.pending = false;
47
+ return was;
48
+ }
49
+ var LiveConfigClass, liveConfig, selfWrite;
40
50
  var init_live = __esm({
41
51
  "src/config/live.ts"() {
42
52
  "use strict";
@@ -97,6 +107,7 @@ var init_live = __esm({
97
107
  o[keys[keys.length - 1]] = val;
98
108
  fs48.writeFileSync(cfgPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
99
109
  console.log(`[liveConfig] persisted ${dotPath} = ${JSON.stringify(val)} to ${cfgPath}`);
110
+ markSelfWrite();
100
111
  } catch (e) {
101
112
  console.warn(`[liveConfig] persist failed (${dotPath}): ${e.message}`);
102
113
  }
@@ -107,6 +118,7 @@ var init_live = __esm({
107
118
  }
108
119
  };
109
120
  liveConfig = new LiveConfigClass();
121
+ selfWrite = { pending: false };
110
122
  }
111
123
  });
112
124
 
@@ -31974,6 +31986,7 @@ function createMemorySideProvider(sideConfig, mainProvider, providers) {
31974
31986
  console.log(`[memory] Side provider: ${sideConfig.provider}/${sideConfig.model} (thinking=${sideConfig.thinking || "default"})`);
31975
31987
  return { provider: sideProvider, model: sideConfig.model, disableThinking };
31976
31988
  }
31989
+ var lastLoadedConfigRaw = null;
31977
31990
  async function doReloadConfig(config2, deps, provider) {
31978
31991
  try {
31979
31992
  const savedConfigPath = config2._configFilePath;
@@ -31988,7 +32001,17 @@ async function doReloadConfig(config2, deps, provider) {
31988
32001
  reloadConfigPath = altPath;
31989
32002
  }
31990
32003
  }
32004
+ let configRaw = "";
32005
+ try {
32006
+ configRaw = fs47.readFileSync(reloadConfigPath, "utf-8");
32007
+ } catch {
32008
+ }
32009
+ if (lastLoadedConfigRaw !== null && configRaw.trim() === lastLoadedConfigRaw) {
32010
+ console.log(`[reload] config content unchanged, skipping reload`);
32011
+ return { ok: true, changes: ["unchanged (skipped)"] };
32012
+ }
31991
32013
  const newConfig = loadConfig(reloadConfigPath);
32014
+ lastLoadedConfigRaw = configRaw.trim();
31992
32015
  const changes = [];
31993
32016
  const oldProviderKey = JSON.stringify({
31994
32017
  providers: config2.providers,
@@ -32139,9 +32162,22 @@ function startConfigWatcher(config2, deps, provider) {
32139
32162
  return null;
32140
32163
  }
32141
32164
  let debounceTimer = null;
32165
+ try {
32166
+ lastLoadedConfigRaw = fs47.readFileSync(configPath2, "utf-8").trim();
32167
+ } catch {
32168
+ }
32142
32169
  const watcher = fs47.watch(configPath2, { persistent: true }, (eventType) => {
32143
32170
  if (debounceTimer) clearTimeout(debounceTimer);
32144
32171
  debounceTimer = setTimeout(async () => {
32172
+ if (consumeSelfWrite()) {
32173
+ console.log(`[config-watch] self-write (liveConfig.set, memory already synced), skipping reload`);
32174
+ try {
32175
+ fs47.appendFileSync(path49.join(config2.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] SELF-WRITE SKIP (liveConfig.set, memory synced)
32176
+ `);
32177
+ } catch {
32178
+ }
32179
+ return;
32180
+ }
32145
32181
  console.log(`[config-watch] file changed (${eventType}), reloading...`);
32146
32182
  try {
32147
32183
  fs47.appendFileSync(path49.join(config2.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] CHANGE eventType=${eventType}, calling doReloadConfig
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "engine7",
3
- "version": "7.1.43",
3
+ "version": "7.1.44",
4
4
  "type": "module",
5
5
  "description": "Engine 7 — 给助手一个家 / A home for your AI assistant",
6
6
  "main": "dist/main.mjs",