@zhushanwen/zcode-subagent-cli 0.6.0 → 0.8.0

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/index.cjs CHANGED
@@ -46,7 +46,7 @@ __export(src_exports, {
46
46
  module.exports = __toCommonJS(src_exports);
47
47
 
48
48
  // src/server.ts
49
- var import_subagent_engine_sdk14 = require("@zhushanwen/subagent-engine-sdk");
49
+ var import_subagent_engine_sdk15 = require("@zhushanwen/subagent-engine-sdk");
50
50
 
51
51
  // src/constants.ts
52
52
  var ZCODE_ENGINE_ID = "zcode";
@@ -82,13 +82,13 @@ var ZCODE_RESUME_CHARS_PER_TOKEN = 4;
82
82
  var ZCODE_SESSION_SWEEP_DEFER_MS = 50;
83
83
 
84
84
  // src/registration.ts
85
- var import_subagent_engine_sdk12 = require("@zhushanwen/subagent-engine-sdk");
85
+ var import_subagent_engine_sdk13 = require("@zhushanwen/subagent-engine-sdk");
86
86
 
87
87
  // src/zcode-engine.ts
88
88
  var fs6 = __toESM(require("fs"), 1);
89
89
  var path4 = __toESM(require("path"), 1);
90
- var import_subagent_engine_sdk10 = require("@zhushanwen/subagent-engine-sdk");
91
90
  var import_subagent_engine_sdk11 = require("@zhushanwen/subagent-engine-sdk");
91
+ var import_subagent_engine_sdk12 = require("@zhushanwen/subagent-engine-sdk");
92
92
 
93
93
  // src/journal-io.ts
94
94
  var import_subagent_engine_sdk = require("@zhushanwen/subagent-engine-sdk");
@@ -159,6 +159,7 @@ function synthesizeCoarseEvents(response, usage) {
159
159
  var fs = __toESM(require("fs"), 1);
160
160
  var os2 = __toESM(require("os"), 1);
161
161
  var path2 = __toESM(require("path"), 1);
162
+ var import_subagent_engine_sdk4 = require("@zhushanwen/subagent-engine-sdk");
162
163
  var ZcodePrepareError = class extends Error {
163
164
  code;
164
165
  constructor(code, message) {
@@ -167,35 +168,81 @@ var ZcodePrepareError = class extends Error {
167
168
  this.code = code;
168
169
  }
169
170
  };
171
+ var TAIJI_SYNC_GUIDANCE = "\u82E5\u4F7F\u7528 taiji \u540C\u6B65\u526F\u672C/\u9ED8\u8BA4\u6A21\u578B\uFF0C\u5230 taiji settings \u6838\u5BF9\u6216\u91CD\u9009\uFF0C\u91CD\u542F taiji \u751F\u6548\u3002";
170
172
  function isRecord(v) {
171
173
  return typeof v === "object" && v !== null && !Array.isArray(v);
172
174
  }
173
175
  function strArray(v) {
174
176
  return Array.isArray(v) ? v.filter((m) => typeof m === "string" && m.trim() !== "") : [];
175
177
  }
176
- function readSourceConfig(absPath) {
177
- const empty = { providers: /* @__PURE__ */ new Map(), order: [] };
178
+ function readSourceJsonOrUndefined(absPath) {
178
179
  let raw;
179
180
  try {
180
181
  raw = fs.readFileSync(absPath, "utf8");
181
182
  } catch {
182
- return empty;
183
+ return void 0;
183
184
  }
184
- let parsed;
185
185
  try {
186
- parsed = JSON.parse(raw);
186
+ return JSON.parse(raw);
187
187
  } catch {
188
- return empty;
189
- }
190
- if (!isRecord(parsed)) return empty;
191
- const rules = parsed["config"]?.["providerConfigRules"];
192
- const providerRules = !isRecord(rules) ? void 0 : rules["providerRules"];
193
- const orderSrc = parsed["config"]?.["providerOrder"];
194
- const conf = { providers: /* @__PURE__ */ new Map(), order: strArray(orderSrc) };
195
- if (!Array.isArray(providerRules)) return conf;
196
- collectProviderRules(providerRules, conf);
188
+ return void 0;
189
+ }
190
+ }
191
+ function extractSourceConfig(parsed) {
192
+ const conf = { providers: /* @__PURE__ */ new Map(), order: [] };
193
+ if (!isRecord(parsed)) return conf;
194
+ const config = parsed["config"];
195
+ if (!isRecord(config)) return conf;
196
+ conf.order = strArray(config["providerOrder"]);
197
+ const rules = config["providerConfigRules"];
198
+ const providerRules = isRecord(rules) ? rules["providerRules"] : void 0;
199
+ if (Array.isArray(providerRules)) collectProviderRules(providerRules, conf);
197
200
  return conf;
198
201
  }
202
+ function readSourceConfig(absPath) {
203
+ return extractSourceConfig(readSourceJsonOrUndefined(absPath));
204
+ }
205
+ function mergePersonalProviderConfig(realObj, copyObj) {
206
+ if (!isRecord(copyObj)) return realObj;
207
+ if (!isRecord(realObj)) return copyObj;
208
+ const cfgOf = (obj) => isRecord(obj["config"]) ? obj["config"] : {};
209
+ const rulesOf = (obj) => {
210
+ const pcr = cfgOf(obj)["providerConfigRules"];
211
+ const rules = isRecord(pcr) ? pcr["providerRules"] : void 0;
212
+ return Array.isArray(rules) ? rules : [];
213
+ };
214
+ const mergedRules = [];
215
+ const seen = /* @__PURE__ */ new Set();
216
+ for (const rule of rulesOf(realObj)) {
217
+ mergedRules.push(rule);
218
+ if (isRecord(rule)) {
219
+ const id = rule["providerId"];
220
+ if (typeof id === "string" && id !== "") seen.add(id);
221
+ }
222
+ }
223
+ for (const rule of rulesOf(copyObj)) {
224
+ if (!isRecord(rule)) continue;
225
+ const id = rule["providerId"];
226
+ if (typeof id !== "string" || id === "") continue;
227
+ if (seen.has(id)) continue;
228
+ seen.add(id);
229
+ mergedRules.push(rule);
230
+ }
231
+ const mergedOrder = [];
232
+ for (const id of [...strArray(cfgOf(realObj)["providerOrder"]), ...strArray(cfgOf(copyObj)["providerOrder"])]) {
233
+ if (!mergedOrder.includes(id)) mergedOrder.push(id);
234
+ }
235
+ const realCfg = cfgOf(realObj);
236
+ const realPcr = isRecord(realCfg["providerConfigRules"]) ? realCfg["providerConfigRules"] : {};
237
+ return {
238
+ ...realObj,
239
+ config: {
240
+ ...realCfg,
241
+ providerOrder: mergedOrder,
242
+ providerConfigRules: { ...realPcr, providerRules: mergedRules }
243
+ }
244
+ };
245
+ }
199
246
  function collectProviderRules(providerRules, conf) {
200
247
  for (const rule of providerRules) {
201
248
  if (!isRecord(rule)) continue;
@@ -230,6 +277,40 @@ function defaultPersonalProviderConfigPath() {
230
277
  function defaultV2ConfigPath() {
231
278
  return path2.join(os2.homedir(), ...ZCODE_V2_CONFIG_PATH_SUFFIX);
232
279
  }
280
+ function piSyncedProviderConfigPath(engineDataDir) {
281
+ return path2.join(engineDataDir, ...import_subagent_engine_sdk4.ZCODE_PI_SYNCED_PROVIDER_CONFIG_SEGMENTS);
282
+ }
283
+ function envEngineDataDirOrUndefined() {
284
+ try {
285
+ return (0, import_subagent_engine_sdk4.resolveEngineDataDir)(process.env);
286
+ } catch {
287
+ return void 0;
288
+ }
289
+ }
290
+ function resolvePersonalProviderSource(sources, engineDataDir) {
291
+ const explicit = sources?.personalProviderConfigPath;
292
+ if (explicit !== void 0) return { kind: "explicit", path: explicit };
293
+ const dataDir = engineDataDir ?? envEngineDataDirOrUndefined();
294
+ if (dataDir !== void 0 && fs.existsSync(piSyncedProviderConfigPath(dataDir))) {
295
+ return { kind: "copy", path: piSyncedProviderConfigPath(dataDir), realPath: defaultPersonalProviderConfigPath() };
296
+ }
297
+ return { kind: "real", path: defaultPersonalProviderConfigPath() };
298
+ }
299
+ function resolvePersonalProviderConfigPath(sources, engineDataDir) {
300
+ return resolvePersonalProviderSource(sources, engineDataDir).path;
301
+ }
302
+ function readPersonalProviderView(sources) {
303
+ const resolution = resolvePersonalProviderSource(sources);
304
+ if (resolution.kind !== "copy") {
305
+ return { conf: readSourceConfig(resolution.path), sourceDesc: resolution.path };
306
+ }
307
+ const copyJson = readSourceJsonOrUndefined(resolution.path);
308
+ const realJson = readSourceJsonOrUndefined(resolution.realPath);
309
+ return {
310
+ conf: extractSourceConfig(mergePersonalProviderConfig(realJson, copyJson)),
311
+ sourceDesc: `merge(\u771F\u5B9E ${resolution.realPath} + \u526F\u672C ${resolution.path})`
312
+ };
313
+ }
233
314
  var SEMVER_SEGMENTS = 3;
234
315
  function locateZcodeBuiltinCatalog(sources) {
235
316
  if (sources?.builtinCatalogPath !== void 0) return sources.builtinCatalogPath;
@@ -276,21 +357,6 @@ function locateZcodeBuiltinCatalog(sources) {
276
357
  }
277
358
  return void 0;
278
359
  }
279
- function resolveZcodeMinimalReasoningLevel(modelRef, sources) {
280
- const catalogPath = locateZcodeBuiltinCatalog(sources);
281
- if (catalogPath === void 0) return void 0;
282
- let parsed;
283
- try {
284
- parsed = JSON.parse(fs.readFileSync(catalogPath, "utf8"));
285
- } catch {
286
- return void 0;
287
- }
288
- const modelId = modelShort(modelRef);
289
- const rules = parsed["config"];
290
- const modelRules = isRecord(rules) && isRecord(rules["modelConfigRules"]) ? rules["modelConfigRules"]["modelRules"] : void 0;
291
- if (!Array.isArray(modelRules)) return void 0;
292
- return lastMatchingReasoningValues(modelRules, modelId)?.[0];
293
- }
294
360
  function lastMatchingReasoningValues(modelRules, modelId) {
295
361
  let values;
296
362
  for (const rule of modelRules) {
@@ -299,7 +365,7 @@ function lastMatchingReasoningValues(modelRules, modelId) {
299
365
  if (typeof match !== "string") continue;
300
366
  let re;
301
367
  try {
302
- re = new RegExp(match);
368
+ re = new RegExp(match, "i");
303
369
  } catch {
304
370
  continue;
305
371
  }
@@ -311,6 +377,21 @@ function lastMatchingReasoningValues(modelRules, modelId) {
311
377
  }
312
378
  return values;
313
379
  }
380
+ function resolveZcodeReasoningValues(modelRef, sources) {
381
+ const catalogPath = locateZcodeBuiltinCatalog(sources);
382
+ if (catalogPath === void 0) return void 0;
383
+ let parsed;
384
+ try {
385
+ parsed = JSON.parse(fs.readFileSync(catalogPath, "utf8"));
386
+ } catch {
387
+ return void 0;
388
+ }
389
+ const modelId = modelShort(modelRef);
390
+ const rules = parsed["config"];
391
+ const modelRules = isRecord(rules) && isRecord(rules["modelConfigRules"]) ? rules["modelConfigRules"]["modelRules"] : void 0;
392
+ if (!Array.isArray(modelRules)) return void 0;
393
+ return lastMatchingReasoningValues(modelRules, modelId);
394
+ }
314
395
  function defaultProviderForShortName(conf, withKey) {
315
396
  const ordered = conf.order.find((id) => {
316
397
  const entry = conf.providers.get(id);
@@ -319,19 +400,65 @@ function defaultProviderForShortName(conf, withKey) {
319
400
  if (ordered !== void 0) return ordered;
320
401
  return withKey[0][0];
321
402
  }
403
+ function resolveAccountModelRef(wanted, wantedProvider, sources) {
404
+ const catalogPath = locateZcodeBuiltinCatalog(sources);
405
+ if (catalogPath === void 0) {
406
+ throw new ZcodePrepareError(
407
+ "model_not_available",
408
+ `account \u6A21\u578B "${wanted}" \u65E0\u6CD5\u6821\u9A8C\uFF1A\u5185\u5EFA\u76EE\u5F55\u5B9A\u4F4D\u5931\u8D25\uFF08ZCODE_BUILTIN_PROVIDER_CONFIG_FILE \u4E0E runtime/provider \u626B\u63CF\u5747\u672A\u547D\u4E2D\uFF09\u3002`
409
+ );
410
+ }
411
+ let catalog;
412
+ try {
413
+ catalog = JSON.parse(fs.readFileSync(catalogPath, "utf8"));
414
+ } catch (err) {
415
+ throw new ZcodePrepareError(
416
+ "model_not_available",
417
+ `account \u6A21\u578B "${wanted}" \u65E0\u6CD5\u6821\u9A8C\uFF1A\u5185\u5EFA\u76EE\u5F55\u4E0D\u53EF\u8BFB\uFF08${err instanceof Error ? err.message : String(err)}\uFF09\u3002`
418
+ );
419
+ }
420
+ const accountRule = findAccountProviderRule(catalog, wantedProvider);
421
+ if (accountRule === void 0) {
422
+ throw new ZcodePrepareError(
423
+ "model_not_available",
424
+ `\u672A\u77E5 account provider "${wantedProvider}"\uFF08\u5185\u5EFA\u76EE\u5F55\u65E0\u6B64\u89C4\u5219\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u76EE\u5F55\u5185 account:* \u89C4\u5219\uFF08\u5982 account:zai-individual-coding-plan / account:bigmodel-individual-coding-plan\uFF09\u3002`
425
+ );
426
+ }
427
+ assertAccountModelKnown(accountRule, wanted, wantedProvider);
428
+ return wanted;
429
+ }
430
+ function findAccountProviderRule(catalog, wantedProvider) {
431
+ const catalogRules = isRecord(catalog) && isRecord(catalog["config"]) && isRecord(catalog["config"]["providerConfigRules"]) ? catalog["config"]["providerConfigRules"]["providerRules"] : void 0;
432
+ const accountRule = Array.isArray(catalogRules) ? catalogRules.find((r) => isRecord(r) && r["providerId"] === wantedProvider) : void 0;
433
+ return isRecord(accountRule) ? accountRule : void 0;
434
+ }
435
+ function assertAccountModelKnown(accountRule, wanted, wantedProvider) {
436
+ const accountConfig = isRecord(accountRule["config"]) ? accountRule["config"] : {};
437
+ const modelIds = accountConfig["builtinModelIds"] ?? accountConfig["personalModelIds"];
438
+ const short = modelShort(wanted);
439
+ if (Array.isArray(modelIds) && modelIds.length > 0 && !modelIds.includes(short)) {
440
+ throw new ZcodePrepareError(
441
+ "model_not_available",
442
+ `\u672A\u77E5\u6A21\u578B "${short}"\uFF08account provider ${wantedProvider} \u4E0B\u53EF\u7528: ${modelIds.join(", ")}\uFF09\u3002`
443
+ );
444
+ }
445
+ }
322
446
  function resolveZcodeModelRef(requested, sources) {
323
- const srcPath = sources?.personalProviderConfigPath ?? defaultPersonalProviderConfigPath();
324
- const conf = readSourceConfig(srcPath);
447
+ const { conf, sourceDesc } = readPersonalProviderView(sources);
325
448
  const withKey = [...conf.providers.entries()].filter(([, e]) => hasApiKey(e));
326
449
  const wanted = requested?.trim() || void 0;
327
450
  if (withKey.length === 0) {
328
451
  const hint = wanted ? `model="${wanted}" \u4E0D\u80FD\u6821\u9A8C` : "\u7F3A\u7701\u6A21\u578B\u89E3\u6790\u4E0D\u80FD\u6821\u9A8C";
329
452
  throw new ZcodePrepareError(
330
453
  "engine_credential_missing",
331
- `zcode \u5F15\u64CE\u627E\u4E0D\u5230\u4EFB\u4F55\u5E26 apiKey \u7684\u4E2A\u4EBA provider\uFF08${hint}\uFF09\u3002\u5DF2\u8BFB\u6E90\uFF1A${srcPath}\u3002\u6062\u590D\u6307\u5F15\uFF1A\u5728 ZCode \u684C\u9762\u7AEF\u914D\u7F6E\u81F3\u5C11\u4E00\u4E2A\u4E2A\u4EBA provider\uFF08provider_config.json \u5185\u5B58\u5728 config.access.apiKey \u975E\u7A7A\u6761\u76EE\uFF09\u540E\u91CD\u8BD5\uFF1Bplan \u5957\u9910\u65CF\uFF08builtin:/account: \u524D\u7F00\uFF09\u7ECF\u8D26\u53F7 entitlement \u95E8\u63A7\uFF0C\u5916\u90E8 spawn \u7684\u5F15\u64CE\u6CE8\u518C\u8868\u4E0D\u88C5\u8F7D\uFF0C\u4E0D\u53EF\u4F5C\u4E3A\u5F15\u64CE\u6A21\u578B\u3002`
454
+ `zcode \u5F15\u64CE\u627E\u4E0D\u5230\u4EFB\u4F55\u5E26 apiKey \u7684\u4E2A\u4EBA provider\uFF08${hint}\uFF09\u3002\u5DF2\u8BFB\u6E90\uFF1A${sourceDesc}\u3002\u6062\u590D\u6307\u5F15\uFF1A\u5728 ZCode \u684C\u9762\u7AEF\u914D\u7F6E\u81F3\u5C11\u4E00\u4E2A\u4E2A\u4EBA provider\uFF08provider_config.json \u5185\u5B58\u5728 config.access.apiKey \u975E\u7A7A\u6761\u76EE\uFF09\u540E\u91CD\u8BD5\uFF1Bplan \u5957\u9910\u65CF\uFF08builtin:/account: \u524D\u7F00\uFF09\u7ECF\u8D26\u53F7 entitlement \u95E8\u63A7\uFF0C\u5916\u90E8 spawn \u7684\u5F15\u64CE\u6CE8\u518C\u8868\u4E0D\u88C5\u8F7D\uFF0C\u4E0D\u53EF\u4F5C\u4E3A\u5F15\u64CE\u6A21\u578B\u3002` + TAIJI_SYNC_GUIDANCE
332
455
  );
333
456
  }
334
457
  if (wanted === void 0) return "";
458
+ const wantedProvider = wanted.includes("/") ? providerOf(wanted) : void 0;
459
+ if (wantedProvider !== void 0 && wantedProvider.startsWith("account:")) {
460
+ return resolveAccountModelRef(wanted, wantedProvider, sources);
461
+ }
335
462
  const provider = wanted.includes("/") ? providerOf(wanted) : defaultProviderForShortName(conf, withKey);
336
463
  const short = modelShort(wanted);
337
464
  const entry = conf.providers.get(provider);
@@ -339,26 +466,26 @@ function resolveZcodeModelRef(requested, sources) {
339
466
  const known = withKey.map(([id]) => id).join(", ");
340
467
  throw new ZcodePrepareError(
341
468
  "model_not_available",
342
- `\u672A\u77E5 provider "${provider}"\uFF08\u5E26\u51ED\u636E\u7684\u4E2A\u4EBA provider: ${known}\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u4E0A\u8FF0 provider \u4E4B\u4E00\uFF08\u5168\u540D provider/model\uFF09\uFF0C\u6216\u5728 ZCode \u684C\u9762\u7AEF\u914D\u7F6E\u8BE5 provider \u540E\u91CD\u8BD5\uFF1B\u7701\u7565 model \u53C2\u6570\u5219\u8D70\u5F15\u64CE\u7F3A\u7701\u89E3\u6790\uFF08CLI \u81EA\u8EAB\u9009\u53D6\u53EF\u7528\u6A21\u578B\uFF09\u3002`
469
+ `\u672A\u77E5 provider "${provider}"\uFF08\u5E26\u51ED\u636E\u7684\u4E2A\u4EBA provider: ${known}\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u4E0A\u8FF0 provider \u4E4B\u4E00\uFF08\u5168\u540D provider/model\uFF09\uFF0C\u6216\u5728 ZCode \u684C\u9762\u7AEF\u914D\u7F6E\u8BE5 provider \u540E\u91CD\u8BD5\uFF1B\u7701\u7565 model \u53C2\u6570\u5219\u8D70\u5F15\u64CE\u7F3A\u7701\u89E3\u6790\uFF08CLI \u81EA\u8EAB\u9009\u53D6\u53EF\u7528\u6A21\u578B\uFF09\u3002` + TAIJI_SYNC_GUIDANCE
343
470
  );
344
471
  }
345
472
  if (!hasApiKey(entry)) {
346
473
  throw new ZcodePrepareError(
347
474
  "engine_credential_missing",
348
- `provider "${provider}" \u5B58\u5728\u4F46\u672A\u914D\u7F6E apiKey\u3002\u6062\u590D\u6307\u5F15\uFF1A\u5728 ZCode \u684C\u9762\u7AEF\u4E3A\u8BE5 provider \u914D\u7F6E\u51ED\u636E\uFF0C\u6216\u6539\u7528\u5DF2\u914D\u51ED\u636E\u7684 provider\uFF08${withKey.map(([id]) => id).join(", ")}\uFF09\u540E\u91CD\u8BD5\u3002`
475
+ `provider "${provider}" \u5B58\u5728\u4F46\u672A\u914D\u7F6E apiKey\u3002\u6062\u590D\u6307\u5F15\uFF1A\u5728 ZCode \u684C\u9762\u7AEF\u4E3A\u8BE5 provider \u914D\u7F6E\u51ED\u636E\uFF0C\u6216\u6539\u7528\u5DF2\u914D\u51ED\u636E\u7684 provider\uFF08${withKey.map(([id]) => id).join(", ")}\uFF09\u540E\u91CD\u8BD5\u3002` + TAIJI_SYNC_GUIDANCE
349
476
  );
350
477
  }
351
478
  const models = entry.models ?? [];
352
479
  if (models.length > 0 && !models.includes(short)) {
353
480
  throw new ZcodePrepareError(
354
481
  "model_not_available",
355
- `\u672A\u77E5\u6A21\u578B "${short}"\uFF08provider ${provider} \u4E0B\u53EF\u7528: ${models.join(", ")}\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u8BE5 provider \u4E0B\u7684\u6A21\u578B\uFF0C\u6216\u5728 ZCode \u684C\u9762\u7AEF\u542F\u7528\u76EE\u6807\u6A21\u578B\u540E\u91CD\u8BD5\u3002`
482
+ `\u672A\u77E5\u6A21\u578B "${short}"\uFF08provider ${provider} \u4E0B\u53EF\u7528: ${models.join(", ")}\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u8BE5 provider \u4E0B\u7684\u6A21\u578B\uFF0C\u6216\u5728 ZCode \u684C\u9762\u7AEF\u542F\u7528\u76EE\u6807\u6A21\u578B\u540E\u91CD\u8BD5\u3002` + TAIJI_SYNC_GUIDANCE
356
483
  );
357
484
  }
358
485
  return `${provider}/${short}`;
359
486
  }
360
487
  function listZcodeModels(sources) {
361
- const conf = readSourceConfig(sources?.personalProviderConfigPath ?? defaultPersonalProviderConfigPath());
488
+ const { conf } = readPersonalProviderView(sources);
362
489
  const out = [];
363
490
  for (const [pid, entry] of conf.providers) {
364
491
  if (!hasApiKey(entry)) continue;
@@ -378,7 +505,7 @@ var fs2 = __toESM(require("fs"), 1);
378
505
  var path3 = __toESM(require("path"), 1);
379
506
 
380
507
  // src/error-message.ts
381
- var import_subagent_engine_sdk4 = require("@zhushanwen/subagent-engine-sdk");
508
+ var import_subagent_engine_sdk5 = require("@zhushanwen/subagent-engine-sdk");
382
509
 
383
510
  // src/appserver-launcher.ts
384
511
  var ZCODE_APPSERVER_LAUNCHER_NAME = "appserver-launcher.cjs";
@@ -390,7 +517,12 @@ const os = require('node:os');
390
517
 
391
518
  const CLI_PATH = process.env.ZCODE_ENG_CLI_PATH;
392
519
  const V2_PATH = process.env.ZCODE_ENG_V2_CONFIG || path.join(os.homedir(), '.zcode', 'v2', 'config.json');
393
- const PROVIDER_CONFIG_PATH = process.env.ZCODE_ENG_PROVIDER_CONFIG || path.join(os.homedir(), '.zcode', 'v2', 'provider_config.json');
520
+ // \u771F\u5B9E provider_config.json\uFF08Registry \u76F4\u8BFB\u8DEF\u5F84\uFF0CA0 \u63A2\u9488\u5B9E\u8BC1\uFF09\u2014\u2014\u4E0E CONFIG_PATH \u540C\u6B3E
521
+ // homedir \u63A8\u5BFC\u5F62\u6001\uFF0C\u4E0D\u53D7 env \u91CD\u5B9A\u5411\uFF08merge \u5206\u652F\u8981\u8BFB\u7684\u6B63\u662F\u8FD9\u4E2A\u771F\u5B9E\u8DEF\u5F84\u672C\u8EAB\uFF09
522
+ const REAL_PROVIDER_CONFIG_PATH = path.join(os.homedir(), '.zcode', 'v2', 'provider_config.json');
523
+ // taiji \u540C\u6B65\u526F\u672C\u8DEF\u5F84\uFF08ZCODE_ENG_PROVIDER_CONFIG \u8BED\u4E49\u6536\u7A84\uFF1B'' = \u672A\u8BBE \u2192 merge \u5206\u652F\u4E0D\u6FC0\u6D3B\uFF09
524
+ const PI_SYNCED_PATH = process.env.ZCODE_ENG_PROVIDER_CONFIG || '';
525
+ const PROVIDER_CONFIG_PATH = process.env.ZCODE_ENG_PROVIDER_CONFIG || REAL_PROVIDER_CONFIG_PATH;
394
526
  const CONFIG_PATH = path.join(os.homedir(), '.zcode', 'cli', 'config.json');
395
527
 
396
528
  // \u5408\u5E76\u5F62\u6001\uFF1A\u771F\u5B9E cli config \u539F\u6837\uFF08model/plugins/mcp/subagents \u7B49 worker \u7EE7\u627F\u9762\u4E0D\u53D8\uFF09
@@ -413,7 +545,7 @@ function injectedConfigText() {
413
545
  let v2 = {};
414
546
  try { v2 = JSON.parse(readOrig(V2_PATH, 'utf8')); }
415
547
  catch (err) {
416
- // ENOENT = \u684C\u9762\u7AEF\u672A\u767B\u5F55\uFF08\u6B63\u5E38 no-patch\uFF0C\u9759\u9ED8\uFF09\uFF1B\u5176\u4ED6\u5931\u8D25\uFF08JSON \u635F\u574F/\u6743\u9650\uFF09
548
+ // ENOENT = \u684C\u9762\u7AEF\u672A\u767B\u5F55\uFF08\u6B63\u5E38 no-patch\uFF0C\u4E0D\u6784\u6210\u9519\u8BEF\uFF1B\u8DF3\u8FC7\u51B3\u7B56\u7531\u5B89\u88C5\u95E8\u65E5\u5FD7\u627F\u8F7D\uFF09\uFF1B\u5176\u4ED6\u5931\u8D25\uFF08JSON \u635F\u574F/\u6743\u9650\uFF09
417
549
  // \u51FA\u58F0\u2014\u2014\u5426\u5219\u6392\u969C\u4F1A\u88AB\u539F\u751F\u300C\u8BF7\u767B\u5F55\u300D\u62A5\u9519\u8BEF\u5BFC\uFF0C\u4E0E\u771F\u56E0\uFF08\u6587\u4EF6\u635F\u574F\uFF09\u4E0D\u7B26
418
550
  if (!err || err.code !== 'ENOENT') {
419
551
  process.stderr.write('[zcode-launcher] v2 config \u8BFB\u53D6\u5931\u8D25(' + ((err && err.code) || (err && err.message) || 'unknown') + '): ' + V2_PATH + '\u2014\u2014\u51ED\u636E\u6CE8\u5165\u672A\u751F\u6548\\n');
@@ -468,11 +600,14 @@ function injectedConfigText() {
468
600
  for (const mid of order) {
469
601
  if (typeof mid === 'string' && mid !== '' && !(mid in models)) models[mid] = {};
470
602
  }
603
+ // kind \u6309\u6761\u76EE api.type \u6D3E\u751F\uFF08D3\uFF09\uFF1Aanthropic-messages \u2192 anthropic\uFF0C\u5176\u4F59
604
+ // \uFF08openai-chat-completions / api.type \u7F3A\u5E2D / \u672A\u77E5\u503C\uFF09\u2192 openai-compatible
605
+ // \u2014\u2014\u5BF9\u9F50 v2 config.json \u65E2\u6709 kind \u4E24\u503C\u5F62\u6001\uFF1B\u4F5C\u7528\u4E8E\u8865\u6CE8\u5165\u6BB5\u5168\u90E8\u6761\u76EE\uFF08\u542B\u900F\u4F20
606
+ // \u771F\u5B9E\u6761\u76EE\uFF0Canthropic \u534F\u8BAE\u771F\u5B9E\u6761\u76EE\u4ECE\u65E7\u9519\u914D\u503C openai-compatible \u987A\u5E26\u4FEE\u6B63\uFF09\u3002
607
+ // \u672A\u77E5\u534F\u8BAE\u503C\u9519\u914D\u65F6\u8BF7\u6C42\u671F\u534F\u8BAE\u9519\u8BEF\u53EF\u89C1\uFF08\u4E0D\u963B\u585E\u6CE8\u518C\u8868\u88C5\u8F7D\uFF09\uFF0C\u771F\u673A\u6F02\u79FB\u4FE1\u53F7\u660E\u786E
471
608
  injectable[id] = {
472
609
  name: typeof rule.providerName === 'string' ? rule.providerName : id,
473
- // provider_config.json \u4E0D\u643A\u5E26\u534F\u8BAE\u5F62\u6001\u2014\u2014standard-personal \u7EC4\u4EE5 openai-compatible
474
- // \u4E3A\u591A\u6570\u5148\u4F8B\uFF1B\u9519\u914D\u65F6\u8BF7\u6C42\u671F\u534F\u8BAE\u9519\u8BEF\u53EF\u89C1\uFF08\u4E0D\u963B\u585E\u6CE8\u518C\u8868\u88C5\u8F7D\uFF09\uFF0C\u771F\u673A\u6F02\u79FB\u4FE1\u53F7\u660E\u786E
475
- kind: 'openai-compatible',
610
+ kind: api.type === 'anthropic-messages' ? 'anthropic' : 'openai-compatible',
476
611
  options: { apiKey: access.apiKey, baseURL: api.baseUrl },
477
612
  source: 'custom',
478
613
  models: models,
@@ -489,50 +624,148 @@ function injectedConfigText() {
489
624
  return JSON.stringify(merged);
490
625
  }
491
626
 
627
+ // [merge-fn-start]\uFF08\u5BF9\u8D26\u5355\u6D4B\u63D0\u53D6\u951A\u2014\u2014appserver-launcher.test.ts \u6309\u6807\u8BB0\u622A\u53D6\u672C\u51FD\u6570
628
+ // eval \u6267\u884C\uFF1Bpreparer.ts mergePersonalProviderConfig \u4E0E\u672C\u51FD\u6570\u540C\u89C4\u5219\u9501\u6B65\uFF0C\u6539\u4EFB\u4E00\u4FA7
629
+ // \u987B\u540C\u6B65\u53E6\u4E00\u4FA7\u5E76\u8DD1\u5BF9\u8D26\u5355\u6D4B\uFF09
630
+ // merge(\u771F\u5B9E, \u526F\u672C)\u2014\u2014D3 \u6362\u8F68\u7248\u89C4\u5219\uFF1A
631
+ // - \u526F\u672C\u975E\u5BF9\u8C61 \u2192 \u539F\u6837\u8FD4\u56DE real\uFF08\u526F\u672C\u7F3A\u5E2D\u56DE\u843D\u8BED\u4E49\uFF1Bwrapper \u4FA7\u66F4\u65E9\u77ED\u8DEF\uFF0C\u9632\u5FA1\u5F62\u6001\uFF09
632
+ // - \u771F\u5B9E\u975E\u5BF9\u8C61\uFF08ENOENT/\u635F\u574F\uFF09\u2192 \u539F\u6837\u8FD4\u56DE copy\uFF08\u526F\u672C\u72EC\u6709\u6761\u76EE\u4E3A\u5168\u96C6\uFF1AproviderRules
633
+ // \u4EC5\u526F\u672C\u6761\u76EE + order \u4EC5\u526F\u672C\u5E8F\uFF0C\u9876\u5C42\u5B57\u6BB5\u968F\u526F\u672C\u4FDD\u6301\u5F62\u6001\u5B8C\u6574\uFF09
634
+ // - providerRules\uFF1A\u771F\u5B9E\u6761\u76EE\u6574\u6761\u4FDD\u7559\u5728\u524D\uFF0C\u526F\u672C\u72EC\u6709 id \u8FFD\u52A0\uFF08\u771F\u5B9E\u4F18\u5148 = \u540C\u540D\u8BA9\u4F4D
635
+ // \u7684\u8FD0\u884C\u65F6\u7B2C\u4E8C\u9053\u9632\u7EBF\uFF09\uFF1B\u65E0\u6709\u6548 providerId \u7684\u526F\u672C\u6761\u76EE\u4E22\u5F03\uFF0C\u771F\u5B9E\u6761\u76EE\u539F\u6837\u4FDD\u7559
636
+ // - providerOrder\uFF1A\u771F\u5B9E\u73B0\u503C\u5E8F + \u526F\u672C\u72EC\u6709 id \u8FFD\u52A0\uFF08\u53BB\u91CD\u4FDD\u5E8F\uFF09
637
+ // - \u5176\u4F59\u5B57\u6BB5\uFF08\u542B config \u5185\u5176\u4ED6\u952E\uFF09\u53D6\u771F\u5B9E\u73B0\u503C
638
+ function mergeProviderConfig(realObj, copyObj) {
639
+ const isRec = (v) => v && typeof v === 'object' && !Array.isArray(v);
640
+ if (!isRec(copyObj)) return realObj;
641
+ if (!isRec(realObj)) return copyObj;
642
+ const cfgOf = (obj) => (isRec(obj.config) ? obj.config : {});
643
+ const rulesOf = (obj) => {
644
+ const pcr = cfgOf(obj).providerConfigRules;
645
+ const r = isRec(pcr) ? pcr.providerRules : undefined;
646
+ return Array.isArray(r) ? r : [];
647
+ };
648
+ const strArr = (v) => (Array.isArray(v) ? v.filter((s) => typeof s === 'string' && s.trim() !== '') : []);
649
+ const mergedRules = [];
650
+ const seen = {};
651
+ for (const rule of rulesOf(realObj)) {
652
+ mergedRules.push(rule);
653
+ if (isRec(rule) && typeof rule.providerId === 'string' && rule.providerId !== '') seen[rule.providerId] = true;
654
+ }
655
+ for (const rule of rulesOf(copyObj)) {
656
+ if (!isRec(rule) || typeof rule.providerId !== 'string' || rule.providerId === '') continue;
657
+ if (seen[rule.providerId]) continue;
658
+ seen[rule.providerId] = true;
659
+ mergedRules.push(rule);
660
+ }
661
+ const mergedOrder = [];
662
+ for (const id of strArr(cfgOf(realObj).providerOrder).concat(strArr(cfgOf(copyObj).providerOrder))) {
663
+ if (mergedOrder.indexOf(id) === -1) mergedOrder.push(id);
664
+ }
665
+ const outCfg = Object.assign({}, cfgOf(realObj), {
666
+ providerOrder: mergedOrder,
667
+ providerConfigRules: Object.assign(
668
+ {},
669
+ isRec(cfgOf(realObj).providerConfigRules) ? cfgOf(realObj).providerConfigRules : {},
670
+ { providerRules: mergedRules },
671
+ ),
672
+ });
673
+ return Object.assign({}, realObj, { config: outCfg });
674
+ }
675
+ // [merge-fn-end]
676
+
677
+ // D3 \u6362\u8F68\u88C5\u8F7D\u901A\u9053\uFF1A\u547D\u4E2D\u771F\u5B9E provider_config.json \u7684\u8BFB\u53D6\u91CD\u5B9A\u5411\u4E3A merge(\u771F\u5B9E\u5B9E\u65F6
678
+ // \u5185\u5BB9, taiji \u540C\u6B65\u526F\u672C)\u2014\u2014\u6BCF\u6B21\u8BFB\u53D6\u91CD\u7B97\uFF08\u4E8B\u5B9E\u9A71\u52A8\uFF0C\u65E0\u7F13\u5B58/\u65F6\u95F4\u7A97\uFF0CZCode \u7AEF\u53D8\u66F4
679
+ // \u5B9E\u65F6\u751F\u6548\uFF09\u3002\u526F\u672C\u7F3A\u5931/\u4E0D\u53EF\u8BFB \u2192 null = \u8C03\u7528\u65B9\u77ED\u8DEF\u56DE\u539F\u6587\u4EF6\uFF08\u56DE\u843D\u771F\u5B9E\u6587\u4EF6\u8BED\u4E49\uFF0C
680
+ // \u96F6\u884C\u4E3A\u53D8\u5316\uFF09\uFF1Benv \u672A\u8BBE \u2192 null\uFF08\u5206\u652F\u4E0D\u6FC0\u6D3B\uFF09\u3002\u8BFB\u53D6\u4E00\u5F8B\u7ECF readOrig \u95F4\u63A5\u53D6\uFF08\u9632
681
+ // patch \u9762\u9012\u5F52\u81EA\u8C03\u7528\uFF09\u3002
682
+ function mergedProviderConfigText() {
683
+ if (!PI_SYNCED_PATH) return null;
684
+ const readOrig = fs.__origReadFileSync || fs.readFileSync;
685
+ let copyObj;
686
+ try {
687
+ copyObj = JSON.parse(readOrig(PI_SYNCED_PATH, 'utf8'));
688
+ } catch { return null; }
689
+ if (!copyObj || typeof copyObj !== 'object' || Array.isArray(copyObj)) return null;
690
+ let realObj = null;
691
+ try {
692
+ const parsed = JSON.parse(readOrig(REAL_PROVIDER_CONFIG_PATH, 'utf8'));
693
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) realObj = parsed;
694
+ } catch { /* ENOENT/\u635F\u574F \u2192 \u526F\u672C\u72EC\u6709\u6761\u76EE\u4E3A\u5168\u96C6 */ }
695
+ return JSON.stringify(mergeProviderConfig(realObj, copyObj));
696
+ }
697
+
492
698
  if (!CLI_PATH) {
493
699
  process.stderr.write('[zcode-launcher] ZCODE_ENG_CLI_PATH \u672A\u8BBE\u7F6E\uFF0C\u65E0\u6CD5\u542F\u52A8 app-server\uFF08\u8BE5 env \u7531\u5F15\u64CE\u81EA\u52A8\u8BBE\u7F6E\uFF1B\u624B\u5DE5\u8FD0\u884C wrapper \u9700\u663E\u5F0F\u4F20\u5165\uFF09\\n');
494
700
  process.exit(2);
495
701
  }
496
702
 
497
- const text = injectedConfigText();
498
- if (text !== null) {
499
- // encoding \u5F52\u4E00\uFF08Node \u522B\u540D\u9762\uFF09\uFF1A'utf8'/'utf-8'/\u5927\u5C0F\u5199\u53D8\u4F53\u7EDF\u4E00\u6309 string \u8FD4\u56DE\u2014\u2014
500
- // \u771F\u5B9E bundle \u7684 config \u8BFB\u53D6\u6070\u7528 'utf-8' \u5F62\u6001\uFF0C\u4EC5\u5339\u914D 'utf8' \u4F1A\u9519\u56DE Buffer
501
- // \uFF08\u5F53\u4E0B\u6E38\u4E0D\u53EA JSON.parse \u800C\u505A\u5B57\u7B26\u4E32\u8FD0\u7B97\u65F6\u5373 TypeError\uFF09
502
- const shape = (args, value) => {
503
- const enc = args[0];
504
- const e = typeof enc === 'string' ? enc
505
- : (enc && typeof enc === 'object' && typeof enc.encoding === 'string' ? enc.encoding : undefined);
506
- if (e !== undefined && String(e).toLowerCase().replace(/-/g, '') === 'utf8') return value;
507
- return Buffer.from(value);
508
- };
509
- fs.__origReadFileSync = fs.readFileSync;
510
- fs.readFileSync = function (p, ...rest) {
511
- if (typeof p === 'string' && p === CONFIG_PATH) {
512
- const cur = injectedConfigText();
513
- if (cur !== null) return shape(rest, cur);
514
- }
515
- return fs.__origReadFileSync.call(fs, p, ...rest);
516
- };
517
- fs.promises.__origReadFile = fs.promises.readFile;
518
- fs.promises.readFile = function (p, ...rest) {
519
- if (typeof p === 'string' && p === CONFIG_PATH) {
520
- const cur = injectedConfigText();
521
- if (cur !== null) return Promise.resolve(shape(rest, cur));
703
+ // [2026-10-13 account \u76F4\u901A] \u5185\u5EFA\u76EE\u5F55\u8BFB\u53D6\u62E6\u622A\uFF1A\u7ED9 zhipu-account \u6761\u76EE\u6CE8\u5165 entitled:true\u3002
704
+ // app-server \u6CE8\u518C\u8868\u88C5\u8F7D\u5224\u636E = access.entitled === true\uFF0C\u5916\u90E8 spawn \u4ECE\u76EE\u5F55\u6784\u5EFA\u7684\u8D26\u53F7
705
+ // \u6761\u76EE\u9ED8\u8BA4\u975E entitled\uFF08YXe \u786C\u7F16\u7801 !1\uFF09\u2192 plan \u5BB6\u65CF\u5F15\u7528\u4E00\u5F8B\u300C\u4E0D\u5B58\u5728 Model\u300D\u3002\u7528\u6237\u88C1\u51B3\uFF1A
706
+ // zai \u7CFB\u8D70 account provider \u914D\u7F6E\u5E76\u7ED5\u8FC7\u8BE5\u9650\u5236\u2014\u2014patch \u53EA\u53D1\u751F\u5728\u672C wrapper \u7684\u8BFB\u53D6\u8FD4\u56DE\u503C\uFF0C
707
+ // ZCode.app \u78C1\u76D8\u6587\u4EF6\u96F6\u89E6\u78B0\u3002null = \u76EE\u5F55\u65E0 zhipu-account \u6761\u76EE\uFF08\u65E0\u9700 patch\uFF09\u3002
708
+ // \u672C\u51FD\u6570\u5FC5\u987B\u4EE5\u5B9A\u4F4D\u540E\u7684\u771F\u5B9E\u8DEF\u5F84\u8C03\u7528\uFF08\u5B89\u88C5\u95E8\u4F20 CATALOG_PATH\uFF09\u2014\u2014\u65E0\u53C2\u8C03\u7528\u4F1A\u5728\u8BFB\u6587\u4EF6
709
+ // \u65F6\u629B\u9519\u88AB catch \u6052\u8FD4 null\uFF0C\u66FE\u81F4\u7EAF account \u5BBF\u4E3B\u8865\u4E01\u5C42\u9759\u9ED8\u4E0D\u5B89\u88C5\uFF08\u89C1\u5B89\u88C5\u95E8\u5904\u6CE8\u91CA\uFF09\u3002
710
+ let CATALOG_PATH = process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE || null;
711
+ const __catalogPatchCache = new Map();
712
+ // \u8DF3\u8FC7\u51B3\u7B56\u5F52\u56E0\uFF082026-10 \u5BA1\u67E5\u8865\uFF09\uFF1AcatalogPatchText \u628A\u300C\u65E0\u6761\u76EE\u9700\u8865\u300D\u4E0E\u300C\u8BFB\u53D6/\u89E3\u6790\u5931\u8D25
713
+ // \uFF08\u6587\u4EF6\u7F3A\u5931/\u635F\u574F\uFF09\u300D\u90FD\u6298\u6210 null\uFF0C\u8DF3\u8FC7\u65E5\u5FD7\u82E5\u4E0D\u533A\u5206\u4F1A\u628A\u635F\u574F\u6001\u8BEF\u62A5\u6210\u300C\u65E0\u6761\u76EE\u300D\uFF0C\u6392\u969C\u88AB\u8BEF\u5BFC
714
+ const __catalogPatchStatus = new Map(); // path -> 'no-entries' | 'unreadable'
715
+ function catalogPatchText(path) {
716
+ if (__catalogPatchCache.has(path)) return __catalogPatchCache.get(path);
717
+ let result = null;
718
+ try {
719
+ const readOrig = fs.__origReadFileSync || fs.readFileSync;
720
+ const parsed = JSON.parse(readOrig(path, 'utf8'));
721
+ const rules = parsed && parsed.config && parsed.config.providerConfigRules
722
+ && Array.isArray(parsed.config.providerConfigRules.providerRules)
723
+ ? parsed.config.providerConfigRules.providerRules : null;
724
+ let touched = 0;
725
+ if (rules) for (const rule of rules) {
726
+ const acc = rule && rule.config && rule.config.access;
727
+ if (acc && acc.type === 'zhipu-account' && acc.entitled !== true) { acc.entitled = true; touched++; }
728
+ }
729
+ result = touched > 0 ? JSON.stringify(parsed) : null;
730
+ __catalogPatchStatus.set(path, 'no-entries');
731
+ } catch { result = null; __catalogPatchStatus.set(path, 'unreadable'); }
732
+ __catalogPatchCache.set(path, result);
733
+ return result;
734
+ }
735
+
736
+ // [2026-10-13 account \u76F4\u901A\u2461] CLI bundle \u6E90\u7801\u5185\u5B58\u8865\u4E01\uFF1A\u5916\u90E8 spawn \u7684\u8D26\u53F7\u6761\u76EE\u6784\u5EFA
737
+ // \u786C\u7F16\u7801 entitled:!1\uFF08YXe\uFF09\uFF0C\u6570\u636E\u9762\u6CE8\u5165\uFF08\u76EE\u5F55 entitled \u5B57\u6BB5\uFF09\u88AB\u5176\u65E0\u89C6\u2014\u2014\u6309\u7528\u6237\u88C1\u51B3
738
+ // \u6539 zcode \u6E90\u7801\u7ED5\u8FC7\uFF1A\u62E6\u622A CLI bundle \u6E90\u7801\u8BFB\u53D6\uFF0C\u5185\u5B58\u66FF\u6362\u8BE5\u5B57\u9762\u91CF\u4E3A !0\uFF08ZCode.app
739
+ // \u78C1\u76D8\u6587\u4EF6\u96F6\u89E6\u78B0\uFF1B\u951A\u4E32\u542B ]]:[] \u5C3E\u7F00\u552F\u4E00\u547D\u4E2D YXe \u6784\u9020\uFF0C\u53E6\u4E00\u5904\u540C\u540D\u6761\u4EF6\u903B\u8F91\u4E0D\u53D7\u5F71\u54CD\uFF09\u3002
740
+ // \u951A\u4E0D\u547D\u4E2D\uFF08\u4E0A\u6E38\u6DF7\u6DC6\u5F62\u6001\u53D8\u5316\uFF09\u2192 \u539F\u6587\u900F\u51FA\uFF1A\u4EC5 account \u5BB6\u65CF\u7EE7\u7EED\u88AB\u62D2\uFF0C\u4E2A\u4EBA provider
741
+ // \u4E0D\u53D7\u5F71\u54CD\u3002
742
+ const __cliPatchCache = new Map();
743
+ function patchedCliSource(path) {
744
+ if (__cliPatchCache.has(path)) return __cliPatchCache.get(path);
745
+ let result = null;
746
+ try {
747
+ const readOrig = fs.__origReadFileSync || fs.readFileSync;
748
+ const src = readOrig(path, 'utf8');
749
+ // \u7248\u672C\u9C81\u68D2\u951A\uFF082026-10-13 \u4FEE\u8BA2\uFF09\uFF1Aminified \u6807\u8BC6\u7B26\uFF08Uk/I3 \u7B49\uFF09\u968F zcode \u91CD\u65B0\u6253\u5305
750
+ // \u6F02\u79FB\uFF0C\u5C5E\u6027\u540D\uFF08zcodeBuiltinProviders / zhipu-account / entitled\uFF09\u662F\u6570\u636E/\u5951\u7EA6
751
+ // \u771F\u540D\u4E0D\u88AB\u6DF7\u6DC6\u2014\u2014\u4EE5\u5C5E\u6027\u540D\u5B9A\u4F4D + 600 \u5B57\u7B26\u7A97\u53E3\u5185\u628A\u8D26\u53F7\u6761\u76EE\u6784\u5EFA\u7684 entitled:!1
752
+ // \u7FFB\u8F6C\u4E3A !0\u3002\u7A97\u53E3\u96F6\u547D\u4E2D = \u4E0A\u6E38\u5F62\u6001\u6F02\u79FB \u2192 \u539F\u6587\u900F\u51FA + stderr warn\uFF08\u6F02\u79FB\u53EF\u89C1\uFF0C
753
+ // \u8FDB app-server stderr \u65E5\u5FD7\uFF09\uFF0C\u4E2A\u4EBA provider \u4E0D\u53D7\u5F71\u54CD\u3002
754
+ const anchorIdx = src.indexOf('zcodeBuiltinProviders.entries()');
755
+ if (anchorIdx >= 0) {
756
+ const window = src.slice(anchorIdx, Math.min(src.length, anchorIdx + 600));
757
+ if (window.indexOf('zhipu-account') >= 0 && window.indexOf('entitled:!1') >= 0) {
758
+ result = src.slice(0, anchorIdx)
759
+ + window.split('entitled:!1').join('entitled:!0')
760
+ + src.slice(anchorIdx + 600);
761
+ }
522
762
  }
523
- return fs.promises.__origReadFile.call(fs.promises, p, ...rest);
524
- };
525
- // existsSync \u62E6\u622A\uFF1A\u771F\u5B9E bundle \u7684\u7528\u6237 config \u8BFB\u53D6\uFF08loadFileConfig\uFF09\u4EE5 existsSync
526
- // \u4E3A\u77ED\u8DEF\u95E8\u2014\u2014\u6587\u4EF6\u4E0D\u5B58\u5728\u65F6\u8FD4\u56DE\u7A7A config \u4E14 readFileSync \u4E0D\u88AB\u8C03\u7528\uFF0CGUI-only
527
- // \u767B\u5F55\u5BBF\u4E3B\uFF08cli/config.json \u4ECE\u672A\u88AB CLI \u4FA7\u5199\u8FC7\uFF09\u4E0A\u6CE8\u5165\u53EA\u6302\u5728\u8BFB\u53D6\u9762 = \u4E0D\u53EF\u89C1
528
- fs.__origExistsSync = fs.existsSync;
529
- fs.existsSync = function (p) {
530
- if (typeof p === 'string' && p === CONFIG_PATH) {
531
- const cur = injectedConfigText();
532
- if (cur !== null) return true;
763
+ if (result === null) {
764
+ process.stderr.write('[zcode-launcher] account bypass: CLI bundle anchor not found (zcode upstream shape drifted?) - account family stays gated, personal providers unaffected\\n');
533
765
  }
534
- return fs.__origExistsSync.call(fs, p);
535
- };
766
+ } catch { result = null; }
767
+ __cliPatchCache.set(path, result);
768
+ return result;
536
769
  }
537
770
 
538
771
  // \u5185\u5EFA provider \u914D\u7F6E\u5B9A\u4F4D\uFF08\u6F02\u79FB\u9762\u2461\uFF09\uFF1A3.12.x \u8D77\u914D\u7F6E\u6587\u4EF6\u632A\u4F4D + CLI \u4F9D\u8D56\u5BBF\u4E3B\u6CE8\u5165
@@ -541,6 +774,11 @@ if (text !== null) {
541
774
  // <plat>-<arch> \u4F18\u5148\uFF0CRust arch \u53D8\u4F53\u5982 darwin-aarch64 \u5B57\u5178\u5E8F\u8DDF\u540E\uFF09\xD7 \u7248\u672C\u76EE\u5F55
542
775
  // \uFF08semver \u6700\u5927\uFF09\u7684 endpoint-*/zcode-builtin.json \u2192 \u90FD\u627E\u4E0D\u5230\u5219\u4E0D\u8BBE\u952E\uFF0C\u8BA9 CLI
543
776
  // \u539F\u751F\u62A5\u9519\u900F\u51FA\uFF08\u9519\u8BEF\u6587\u6848\u542B\u6062\u590D\u6307\u5F15\uFF09\u3002
777
+ // [\u4F4D\u7F6E\uFF1A\u5B89\u88C5\u95E8\u4E4B\u524D] \u5B9A\u4F4D/env \u63A8\u5BFC\u5FC5\u987B\u5148\u4E8E\u5B89\u88C5\u95E8\u5224\u5B9A\u5B8C\u6210\u2014\u2014catalogPatchText
778
+ // \u9700\u8981\u5B9A\u4F4D\u540E\u7684\u771F\u5B9E\u8DEF\u5F84\u53C2\u4E0E\u95E8\u5224\u5B9A\u3002\u66FE\u56E0\u95E8\u5148\u4E8E\u5B9A\u4F4D\u6267\u884C\u4E14\u65E0\u53C2\u8C03\u7528\uFF0C
779
+ // fs.readFileSync(undefined) \u629B\u9519\u88AB catch \u6052\u8FD4 null \u2192 \u95E8\u9000\u5316\u4E3A text!==null\uFF0C
780
+ // \u7EAF account \u5BBF\u4E3B\uFF08v2 \u65E0\u51ED\u636E\u6761\u76EE \u2192 text=null\uFF09\u4E0B\u8865\u4E01\u5C42\u9759\u9ED8\u4E0D\u5B89\u88C5\u3001account
781
+ // \u76F4\u901A\u6574\u4F53\u5931\u6548\u4E14\u96F6\u65E5\u5FD7\uFF082026-10 \u56DE\u5F52\u4FEE\u590D\uFF09\u3002
544
782
  if (!process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE) {
545
783
  let located = null;
546
784
  try {
@@ -582,6 +820,7 @@ if (!process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE) {
582
820
  }
583
821
  } catch { /* provider \u76EE\u5F55\u7F3A\u5931/\u4E0D\u53EF\u8BFB \u2192 \u4E0D\u8BBE\u952E */ }
584
822
  if (located) process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE = located;
823
+ CATALOG_PATH = process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE || null;
585
824
  // endpoint origin \u5BF9\u9F50\uFF082026-09-29 \u8FC1\u79FB\u540C\u6B65\uFF09\uFF1ACLI \u6309 ZCODE_BASE_URL \u6D3E\u751F active
586
825
  // \u76EE\u5F55\u8DEF\u5F84\uFF08sha256(origin) \u524D\u7F00\uFF09\uFF1BGUI \u5B89\u88C5\u7684\u76EE\u5F55\u5728 refresh \u63A7\u5236\u6587\u4EF6\u7684 endpointKey
587
826
  // \u4E0B\uFF08\u5982 https://zcode.z.ai\uFF09\uFF0C\u4E0E CLI \u7F3A\u7701 origin\uFF08bigmodel.cn\uFF09\u4E0D\u540C\u2014\u2014\u4E0D\u6CE8\u5165\u5219
@@ -601,6 +840,115 @@ if (!process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE) {
601
840
  }
602
841
  }
603
842
 
843
+ // \u5B89\u88C5\u95E8\uFF1A\u4EFB\u4E00 patch \u6E90\u53EF\u7528\u5373\u5B89\u88C5\u62E6\u622A\u5C42\uFF1B\u51B3\u7B56\u4E24\u6001\u90FD\u51FA\u58F0\uFF08\u88C5\u4E86\u54EA\u4E9B patch / \u4E3A\u4F55
844
+ // \u8DF3\u8FC7\uFF09\u2014\u2014\u8865\u4E01\u5C42\u7684\u5931\u6548\u5F62\u6001\u662F\u9759\u9ED8\u7684\uFF08account \u76F4\u901A\u5931\u6548 = plan \u5BB6\u65CF\u62A5\u300C\u4E0D\u5B58\u5728
845
+ // Model\u300D\u800C\u65E0\u4EFB\u4F55\u65E5\u5FD7\uFF09\uFF0C\u8DF3\u8FC7\u540C\u6837\u5FC5\u987B\u7559\u75D5\u3002
846
+ const text = injectedConfigText();
847
+ const catalogPatch = CATALOG_PATH !== null ? catalogPatchText(CATALOG_PATH) : null;
848
+ if (text !== null || catalogPatch !== null) {
849
+ process.stderr.write('[zcode-launcher] \u8865\u4E01\u5C42\u5DF2\u5B89\u88C5: cli-config-inject=' + (text !== null ? 'on' : 'off')
850
+ + ', catalog-entitled=' + (catalogPatch !== null ? 'on' : 'off')
851
+ + ', provider-merge=' + (PI_SYNCED_PATH ? 'armed' : 'off') + ', cli-source-bypass=armed\\n');
852
+ // encoding \u5F52\u4E00\uFF08Node \u522B\u540D\u9762\uFF09\uFF1A'utf8'/'utf-8'/\u5927\u5C0F\u5199\u53D8\u4F53\u7EDF\u4E00\u6309 string \u8FD4\u56DE\u2014\u2014
853
+ // \u771F\u5B9E bundle \u7684 config \u8BFB\u53D6\u6070\u7528 'utf-8' \u5F62\u6001\uFF0C\u4EC5\u5339\u914D 'utf8' \u4F1A\u9519\u56DE Buffer
854
+ // \uFF08\u5F53\u4E0B\u6E38\u4E0D\u53EA JSON.parse \u800C\u505A\u5B57\u7B26\u4E32\u8FD0\u7B97\u65F6\u5373 TypeError\uFF09
855
+ // shape \u540C\u65F6\u670D\u52A1\u56DB\u5904 patch \u6E90\uFF08config / provider merge / \u5185\u5EFA\u76EE\u5F55 / \u2014\u2014encoding \u5F52\u4E00
856
+ // \u8BED\u4E49\u76F8\u540C\uFF0C\u5355\u526F\u672C\uFF1A\u76EE\u5F55\u6761\u76EE\u66FE\u53E6\u6301\u9010\u5B57\u91CD\u590D\u526F\u672C catalogShape\uFF0C\u5DF2\u5E76\u56DE\u672C\u51FD\u6570\uFF09
857
+ const shape = (args, value) => {
858
+ const enc = args[0];
859
+ const e = typeof enc === 'string' ? enc
860
+ : (enc && typeof enc === 'object' && typeof enc.encoding === 'string' ? enc.encoding : undefined);
861
+ if (e !== undefined && String(e).toLowerCase().replace(/-/g, '') === 'utf8') return value;
862
+ return Buffer.from(value);
863
+ };
864
+ fs.__origReadFileSync = fs.readFileSync;
865
+ fs.readFileSync = function (p, ...rest) {
866
+ if (typeof p === 'string' && p === CONFIG_PATH) {
867
+ const cur = injectedConfigText();
868
+ if (cur !== null) return shape(rest, cur);
869
+ }
870
+ // D3 \u6362\u8F68\uFF1ARegistry \u76F4\u8BFB\u771F\u5B9E provider_config.json \u2192 merge(\u771F\u5B9E, \u526F\u672C) \u89C6\u56FE
871
+ if (typeof p === 'string' && p === REAL_PROVIDER_CONFIG_PATH) {
872
+ const cur = mergedProviderConfigText();
873
+ if (cur !== null) return shape(rest, cur);
874
+ }
875
+ // account \u76F4\u901A\uFF1A\u5185\u5EFA\u76EE\u5F55\u8BFB\u53D6 \u2192 zhipu-account \u6CE8\u5165 entitled:true\u3002\u6309\u6587\u4EF6\u540D\u5339\u914D
876
+ // \uFF08app-server \u6309 ZCODE_BASE_URL \u81EA\u6D3E\u751F endpoint \u76EE\u5F55\uFF0C\u8BFB\u8DEF\u5F84\u2260env \u5B9A\u4F4D\u8DEF\u5F84\uFF09\u3002
877
+ if (typeof p === 'string' && p.endsWith('zcode-builtin.json')) {
878
+ const cur = catalogPatchText(p);
879
+ if (cur !== null) return shape(rest, cur);
880
+ }
881
+ // account \u76F4\u901A\u2461\uFF1ACLI bundle \u6E90\u7801 \u2192 YXe entitled:!1 \u5185\u5B58\u7FFB\u8F6C\u4E3A !0
882
+ if (typeof p === 'string' && p === CLI_PATH) {
883
+ const cur = patchedCliSource(p);
884
+ if (cur !== null) return cur;
885
+ }
886
+ return fs.__origReadFileSync.call(fs, p, ...rest);
887
+ };
888
+ fs.promises.__origReadFile = fs.promises.readFile;
889
+ fs.promises.readFile = function (p, ...rest) {
890
+ if (typeof p === 'string' && p === CONFIG_PATH) {
891
+ const cur = injectedConfigText();
892
+ if (cur !== null) return Promise.resolve(shape(rest, cur));
893
+ }
894
+ if (typeof p === 'string' && p === REAL_PROVIDER_CONFIG_PATH) {
895
+ const cur = mergedProviderConfigText();
896
+ if (cur !== null) return Promise.resolve(shape(rest, cur));
897
+ }
898
+ if (typeof p === 'string' && p.endsWith('zcode-builtin.json')) {
899
+ const cur = catalogPatchText(p);
900
+ if (cur !== null) return Promise.resolve(shape(rest, cur));
901
+ }
902
+ if (typeof p === 'string' && p === CLI_PATH) {
903
+ const cur = patchedCliSource(p);
904
+ if (cur !== null) return Promise.resolve(cur);
905
+ }
906
+ return fs.promises.__origReadFile.call(fs.promises, p, ...rest);
907
+ };
908
+ // [account \u76F4\u901A\u2461 \u8F7D\u4F53] .js \u6269\u5C55\u5904\u7406\u5668\u6302\u94A9\uFF1ANode \u5BF9 CJS \u5165\u53E3\u6E90\u7801\u7684\u8BFB\u53D6\u8D70\u539F\u751F
909
+ // internalModuleReadFile \u901A\u9053\uFF0Cfs \u7334\u8865\u4E01\u4E0D\u53EF\u89C1\u2014\u2014CLI bundle \u6E90\u7801\u8865\u4E01\u6539\u5728\u6269\u5C55
910
+ // \u5904\u7406\u5668\u5C42\u62E6\u622A\uFF08\u4EC5\u547D\u4E2D CLI_PATH\uFF1B\u5176\u4F59\u6587\u4EF6\u5168\u6743\u59D4\u6258\u539F handler\uFF0C\u96F6\u989D\u5916\u5F00\u9500\uFF09\u3002
911
+ const __Module = require('node:module');
912
+ const __origJsHandler = __Module._extensions['.js'];
913
+ __Module._extensions['.js'] = function (mod, filename) {
914
+ if (CLI_PATH && filename === CLI_PATH) {
915
+ const patched = patchedCliSource(filename);
916
+ if (patched !== null) {
917
+ let src = patched.charCodeAt(0) === 0xfeff ? patched.slice(1) : patched;
918
+ if (src.startsWith('#!')) src = src.slice(src.indexOf('\\n') + 1);
919
+ return mod._compile(src, filename);
920
+ }
921
+ }
922
+ return __origJsHandler(mod, filename);
923
+ };
924
+
925
+ // existsSync \u62E6\u622A\uFF1A\u771F\u5B9E bundle \u7684\u7528\u6237 config \u8BFB\u53D6\uFF08loadFileConfig\uFF09\u4EE5 existsSync
926
+ // \u4E3A\u77ED\u8DEF\u95E8\u2014\u2014\u6587\u4EF6\u4E0D\u5B58\u5728\u65F6\u8FD4\u56DE\u7A7A config \u4E14 readFileSync \u4E0D\u88AB\u8C03\u7528\uFF0CGUI-only
927
+ // \u767B\u5F55\u5BBF\u4E3B\uFF08cli/config.json \u4ECE\u672A\u88AB CLI \u4FA7\u5199\u8FC7\uFF09\u4E0A\u6CE8\u5165\u53EA\u6302\u5728\u8BFB\u53D6\u9762 = \u4E0D\u53EF\u89C1\u3002
928
+ // D3 \u6362\u8F68\uFF1A\u771F\u5B9E provider_config.json \u7684\u5B58\u5728\u6027 = \u771F\u5B9E\u6216\u526F\u672C\u4EFB\u4E00\u5B58\u5728\u5373 true
929
+ //\uFF08\u771F\u5B9E\u7F3A\u5931 + \u526F\u672C\u5B58\u5728\u65F6 Registry \u7684 existsSync \u95E8\u4E0D\u5F97\u62E6\u6389 merge \u89C6\u56FE\u8BFB\u53D6\uFF09
930
+ fs.__origExistsSync = fs.existsSync;
931
+ fs.existsSync = function (p) {
932
+ if (typeof p === 'string' && p === CONFIG_PATH) {
933
+ const cur = injectedConfigText();
934
+ if (cur !== null) return true;
935
+ }
936
+ if (typeof p === 'string' && p === REAL_PROVIDER_CONFIG_PATH && PI_SYNCED_PATH) {
937
+ if (fs.__origExistsSync.call(fs, REAL_PROVIDER_CONFIG_PATH)) return true;
938
+ return fs.__origExistsSync.call(fs, PI_SYNCED_PATH);
939
+ }
940
+ return fs.__origExistsSync.call(fs, p);
941
+ };
942
+ } else {
943
+ process.stderr.write('[zcode-launcher] \u8865\u4E01\u5C42\u672A\u5B89\u88C5(\u8DF3\u8FC7): \u65E0\u51ED\u636E\u53EF\u6CE8\u5165(v2 config \u65E0 provider \u6761\u76EE)'
944
+ + (CATALOG_PATH !== null
945
+ ? (__catalogPatchStatus.get(CATALOG_PATH) === 'unreadable'
946
+ ? '; \u5185\u5EFA\u76EE\u5F55\u5DF2\u5B9A\u4F4D\u4F46 catalog \u8BFB\u53D6/\u89E3\u6790\u5931\u8D25(\u6587\u4EF6\u7F3A\u5931\u6216\u635F\u574F\uFF0C\u6392\u969C\u5165\u53E3: zcode-builtin.json\u2014\u2014\u975E\u300C\u65E0\u6761\u76EE\u300D)'
947
+ : '; \u5185\u5EFA\u76EE\u5F55\u5DF2\u5B9A\u4F4D\u4F46\u65E0 zhipu-account \u6761\u76EE\u9700\u8865(\u76EE\u5F55\u8BFB\u53D6\u539F\u751F\u900F\u51FA)')
948
+ : '; \u5185\u5EFA\u76EE\u5F55\u672A\u5B9A\u4F4D(env \u672A\u8BBE\u4E14\u81EA\u5B9A\u4F4D\u672A\u547D\u4E2D)')
949
+ + '\\n');
950
+ }
951
+
604
952
  // \u4E0A\u6E38 provider bootstrap \u4EE5 argv[1] \u4E3A\u5165\u53E3\u951A\uFF0C\u4ECE\u8BE5\u8DEF\u5F84\u90BB\u8FD1\u5B9A\u4F4D CLI \u5185\u5EFA
605
953
  // provider \u914D\u7F6E\u2014\u2014wrapper \u5F62\u6001\u4E0B argv[1] = \u672C wrapper \u843D\u76D8\u8DEF\u5F84\uFF0Cbootstrap \u4F1A\u5728
606
954
  // wrapper \u90BB\u57DF\u627E provider \u914D\u7F6E\u800C\u5931\u8D25\uFF08\u771F\u673A\u62A5\u300C\u65E0\u6CD5\u5B9A\u4F4D CLI ZCode Built-in Provider
@@ -625,7 +973,7 @@ function ensureAppServerLauncher(engineDataDir) {
625
973
  fs2.writeFileSync(tmp, APPSERVER_LAUNCHER_SOURCE);
626
974
  fs2.renameSync(tmp, file);
627
975
  } catch (err) {
628
- const reason = (0, import_subagent_engine_sdk4.toErrorMessage)(err);
976
+ const reason = (0, import_subagent_engine_sdk5.toErrorMessage)(err);
629
977
  throw new Error(
630
978
  `zcode app-server launcher \u843D\u76D8\u5931\u8D25: ${file}\uFF08${reason}\uFF09\u3002\u6062\u590D\uFF1A\u68C0\u67E5\u5F15\u64CE\u6570\u636E\u76EE\u5F55 \u5199\u6743\u9650\u4E0E\u78C1\u76D8\u7A7A\u95F4\uFF08engineDataDir \u7531\u5BBF\u4E3B\u4F20\u5165\uFF0C\u8DEF\u5F84\u89C1\u4E0A\uFF09\u540E\u91CD\u8BD5\u3002`
631
979
  );
@@ -883,21 +1231,21 @@ async function readZcodeSessionView(dbPath, sessionId) {
883
1231
  var fs4 = __toESM(require("fs"), 1);
884
1232
  var import_node_path = require("path");
885
1233
  var import_node_os = require("os");
886
- var import_subagent_engine_sdk7 = require("@zhushanwen/subagent-engine-sdk");
1234
+ var import_subagent_engine_sdk8 = require("@zhushanwen/subagent-engine-sdk");
887
1235
 
888
1236
  // src/logs/stderr-rotation.ts
889
- var import_subagent_engine_sdk5 = require("@zhushanwen/subagent-engine-sdk");
890
1237
  var import_subagent_engine_sdk6 = require("@zhushanwen/subagent-engine-sdk");
1238
+ var import_subagent_engine_sdk7 = require("@zhushanwen/subagent-engine-sdk");
891
1239
  var ZCODE_STDERR_LOG_PREFIX = "zcode-appserver-stderr-";
892
1240
  function stderrLogPathFor(engineDataDir, pid) {
893
- return (0, import_subagent_engine_sdk5.stderrLogPathFor)(engineDataDir, pid, ZCODE_STDERR_LOG_PREFIX);
1241
+ return (0, import_subagent_engine_sdk6.stderrLogPathFor)(engineDataDir, pid, ZCODE_STDERR_LOG_PREFIX);
894
1242
  }
895
1243
  function cleanupSiblingStderrLogs(logPath, env, now) {
896
- return (0, import_subagent_engine_sdk5.cleanupSiblingStderrLogs)(logPath, env, ZCODE_STDERR_LOG_PREFIX, now);
1244
+ return (0, import_subagent_engine_sdk6.cleanupSiblingStderrLogs)(logPath, env, ZCODE_STDERR_LOG_PREFIX, now);
897
1245
  }
898
1246
 
899
1247
  // src/connection.ts
900
- var logger = (0, import_subagent_engine_sdk7.getLogger)("subagents");
1248
+ var logger = (0, import_subagent_engine_sdk8.getLogger)("subagents");
901
1249
  var RAW_FRAME_LOG_CHARS = 200;
902
1250
  var RUNTIME_PREFERENCES = Object.freeze({
903
1251
  nativeSearchEnhancementsEnabled: true,
@@ -919,11 +1267,11 @@ function frameIdOf(frame) {
919
1267
  return typeof id === "string" || typeof id === "number" ? id : void 0;
920
1268
  }
921
1269
  function errMessage(err) {
922
- return (0, import_subagent_engine_sdk4.toErrorMessage)(err);
1270
+ return (0, import_subagent_engine_sdk5.toErrorMessage)(err);
923
1271
  }
924
1272
  function buildAppServerEnv(baseEnv = process.env) {
925
1273
  return {
926
- ...(0, import_subagent_engine_sdk7.buildNestedSpawnEnv)(baseEnv),
1274
+ ...(0, import_subagent_engine_sdk8.buildNestedSpawnEnv)(baseEnv),
927
1275
  ZCODE_MODEL_TELEMETRY_ENABLED: "false"
928
1276
  };
929
1277
  }
@@ -1073,7 +1421,7 @@ var AppServerConnection = class {
1073
1421
  close() {
1074
1422
  const child = this.child;
1075
1423
  if (child === null || this.killChainPromise !== void 0) return;
1076
- this.killChainPromise = (0, import_subagent_engine_sdk7.killChain)(child, { graceMs: ZCODE_KILL_GRACE_MS });
1424
+ this.killChainPromise = (0, import_subagent_engine_sdk8.killChain)(child, { graceMs: ZCODE_KILL_GRACE_MS });
1077
1425
  }
1078
1426
  /**
1079
1427
  * 异步完整关闭面:SIGTERM → grace → SIGKILL 杀链走完(含收尸),resolve 于进程
@@ -1085,7 +1433,7 @@ var AppServerConnection = class {
1085
1433
  if (this.killChainPromise === void 0) {
1086
1434
  const child = this.child;
1087
1435
  if (child === null) return;
1088
- this.killChainPromise = (0, import_subagent_engine_sdk7.killChain)(child, { graceMs: opts?.graceMs ?? ZCODE_KILL_GRACE_MS });
1436
+ this.killChainPromise = (0, import_subagent_engine_sdk8.killChain)(child, { graceMs: opts?.graceMs ?? ZCODE_KILL_GRACE_MS });
1089
1437
  }
1090
1438
  await this.killChainPromise;
1091
1439
  }
@@ -1104,10 +1452,10 @@ var AppServerConnection = class {
1104
1452
  this.generation += 1;
1105
1453
  const gen = this.generation;
1106
1454
  const script = this.launcherScript ?? this.cliPath;
1107
- const child = (0, import_subagent_engine_sdk7.spawnEngineChild)({
1455
+ const child = (0, import_subagent_engine_sdk8.spawnEngineChild)({
1108
1456
  command: this.nodeBin,
1109
1457
  args: [script, "app-server", "--cwd", this.cwd],
1110
- env: (0, import_subagent_engine_sdk7.buildEngineChildEnv)(this.env, {
1458
+ env: (0, import_subagent_engine_sdk8.buildEngineChildEnv)(this.env, {
1111
1459
  // L0 TAIJI_AGENT_DATA_DIR 缺省链:显式传参 > 宿主注入 env > tmpdir 占位
1112
1460
  //(app-server 不消费该键,占位仅满足 L0 必注入契约;生产调用方
1113
1461
  // zcode-engine.ensureAppServerRuntime 恒传 engineDataDir)。
@@ -1145,7 +1493,7 @@ var AppServerConnection = class {
1145
1493
  }
1146
1494
  }
1147
1495
  };
1148
- (0, import_subagent_engine_sdk7.pumpNdjsonLines)(child.stdout, (line) => this.handleLine(line));
1496
+ (0, import_subagent_engine_sdk8.pumpNdjsonLines)(child.stdout, (line) => this.handleLine(line));
1149
1497
  child.stderr?.setEncoding("utf8");
1150
1498
  child.stderr?.on("data", (chunk) => {
1151
1499
  this.stderrTail = (this.stderrTail + chunk).slice(-ZCODE_APPSERVER_STDERR_TAIL_BUFFER_CHARS);
@@ -1286,8 +1634,8 @@ var AppServerConnection = class {
1286
1634
  }
1287
1635
  this.stderrStream.write(chunk);
1288
1636
  if (this.activeStderrLogPath !== null) {
1289
- const params = (0, import_subagent_engine_sdk6.stderrRotationParams)(process.env);
1290
- if ((0, import_subagent_engine_sdk6.rotateStderrLogIfNeeded)(this.activeStderrLogPath, params)) {
1637
+ const params = (0, import_subagent_engine_sdk7.stderrRotationParams)(process.env);
1638
+ if ((0, import_subagent_engine_sdk7.rotateStderrLogIfNeeded)(this.activeStderrLogPath, params)) {
1291
1639
  this.closeStderrStream();
1292
1640
  }
1293
1641
  }
@@ -1305,8 +1653,8 @@ var AppServerConnection = class {
1305
1653
 
1306
1654
  // src/session-channel.ts
1307
1655
  var import_node_crypto = require("crypto");
1308
- var import_subagent_engine_sdk8 = require("@zhushanwen/subagent-engine-sdk");
1309
- var logger2 = (0, import_subagent_engine_sdk8.getLogger)("subagents");
1656
+ var import_subagent_engine_sdk9 = require("@zhushanwen/subagent-engine-sdk");
1657
+ var logger2 = (0, import_subagent_engine_sdk9.getLogger)("subagents");
1310
1658
  var SUBSCRIBE_DELIVERY_KIND = "desktop-continuous";
1311
1659
  var WORKSPACE_KEY_HASH_CHARS = 16;
1312
1660
  var CREATE_REPLY_LOG_CHARS = 300;
@@ -1315,7 +1663,7 @@ function isRecord3(v) {
1315
1663
  return typeof v === "object" && v !== null && !Array.isArray(v);
1316
1664
  }
1317
1665
  function errMessage2(err) {
1318
- return (0, import_subagent_engine_sdk4.toErrorMessage)(err);
1666
+ return (0, import_subagent_engine_sdk5.toErrorMessage)(err);
1319
1667
  }
1320
1668
  function stableWorkspaceKey(workspacePath) {
1321
1669
  return "ws-" + (0, import_node_crypto.createHash)("sha256").update(workspacePath).digest("hex").slice(0, WORKSPACE_KEY_HASH_CHARS);
@@ -1842,8 +2190,8 @@ var SessionChannel = class {
1842
2190
 
1843
2191
  // src/session-db-maintenance.ts
1844
2192
  var fs5 = __toESM(require("fs"), 1);
1845
- var import_subagent_engine_sdk9 = require("@zhushanwen/subagent-engine-sdk");
1846
- var logger3 = (0, import_subagent_engine_sdk9.getLogger)("subagents");
2193
+ var import_subagent_engine_sdk10 = require("@zhushanwen/subagent-engine-sdk");
2194
+ var logger3 = (0, import_subagent_engine_sdk10.getLogger)("subagents");
1847
2195
  var ZCODE_SESSION_TTL_MS = 2592e6;
1848
2196
  var ZCODE_SESSION_SWEEP_INTERVAL_MS = 864e5;
1849
2197
  var SWEEP_BUSY_TIMEOUT_MS = 5e3;
@@ -1999,9 +2347,10 @@ function maybeSweepExpiredZcodeSessions(dbPath, opts = {}) {
1999
2347
  }
2000
2348
 
2001
2349
  // src/zcode-engine.ts
2002
- var logger4 = (0, import_subagent_engine_sdk10.getLogger)("subagents");
2350
+ var logger4 = (0, import_subagent_engine_sdk11.getLogger)("subagents");
2003
2351
  var PROBE_VERSION_TIMEOUT_MS = 15e3;
2004
2352
  var COMMON_THOUGHT_LEVELS = ["low", "high", "max"];
2353
+ var OFF_FAMILY_THINKING_LEVELS = /* @__PURE__ */ new Set(["off", "minimal"]);
2005
2354
  var ZcodeEngine = class {
2006
2355
  id = ZCODE_ENGINE_ID;
2007
2356
  deps;
@@ -2214,7 +2563,7 @@ var ZcodeEngine = class {
2214
2563
  */
2215
2564
  async attemptAppServerTurn(task, ctx, modelRef, cwd, prompt, opts = {}) {
2216
2565
  const rt = this.ensureAppServerRuntime();
2217
- const reasoningLevel = modelRef !== void 0 && modelRef !== "" ? this.minimalReasoningFor(modelRef) : void 0;
2566
+ const reasoningLevel = modelRef !== void 0 && modelRef !== "" ? this.reasoningLevelFor(modelRef, task.thinkingLevel) : void 0;
2218
2567
  const createParams = buildAppServerCreateParams(task, modelRef, cwd, reasoningLevel);
2219
2568
  let currentSessionId;
2220
2569
  let signalSessionCreated;
@@ -2368,7 +2717,7 @@ var ZcodeEngine = class {
2368
2717
  const env = buildAppServerEnv(this.deps.processEnv ?? process.env);
2369
2718
  env.ZCODE_ENG_CLI_PATH = cliPath;
2370
2719
  env.ZCODE_ENG_V2_CONFIG = this.deps.sources?.v2ConfigPath ?? defaultV2ConfigPath();
2371
- env.ZCODE_ENG_PROVIDER_CONFIG = this.deps.sources?.personalProviderConfigPath ?? defaultPersonalProviderConfigPath();
2720
+ env.ZCODE_ENG_PROVIDER_CONFIG = resolvePersonalProviderConfigPath(this.deps.sources, engineDataDir);
2372
2721
  const sessionDbPath = zcodeSessionDbPath(engineDataDir);
2373
2722
  env.ZCODE_SESSION_DB_PATH = sessionDbPath;
2374
2723
  delete env.ZCODE_SESSION_DB;
@@ -2465,7 +2814,7 @@ var ZcodeEngine = class {
2465
2814
  /** abort 合成终态:exitCode=null(record 正常收尾,不留僵尸)。 */
2466
2815
  applyAbortedOutcome(outcome, task, ctx, final, emit) {
2467
2816
  outcome.exitCode = null;
2468
- outcome.error = isHostTimeoutAbort(ctx) ? (0, import_subagent_engine_sdk11.synthesizeTimeoutOutcome)(task, final.output.stdoutText, ZCODE_ENGINE_ID).error ?? (0, import_subagent_engine_sdk11.engineTimeoutDetail)(final.output.stdoutText) : final.abortMessage ?? `engine_run_failed: zcode \u4EFB\u52A1\u88AB\u4E2D\u6B62\uFF08app-server abort \u94FE\u6536\u53E3\uFF0C\u5BBF\u4E3B\u5408\u6210\u7EC8\u6001\uFF09\u3002\u8F93\u51FA\u5C3E\u90E8: ${final.output.stdoutText.slice(-ZCODE_ERROR_TAIL_CHARS)}`;
2817
+ outcome.error = isHostTimeoutAbort(ctx) ? (0, import_subagent_engine_sdk12.synthesizeTimeoutOutcome)(task, final.output.stdoutText, ZCODE_ENGINE_ID).error ?? (0, import_subagent_engine_sdk12.engineTimeoutDetail)(final.output.stdoutText) : final.abortMessage ?? `engine_run_failed: zcode \u4EFB\u52A1\u88AB\u4E2D\u6B62\uFF08app-server abort \u94FE\u6536\u53E3\uFF0C\u5BBF\u4E3B\u5408\u6210\u7EC8\u6001\uFF09\u3002\u8F93\u51FA\u5C3E\u90E8: ${final.output.stdoutText.slice(-ZCODE_ERROR_TAIL_CHARS)}`;
2469
2818
  emit({ type: "error", message: outcome.error });
2470
2819
  }
2471
2820
  /**
@@ -2511,16 +2860,30 @@ var ZcodeEngine = class {
2511
2860
  listModels() {
2512
2861
  return listZcodeModels(this.deps.sources);
2513
2862
  }
2514
- /** 显式模型的最小 reasoning 档(目录 modelRules 值域;per-modelRef 记忆化——
2863
+ /** 模型 reasoning 值域缓存(目录 modelRules 值域;per-modelRef 记忆化——
2515
2864
  * 目录文件在引擎进程生命周期内视为静态,重复 run 不重读)。 */
2516
2865
  reasoningMemo = /* @__PURE__ */ new Map();
2517
- minimalReasoningFor(modelRef) {
2866
+ /**
2867
+ * create 帧模型 reasoning 档择选(目录值域域内择档;2026-10-13 探针实测驱动):
2868
+ * - 无 thinkingLevel:目录值域首值(最小档,现状保形——轻推理默认);
2869
+ * - off 族(off/minimal,显式禁思考/最省):恒值域首值(最小档)——绝不落
2870
+ * 非最小档末值回退(那是「请求思考」档位的回退,off 族落之即意图反转);
2871
+ * - 其余 thinkingLevel:精确命中值域 → 用之;值域无精确名 → 取非最小档末值
2872
+ * (请求了思考 = reasoning 开;plan 网关对部分模型拒收 disabled——目录域含
2873
+ * disabled 但服务端只认非最小档,域与接受面漂移时显式意图走非最小档)。
2874
+ */
2875
+ reasoningLevelFor(modelRef, thinkingLevel) {
2518
2876
  const memoKey = `${locateZcodeBuiltinCatalog(this.deps.sources) ?? "none"}|${modelRef}`;
2519
- const hit = this.reasoningMemo.get(memoKey);
2520
- if (hit !== void 0 || this.reasoningMemo.has(memoKey)) return hit;
2521
- const level = resolveZcodeMinimalReasoningLevel(modelRef, this.deps.sources);
2522
- this.reasoningMemo.set(memoKey, level);
2523
- return level;
2877
+ const memoHit = this.reasoningMemo.get(memoKey);
2878
+ const domain = memoHit !== void 0 || this.reasoningMemo.has(memoKey) ? memoHit : resolveZcodeReasoningValues(modelRef, this.deps.sources);
2879
+ this.reasoningMemo.set(memoKey, domain);
2880
+ if (domain === void 0 || domain.length === 0) return void 0;
2881
+ const requested = thinkingLevel?.trim();
2882
+ if (requested === void 0 || requested === "") return domain[0];
2883
+ if (domain.includes(requested)) return requested;
2884
+ if (OFF_FAMILY_THINKING_LEVELS.has(requested)) return domain[0];
2885
+ const nonMinimal = domain.slice(1);
2886
+ return nonMinimal.length > 0 ? nonMinimal[nonMinimal.length - 1] : domain[0];
2524
2887
  }
2525
2888
  /**
2526
2889
  * [u-h2 D2-2] 派发同步期 model 校验:委托 resolveZcodeModelRef(与 run prepare 期
@@ -2570,7 +2933,7 @@ var ZcodeEngine = class {
2570
2933
  }
2571
2934
  } else {
2572
2935
  const poolDir = path4.resolve(
2573
- (0, import_subagent_engine_sdk11.resolvePoolDir)(this.deps.engineDataDir(), ZCODE_ENGINE_ID, import_subagent_engine_sdk11.SHARED_POOL_KEY)
2936
+ (0, import_subagent_engine_sdk12.resolvePoolDir)(this.deps.engineDataDir(), ZCODE_ENGINE_ID, import_subagent_engine_sdk12.SHARED_POOL_KEY)
2574
2937
  );
2575
2938
  const resolved = path4.resolve(poolDir, dbPathRaw);
2576
2939
  if (resolved.startsWith(poolDir + path4.sep)) {
@@ -2588,7 +2951,7 @@ var ZcodeEngine = class {
2588
2951
  logger4.warn("[zcode-engine] native session read failed, degrade to journal replay", {
2589
2952
  dbPath,
2590
2953
  sessionId,
2591
- reason: (0, import_subagent_engine_sdk4.toErrorMessage)(err)
2954
+ reason: (0, import_subagent_engine_sdk5.toErrorMessage)(err)
2592
2955
  });
2593
2956
  }
2594
2957
  }
@@ -2675,7 +3038,7 @@ var ZcodeEngine = class {
2675
3038
  buildPrompt(task, schema) {
2676
3039
  const segments = [...task.appendSystemPrompt ?? []];
2677
3040
  segments.push(task.prompt);
2678
- if (schema !== void 0) segments.push((0, import_subagent_engine_sdk11.buildSchemaEmulationSegment)(schema));
3041
+ if (schema !== void 0) segments.push((0, import_subagent_engine_sdk12.buildSchemaEmulationSegment)(schema));
2679
3042
  return segments.join("\n\n");
2680
3043
  }
2681
3044
  };
@@ -2718,7 +3081,7 @@ function isPlainObject(v) {
2718
3081
  return typeof v === "object" && v !== null && !Array.isArray(v);
2719
3082
  }
2720
3083
  function errMessage3(err) {
2721
- return (0, import_subagent_engine_sdk4.toErrorMessage)(err);
3084
+ return (0, import_subagent_engine_sdk5.toErrorMessage)(err);
2722
3085
  }
2723
3086
  function resolveAppserverTimingMs(envName, fallbackMs, label) {
2724
3087
  const raw = process.env[envName];
@@ -2830,7 +3193,7 @@ function parsedAppServerAttempt(task, r) {
2830
3193
  kind: "parsed",
2831
3194
  output: syntheticAppServerOutput(0),
2832
3195
  payload: turnResultToPayload(r),
2833
- ...schema !== void 0 ? { schemaResult: (0, import_subagent_engine_sdk11.extractAndValidateStructuredOutput)(r.response, schema) } : {}
3196
+ ...schema !== void 0 ? { schemaResult: (0, import_subagent_engine_sdk12.extractAndValidateStructuredOutput)(r.response, schema) } : {}
2834
3197
  };
2835
3198
  }
2836
3199
  function failedTerminalAppServerAttempt(r) {
@@ -2868,16 +3231,16 @@ function failedAppServerAttempt(err, currentSessionId, opts = {}) {
2868
3231
  };
2869
3232
  }
2870
3233
  function isHostTimeoutAbort(ctx) {
2871
- return ctx.signal?.aborted === true && ctx.signal.reason === import_subagent_engine_sdk11.HOST_TIMEOUT_ABORT_REASON;
3234
+ return ctx.signal?.aborted === true && ctx.signal.reason === import_subagent_engine_sdk12.HOST_TIMEOUT_ABORT_REASON;
2872
3235
  }
2873
3236
  var PROBE_STDOUT_CAP_CHARS = 4096;
2874
3237
  async function defaultProbeVersion(cliPath, dataDir) {
2875
3238
  try {
2876
3239
  return await new Promise((resolve2, reject) => {
2877
- const child = (0, import_subagent_engine_sdk11.spawnEngineChild)({
3240
+ const child = (0, import_subagent_engine_sdk12.spawnEngineChild)({
2878
3241
  command: "node",
2879
3242
  args: [cliPath, "--version"],
2880
- env: (0, import_subagent_engine_sdk11.buildEngineChildEnv)(process.env, { dataDir }),
3243
+ env: (0, import_subagent_engine_sdk12.buildEngineChildEnv)(process.env, { dataDir }),
2881
3244
  stdout: "pipe",
2882
3245
  stderr: "ignore",
2883
3246
  signal: AbortSignal.timeout(PROBE_VERSION_TIMEOUT_MS)
@@ -2895,7 +3258,7 @@ async function defaultProbeVersion(cliPath, dataDir) {
2895
3258
  });
2896
3259
  } catch (err) {
2897
3260
  logger4.debug(
2898
- `[zcode-engine] probe version check failed (best-effort continue): ${(0, import_subagent_engine_sdk4.toErrorMessage)(err)}`
3261
+ `[zcode-engine] probe version check failed (best-effort continue): ${(0, import_subagent_engine_sdk5.toErrorMessage)(err)}`
2899
3262
  );
2900
3263
  return void 0;
2901
3264
  }
@@ -2903,7 +3266,7 @@ async function defaultProbeVersion(cliPath, dataDir) {
2903
3266
 
2904
3267
  // src/registration.ts
2905
3268
  function defaultEngineDataDir() {
2906
- return (0, import_subagent_engine_sdk12.resolveEngineDataDir)(process.env);
3269
+ return (0, import_subagent_engine_sdk13.resolveEngineDataDir)(process.env);
2907
3270
  }
2908
3271
  function createZcodeEngine(deps) {
2909
3272
  return new ZcodeEngine(deps);
@@ -2916,11 +3279,11 @@ function createDefaultZcodeEngine() {
2916
3279
  }
2917
3280
 
2918
3281
  // src/port-types.ts
2919
- var import_subagent_engine_sdk13 = require("@zhushanwen/subagent-engine-sdk");
3282
+ var import_subagent_engine_sdk14 = require("@zhushanwen/subagent-engine-sdk");
2920
3283
 
2921
3284
  // src/server.ts
2922
3285
  var import_server = require("@zhushanwen/subagent-engine-sdk/server");
2923
- var logger5 = (0, import_subagent_engine_sdk14.getLogger)("subagents");
3286
+ var logger5 = (0, import_subagent_engine_sdk15.getLogger)("subagents");
2924
3287
  var EngineProtocolServer = class {
2925
3288
  write;
2926
3289
  engine;
@@ -2990,7 +3353,7 @@ var EngineProtocolServer = class {
2990
3353
  const active = { controller, seq: 0 };
2991
3354
  this.activeRuns.set(runId, active);
2992
3355
  const fullTask = (0, import_server.assembleFullTask)(task, ctx);
2993
- const ctxModel = (0, import_subagent_engine_sdk13.parseCtxModel)(ctx.ctxModel);
3356
+ const ctxModel = (0, import_subagent_engine_sdk14.parseCtxModel)(ctx.ctxModel);
2994
3357
  const stream = ctx.streamMode === "stream" ? {
2995
3358
  onDelta: (delta) => {
2996
3359
  void this.reverseRequestInternal("host/streamDelta", { runId, delta }).catch(this.warnReverseFailure("host/streamDelta", `run ${runId}`));
@@ -3026,7 +3389,7 @@ var EngineProtocolServer = class {
3026
3389
  }
3027
3390
  validateModel(params) {
3028
3391
  if (this.engine.validateModel === void 0) {
3029
- throw new import_subagent_engine_sdk14.EngineSdkError(
3392
+ throw new import_subagent_engine_sdk15.EngineSdkError(
3030
3393
  "engine_capability_unsupported",
3031
3394
  "engine does not implement validateModel",
3032
3395
  "Manifest omits modelCatalog; model validation falls back to run-time engine checks."
@@ -3053,7 +3416,7 @@ var EngineProtocolServer = class {
3053
3416
  warnReverseFailure(method, context) {
3054
3417
  return (err) => {
3055
3418
  logger5.warn(`[protocol] ${method} reverse request failed (${context}); continuing without it`, {
3056
- detail: (0, import_subagent_engine_sdk4.toErrorMessage)(err)
3419
+ detail: (0, import_subagent_engine_sdk5.toErrorMessage)(err)
3057
3420
  });
3058
3421
  };
3059
3422
  }
@@ -3082,7 +3445,7 @@ var EngineProtocolServer = class {
3082
3445
  clearTimeout(pending.timer);
3083
3446
  this.reverseClock?.acked(String(id));
3084
3447
  this.reverseClock?.settled(String(id));
3085
- if (frame.error !== void 0) pending.reject(new Error(`reverse request ${String(id)} rejected: ${(0, import_subagent_engine_sdk4.toErrorMessage)(frame.error)}`));
3448
+ if (frame.error !== void 0) pending.reject(new Error(`reverse request ${String(id)} rejected: ${(0, import_subagent_engine_sdk5.toErrorMessage)(frame.error)}`));
3086
3449
  else pending.resolve(frame.result);
3087
3450
  }
3088
3451
  };