@zhushanwen/zcode-subagent-cli 0.4.1 → 0.4.2
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/{chunk-U56IBQ47.js → chunk-F6YT6OGA.js} +250 -69
- package/dist/index.cjs +249 -69
- package/dist/index.d.cts +40 -7
- package/dist/index.d.ts +40 -7
- package/dist/index.js +1 -1
- package/dist/main.cjs +249 -69
- package/dist/main.js +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -49,6 +49,13 @@ declare class EngineProtocolServer {
|
|
|
49
49
|
* 应答超时兜底 reject——数据面通道(host/log 等)core 10s 应答,reject 由调用方
|
|
50
50
|
* 吞掉留痕(数据面丢失不拖死主链路)。
|
|
51
51
|
*/
|
|
52
|
+
/**
|
|
53
|
+
* fire-and-forget 反向请求(`void this.reverseRequestInternal(...)` 形态)的
|
|
54
|
+
* rejection 兜底:60s 超时(reverseRequestInternal 计时器)或宿主 error 帧
|
|
55
|
+
* (settleReverse)都会 reject——无 handler 即 unhandled rejection(Node ≥15
|
|
56
|
+
* 默认崩引擎进程)。失败只降级该次通道上报,warn 留痕不断流。
|
|
57
|
+
*/
|
|
58
|
+
private warnReverseFailure;
|
|
52
59
|
/** 反向请求发送(公开面:main.ts 的 host/log 桥接消费;内部 run 通道同路)。 */
|
|
53
60
|
reverseRequest(method: string, params: unknown): Promise<unknown>;
|
|
54
61
|
private reverseRequestInternal;
|
|
@@ -57,8 +64,12 @@ declare class EngineProtocolServer {
|
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
interface ZcodeSourcePaths {
|
|
60
|
-
/**
|
|
67
|
+
/** 个人 provider 注册表源(app-server 注册表对齐)。缺省 ~/.zcode/v2/provider_config.json。 */
|
|
68
|
+
personalProviderConfigPath?: string;
|
|
69
|
+
/** launcher 凭据注入的 v2 config 源(ZCODE_ENG_V2_CONFIG 消费——凭据供数面,与模型校验源无关)。缺省 ~/.zcode/v2/config.json。 */
|
|
61
70
|
v2ConfigPath?: string;
|
|
71
|
+
/** 内建 provider 目录源(reasoningLevel 值域解析)。缺省按 runtime/provider 目录扫描(与 launcher 同型)。 */
|
|
72
|
+
builtinCatalogPath?: string;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
/** ZcodeEngine 构造依赖(全部可注入——测试不依赖真机 CLI/真凭据)。 */
|
|
@@ -148,6 +159,24 @@ declare class ZcodeEngine implements EnginePort {
|
|
|
148
159
|
* retried:瞬时重试轮标记——失败文案补「已自动重试一次」句(F-1/F-4)。
|
|
149
160
|
*/
|
|
150
161
|
private attemptAppServerTurn;
|
|
162
|
+
/**
|
|
163
|
+
* [attemptAppServerTurn 拆分] 失败分流(catch 半边):
|
|
164
|
+
* - signal 已 aborted → 中止终态收口;
|
|
165
|
+
* - [P0-1 U2] 超时入口(D3 v1.1):turn 已被 channel 判死 reject——升级判据不能
|
|
166
|
+
* 再挂在 turn 落定上(race 恒真,killChain 结构性不可达的 v1 击穿点),改以
|
|
167
|
+
* stop 应答三态裁决。await 链终局(非 fire-and-forget):outcome 止损文案与
|
|
168
|
+
* 重试时序(D6,u-z4)都依赖链终局信号——止损完成前不合成终态。timeout 类
|
|
169
|
+
* (idle/ceiling 都算)是 D6 明文的可重试形态——结构化标记
|
|
170
|
+
* (TurnTimeoutError 类型化判据,不经字符串匹配,D4 同精神);
|
|
171
|
+
* - [P0-1 U4] 连接崩溃收割形态(failAllTurns 的错误,D6 第二可重试形态)判据:
|
|
172
|
+
* 非 RPC error(服务端无明确应答——有应答即精确错误归类,非瞬时崩溃面)且
|
|
173
|
+
* conn 不存活。时序可靠性:catch 时刻紧随 onClose 收割,连接重建仅由
|
|
174
|
+
* conn.request 惰性触发——本链路中 runTurn finally 的 closeSession 对死连接
|
|
175
|
+
* 短路(channel 侧 !alive 守卫)、stop 只属 abort/超时入口(前者已被
|
|
176
|
+
* signal.aborted 短路、后者走上一分支)——此刻无 request 可重建,判据可靠;
|
|
177
|
+
* - 其余 → 精确错误终态。
|
|
178
|
+
*/
|
|
179
|
+
private classifyAppServerTurnFailure;
|
|
151
180
|
/**
|
|
152
181
|
* killChain 后等待连接 finalize 实际完成(child 置空 + onClose 广播)再宣告链终局:
|
|
153
182
|
* shutdown resolve 于 `exit` 事件,而 finalize 挂 `close`(stdio 排空)——两者之间的
|
|
@@ -224,11 +253,15 @@ declare class ZcodeEngine implements EnginePort {
|
|
|
224
253
|
private applyRunFailedOutcome;
|
|
225
254
|
/** parsed 合成终态:content/sessionId/usage 落位 + schema 校验分流 + coarse 事件。 */
|
|
226
255
|
private applyParsedOutcome;
|
|
227
|
-
/** [U7] 模型可发现性:
|
|
256
|
+
/** [U7] 模型可发现性:provider_config 个人 provider 聚合(注册表实况对齐源),失败安全返回清单本身可能为空。 */
|
|
228
257
|
listModels(): Array<{
|
|
229
258
|
id: string;
|
|
230
259
|
name?: string;
|
|
231
260
|
}>;
|
|
261
|
+
/** 显式模型的最小 reasoning 档(目录 modelRules 值域;per-modelRef 记忆化——
|
|
262
|
+
* 目录文件在引擎进程生命周期内视为静态,重复 run 不重读)。 */
|
|
263
|
+
private readonly reasoningMemo;
|
|
264
|
+
private minimalReasoningFor;
|
|
232
265
|
/**
|
|
233
266
|
* [u-h2 D2-2] 派发同步期 model 校验:委托 resolveZcodeModelRef(与 run prepare 期
|
|
234
267
|
* 显式路径同一函数——canonicalRef 归一化、短名缺省 provider、凭据与清单校验单一
|
|
@@ -237,11 +270,11 @@ declare class ZcodeEngine implements EnginePort {
|
|
|
237
270
|
*
|
|
238
271
|
* [R4/D6-②] 缺席语义:本实现是进程内形态 + 协议诊断面(宿主 cli 形态消费的是
|
|
239
272
|
* RemoteEngine 的 manifest 本地判定,不经本方法——SDK protocol methods.ts 明示
|
|
240
|
-
* validateModel 为诊断面)。缺席 modelRef
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* port-contract
|
|
244
|
-
* server handler 签名,非本包单方面可完成)。
|
|
273
|
+
* validateModel 为诊断面)。缺席 modelRef 时返回空串 canonical(= create 帧省略
|
|
274
|
+
* model 键、CLI 自身缺省解析——2026-09-29 account 体系迁移后 plan 家族兜底 id
|
|
275
|
+
* 已不可用;record 留痕侧按 R4/D6-② 空串归一为「用户未指定」条件留空)。帧应答
|
|
276
|
+
* 形态维持 {canonicalRef: string}(SDK port-contract 契约必填——「帧字段缺席」
|
|
277
|
+
* 的 optional 对齐需放宽 SDK 契约与 server handler 签名,非本包单方面可完成)。
|
|
245
278
|
*/
|
|
246
279
|
validateModel(modelRef: string | undefined): {
|
|
247
280
|
canonicalRef: string;
|
package/dist/index.js
CHANGED
package/dist/main.cjs
CHANGED
|
@@ -33,7 +33,7 @@ var ZCODE_ENGINE_ID = "zcode";
|
|
|
33
33
|
var ZCODE_ADAPTER_VERSION = "2.0.0";
|
|
34
34
|
var ZCODE_CLI_DEFAULT_PATH = "/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs";
|
|
35
35
|
var ZCODE_V2_CONFIG_PATH_SUFFIX = [".zcode", "v2", "config.json"];
|
|
36
|
-
var
|
|
36
|
+
var ZCODE_PERSONAL_PROVIDER_CONFIG_PATH_SUFFIX = [".zcode", "v2", "provider_config.json"];
|
|
37
37
|
var ZCODE_KILL_GRACE_MS = 5e3;
|
|
38
38
|
var ZCODE_ERROR_TAIL_CHARS = 2e3;
|
|
39
39
|
var ZCODE_APPSERVER_REQUEST_TIMEOUT_MS = 15e3;
|
|
@@ -160,11 +160,11 @@ var ZcodePrepareError = class extends Error {
|
|
|
160
160
|
function isRecord(v) {
|
|
161
161
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
162
162
|
}
|
|
163
|
-
function
|
|
164
|
-
return
|
|
163
|
+
function strArray(v) {
|
|
164
|
+
return Array.isArray(v) ? v.filter((m) => typeof m === "string" && m.trim() !== "") : [];
|
|
165
165
|
}
|
|
166
166
|
function readSourceConfig(absPath) {
|
|
167
|
-
const empty = { providers: /* @__PURE__ */ new Map() };
|
|
167
|
+
const empty = { providers: /* @__PURE__ */ new Map(), order: [] };
|
|
168
168
|
let raw;
|
|
169
169
|
try {
|
|
170
170
|
raw = fs.readFileSync(absPath, "utf8");
|
|
@@ -178,15 +178,30 @@ function readSourceConfig(absPath) {
|
|
|
178
178
|
return empty;
|
|
179
179
|
}
|
|
180
180
|
if (!isRecord(parsed)) return empty;
|
|
181
|
-
const
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
181
|
+
const rules = parsed["config"]?.["providerConfigRules"];
|
|
182
|
+
const providerRules = !isRecord(rules) ? void 0 : rules["providerRules"];
|
|
183
|
+
const orderSrc = parsed["config"]?.["providerOrder"];
|
|
184
|
+
const conf = { providers: /* @__PURE__ */ new Map(), order: strArray(orderSrc) };
|
|
185
|
+
if (!Array.isArray(providerRules)) return conf;
|
|
186
|
+
collectProviderRules(providerRules, conf);
|
|
188
187
|
return conf;
|
|
189
188
|
}
|
|
189
|
+
function collectProviderRules(providerRules, conf) {
|
|
190
|
+
for (const rule of providerRules) {
|
|
191
|
+
if (!isRecord(rule)) continue;
|
|
192
|
+
const id = rule["providerId"];
|
|
193
|
+
if (typeof id !== "string" || id.trim() === "") continue;
|
|
194
|
+
const cfg = isRecord(rule["config"]) ? rule["config"] : {};
|
|
195
|
+
const access = isRecord(cfg["access"]) ? cfg["access"] : {};
|
|
196
|
+
const apiKey = access["apiKey"];
|
|
197
|
+
const personal = strArray(cfg["personalModelIds"]);
|
|
198
|
+
conf.providers.set(id, {
|
|
199
|
+
providerName: typeof rule["providerName"] === "string" ? rule["providerName"] : void 0,
|
|
200
|
+
apiKey: typeof apiKey === "string" && apiKey !== "" ? apiKey : void 0,
|
|
201
|
+
models: personal.length > 0 ? personal : strArray(cfg["modelOrder"])
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
190
205
|
function modelShort(ref) {
|
|
191
206
|
return ref.slice(ref.lastIndexOf("/") + 1);
|
|
192
207
|
}
|
|
@@ -197,63 +212,148 @@ function splitZcodeModelRef(modelRef) {
|
|
|
197
212
|
return { providerId: providerOf(modelRef), modelId: modelShort(modelRef) };
|
|
198
213
|
}
|
|
199
214
|
function hasApiKey(entry) {
|
|
200
|
-
|
|
201
|
-
|
|
215
|
+
return typeof entry.apiKey === "string" && entry.apiKey !== "";
|
|
216
|
+
}
|
|
217
|
+
function defaultPersonalProviderConfigPath() {
|
|
218
|
+
return path2.join(os2.homedir(), ...ZCODE_PERSONAL_PROVIDER_CONFIG_PATH_SUFFIX);
|
|
202
219
|
}
|
|
203
220
|
function defaultV2ConfigPath() {
|
|
204
221
|
return path2.join(os2.homedir(), ...ZCODE_V2_CONFIG_PATH_SUFFIX);
|
|
205
222
|
}
|
|
206
|
-
var
|
|
207
|
-
function
|
|
208
|
-
if (
|
|
223
|
+
var SEMVER_SEGMENTS = 3;
|
|
224
|
+
function locateZcodeBuiltinCatalog(sources) {
|
|
225
|
+
if (sources?.builtinCatalogPath !== void 0) return sources.builtinCatalogPath;
|
|
226
|
+
const fromEnv = process.env["ZCODE_BUILTIN_PROVIDER_CONFIG_FILE"]?.trim();
|
|
227
|
+
if (fromEnv !== void 0 && fromEnv !== "") return fromEnv;
|
|
228
|
+
try {
|
|
229
|
+
const providerRoot = path2.join(os2.homedir(), ".zcode", "v2", "runtime", "provider");
|
|
230
|
+
const prefix = `${process.platform}-`;
|
|
231
|
+
const platDirs = fs.readdirSync(providerRoot, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.startsWith(prefix)).map((d) => d.name);
|
|
232
|
+
const byVerDesc = (a, b) => {
|
|
233
|
+
const pa = a.split(".");
|
|
234
|
+
const pb = b.split(".");
|
|
235
|
+
for (let i = 0; i < SEMVER_SEGMENTS; i++) {
|
|
236
|
+
const na = Number.parseInt(pa[i] ?? "", 10) || 0;
|
|
237
|
+
const nb = Number.parseInt(pb[i] ?? "", 10) || 0;
|
|
238
|
+
if (na !== nb) return nb - na;
|
|
239
|
+
}
|
|
240
|
+
return 0;
|
|
241
|
+
};
|
|
242
|
+
for (const plat of platDirs) {
|
|
243
|
+
const rtRoot = path2.join(providerRoot, plat);
|
|
244
|
+
let versions = [];
|
|
245
|
+
try {
|
|
246
|
+
versions = fs.readdirSync(rtRoot).filter((v) => /^\d+\.\d+/.test(v)).sort(byVerDesc);
|
|
247
|
+
} catch {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
for (const ver of versions) {
|
|
251
|
+
const verDir = path2.join(rtRoot, ver);
|
|
252
|
+
let endpoints = [];
|
|
253
|
+
try {
|
|
254
|
+
endpoints = fs.readdirSync(verDir).filter((e) => e.startsWith("endpoint-")).sort();
|
|
255
|
+
} catch {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
for (const ep of endpoints) {
|
|
259
|
+
const candidate = path2.join(verDir, ep, "zcode-builtin.json");
|
|
260
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
} catch {
|
|
265
|
+
return void 0;
|
|
266
|
+
}
|
|
267
|
+
return void 0;
|
|
268
|
+
}
|
|
269
|
+
function resolveZcodeMinimalReasoningLevel(modelRef, sources) {
|
|
270
|
+
const catalogPath = locateZcodeBuiltinCatalog(sources);
|
|
271
|
+
if (catalogPath === void 0) return void 0;
|
|
272
|
+
let parsed;
|
|
273
|
+
try {
|
|
274
|
+
parsed = JSON.parse(fs.readFileSync(catalogPath, "utf8"));
|
|
275
|
+
} catch {
|
|
276
|
+
return void 0;
|
|
277
|
+
}
|
|
278
|
+
const modelId = modelShort(modelRef);
|
|
279
|
+
const rules = parsed["config"];
|
|
280
|
+
const modelRules = isRecord(rules) && isRecord(rules["modelConfigRules"]) ? rules["modelConfigRules"]["modelRules"] : void 0;
|
|
281
|
+
if (!Array.isArray(modelRules)) return void 0;
|
|
282
|
+
return lastMatchingReasoningValues(modelRules, modelId)?.[0];
|
|
283
|
+
}
|
|
284
|
+
function lastMatchingReasoningValues(modelRules, modelId) {
|
|
285
|
+
let values;
|
|
286
|
+
for (const rule of modelRules) {
|
|
287
|
+
if (!isRecord(rule)) continue;
|
|
288
|
+
const match = rule["modelMatch"];
|
|
289
|
+
if (typeof match !== "string") continue;
|
|
290
|
+
let re;
|
|
291
|
+
try {
|
|
292
|
+
re = new RegExp(match);
|
|
293
|
+
} catch {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (!re.test(modelId)) continue;
|
|
297
|
+
const spec = rule["config"]?.["optionSpecs"];
|
|
298
|
+
const level = isRecord(spec) ? spec["reasoningLevel"] : void 0;
|
|
299
|
+
const vals = isRecord(level) ? strArray(level["values"]) : [];
|
|
300
|
+
if (vals.length > 0) values = vals;
|
|
301
|
+
}
|
|
302
|
+
return values;
|
|
303
|
+
}
|
|
304
|
+
function defaultProviderForShortName(conf, withKey) {
|
|
305
|
+
const ordered = conf.order.find((id) => {
|
|
306
|
+
const entry = conf.providers.get(id);
|
|
307
|
+
return entry !== void 0 && hasApiKey(entry);
|
|
308
|
+
});
|
|
309
|
+
if (ordered !== void 0) return ordered;
|
|
209
310
|
return withKey[0][0];
|
|
210
311
|
}
|
|
211
312
|
function resolveZcodeModelRef(requested, sources) {
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
const withKey = [...
|
|
313
|
+
const srcPath = sources?.personalProviderConfigPath ?? defaultPersonalProviderConfigPath();
|
|
314
|
+
const conf = readSourceConfig(srcPath);
|
|
315
|
+
const withKey = [...conf.providers.entries()].filter(([, e]) => hasApiKey(e));
|
|
215
316
|
const wanted = requested?.trim() || void 0;
|
|
216
|
-
const target = wanted ?? ZCODE_FALLBACK_DEFAULT_MODEL;
|
|
217
317
|
if (withKey.length === 0) {
|
|
218
|
-
const hint = wanted ? `model="${wanted}" \u4E0D\u80FD\u6821\u9A8C` :
|
|
318
|
+
const hint = wanted ? `model="${wanted}" \u4E0D\u80FD\u6821\u9A8C` : "\u7F3A\u7701\u6A21\u578B\u89E3\u6790\u4E0D\u80FD\u6821\u9A8C";
|
|
219
319
|
throw new ZcodePrepareError(
|
|
220
320
|
"engine_credential_missing",
|
|
221
|
-
`zcode \u5F15\u64CE\u627E\u4E0D\u5230\u4EFB\u4F55\u5E26 apiKey \u7684 provider\uFF08${hint}\uFF09\u3002\u5DF2\u8BFB\u6E90\uFF1A${
|
|
321
|
+
`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`
|
|
222
322
|
);
|
|
223
323
|
}
|
|
224
|
-
|
|
225
|
-
const
|
|
226
|
-
const
|
|
324
|
+
if (wanted === void 0) return "";
|
|
325
|
+
const provider = wanted.includes("/") ? providerOf(wanted) : defaultProviderForShortName(conf, withKey);
|
|
326
|
+
const short = modelShort(wanted);
|
|
327
|
+
const entry = conf.providers.get(provider);
|
|
227
328
|
if (!entry) {
|
|
228
329
|
const known = withKey.map(([id]) => id).join(", ");
|
|
229
330
|
throw new ZcodePrepareError(
|
|
230
331
|
"model_not_available",
|
|
231
|
-
`\u672A\u77E5 provider "${provider}"\uFF08\u5E26\u51ED\u636E\u7684 provider: ${known}\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u4E0A\u8FF0 provider \u4E4B\u4E00\uFF08\u5168\u540D provider/model\uFF09\uFF0C\u6216\
|
|
332
|
+
`\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`
|
|
232
333
|
);
|
|
233
334
|
}
|
|
234
335
|
if (!hasApiKey(entry)) {
|
|
235
336
|
throw new ZcodePrepareError(
|
|
236
337
|
"engine_credential_missing",
|
|
237
|
-
`provider "${provider}" \u5B58\u5728\u4F46\u672A\u914D\u7F6E apiKey\u3002\u6062\u590D\u6307\u5F15\uFF1A\u5728 ZCode \u684C\u9762\u7AEF\u4E3A\u8BE5 provider \
|
|
338
|
+
`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`
|
|
238
339
|
);
|
|
239
340
|
}
|
|
240
|
-
const models =
|
|
341
|
+
const models = entry.models ?? [];
|
|
241
342
|
if (models.length > 0 && !models.includes(short)) {
|
|
242
343
|
throw new ZcodePrepareError(
|
|
243
344
|
"model_not_available",
|
|
244
|
-
`\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\
|
|
345
|
+
`\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`
|
|
245
346
|
);
|
|
246
347
|
}
|
|
247
348
|
return `${provider}/${short}`;
|
|
248
349
|
}
|
|
249
350
|
function listZcodeModels(sources) {
|
|
250
|
-
const
|
|
351
|
+
const conf = readSourceConfig(sources?.personalProviderConfigPath ?? defaultPersonalProviderConfigPath());
|
|
251
352
|
const out = [];
|
|
252
|
-
for (const [pid, entry] of
|
|
353
|
+
for (const [pid, entry] of conf.providers) {
|
|
253
354
|
if (!hasApiKey(entry)) continue;
|
|
254
|
-
const providerName =
|
|
255
|
-
const
|
|
256
|
-
for (const model of models) {
|
|
355
|
+
const providerName = entry.providerName !== void 0 && entry.providerName.trim() !== "" ? entry.providerName.trim() : void 0;
|
|
356
|
+
for (const model of entry.models ?? []) {
|
|
257
357
|
out.push({
|
|
258
358
|
id: `${pid}/${model}`,
|
|
259
359
|
...providerName !== void 0 ? { name: `${providerName} \xB7 ${model}` } : {}
|
|
@@ -281,13 +381,13 @@ const os = require('node:os');
|
|
|
281
381
|
const CLI_PATH = process.env.ZCODE_ENG_CLI_PATH;
|
|
282
382
|
const V2_PATH = process.env.ZCODE_ENG_V2_CONFIG || path.join(os.homedir(), '.zcode', 'v2', 'config.json');
|
|
283
383
|
const CONFIG_PATH = path.join(os.homedir(), '.zcode', 'cli', 'config.json');
|
|
284
|
-
// \u4E0E constants.ts ZCODE_FALLBACK_DEFAULT_MODEL \u53CC\u6E90\uFF08\u5185\u5D4C\u5B57\u7B26\u4E32\u65E0\u6CD5 import\uFF09\u2014\u2014\u6539\u90A3\u8FB9\u987B\u540C\u6B65\u6B64\u5904
|
|
285
|
-
const FALLBACK_MODEL_MAIN = 'builtin:bigmodel-coding-plan/GLM-5.3';
|
|
286
384
|
|
|
287
385
|
// \u5408\u5E76\u5F62\u6001\uFF1A\u771F\u5B9E cli config \u539F\u6837\uFF08model/plugins/mcp/subagents \u7B49 worker \u7EE7\u627F\u9762\u4E0D\u53D8\uFF09
|
|
288
386
|
// + v2 \u7684 provider \u5B57\u5178\u6CE8\u5165\uFF0C\u540C id \u65F6 v2 \u6761\u76EE\u6574\u6761\u4F18\u5148\u2014\u2014GUI \u76F4\u4F20 modelConfig \u65F6
|
|
289
387
|
// v2 \u5373\u6743\u5A01\u6E90\uFF08\u8FDB\u7A0B\u5916\u7B49\u4EF7\u590D\u523B\uFF09\uFF1Bcli config \u4E0D\u5728 GUI \u7BA1\u7406\u9762\u3001\u53EF\u80FD\u6B8B\u7559\u5386\u53F2\u9A8C\u8BC1
|
|
290
388
|
// \u914D\u7F6E\uFF082026-08-25 \u4E8B\u6545\uFF1A\u6B8B\u7559\u65E7 key \u538B\u8FC7\u65B0\u51ED\u636E\u81F4 turn 0 401\uFF09\uFF0C\u6545\u4E0D\u53D6 real \u4F18\u5148\u3002
|
|
389
|
+
// model.main \u7F3A\u5931\u65F6\u53EA\u4ECE v2 \u900F\u4F20\uFF08v2 \u4E5F\u6CA1\u6709\u5219\u4E0D\u4F2A\u9020\u2014\u2014CLI \u7F3A\u7701\u89E3\u6790\u81EA\u4F1A\u843D\u5230\u6CE8\u518C\u8868
|
|
390
|
+
// \u53EF\u7528\u6A21\u578B\uFF1Bplan \u5BB6\u65CF id \u5DF2\u4E0D\u53EF\u7528\uFF0C\u4E0D\u518D\u515C\u5E95\u4F2A\u9020\uFF09\u3002
|
|
291
391
|
// \u8FD4\u56DE null = \u65E0\u53EF\u6CE8\u5165\u51ED\u636E\uFF08v2 \u65E0 provider \u6761\u76EE\uFF09\u2014\u2014\u4E0D patch\uFF0C\u8BA9\u539F\u751F\u62A5\u9519\u900F\u51FA\u3002
|
|
292
392
|
// \u8BFB\u6E90\u7ECF readOrig \u95F4\u63A5\u53D6\uFF1Apatch \u524D\u9996\u8C03 = fs.readFileSync \u672C\u4F53\uFF1Bpatch \u540E = \u539F\u51FD\u6570
|
|
293
393
|
// \uFF08\u9632 patch \u540E\u7684\u9012\u5F52\u81EA\u8C03\u7528\uFF09\u3002
|
|
@@ -315,9 +415,9 @@ function injectedConfigText() {
|
|
|
315
415
|
if (Object.keys(injectable).length === 0) return null;
|
|
316
416
|
const merged = { ...real };
|
|
317
417
|
merged.provider = { ...(real.provider && typeof real.provider === 'object' ? real.provider : {}), ...injectable };
|
|
318
|
-
if (!merged.model || typeof merged.model !== 'object' || !merged.model.main)
|
|
319
|
-
|
|
320
|
-
merged.model = { ...(merged.model || {}), main };
|
|
418
|
+
if ((!merged.model || typeof merged.model !== 'object' || !merged.model.main)
|
|
419
|
+
&& v2.model && typeof v2.model === 'object' && v2.model.main) {
|
|
420
|
+
merged.model = { ...(merged.model || {}), main: v2.model.main };
|
|
321
421
|
}
|
|
322
422
|
return JSON.stringify(merged);
|
|
323
423
|
}
|
|
@@ -415,6 +515,23 @@ if (!process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE) {
|
|
|
415
515
|
}
|
|
416
516
|
} catch { /* provider \u76EE\u5F55\u7F3A\u5931/\u4E0D\u53EF\u8BFB \u2192 \u4E0D\u8BBE\u952E */ }
|
|
417
517
|
if (located) process.env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE = located;
|
|
518
|
+
// endpoint origin \u5BF9\u9F50\uFF082026-09-29 \u8FC1\u79FB\u540C\u6B65\uFF09\uFF1ACLI \u6309 ZCODE_BASE_URL \u6D3E\u751F active
|
|
519
|
+
// \u76EE\u5F55\u8DEF\u5F84\uFF08sha256(origin) \u524D\u7F00\uFF09\uFF1BGUI \u5B89\u88C5\u7684\u76EE\u5F55\u5728 refresh \u63A7\u5236\u6587\u4EF6\u7684 endpointKey
|
|
520
|
+
// \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
|
|
521
|
+
// active \u8DEF\u5F84\u7B97\u5230\u4E0D\u5B58\u5728\u7684\u76EE\u5F55\uFF0C\u89E6\u53D1\u65E0\u8C13\u7684\u8054\u7F51\u91CD\u88C5\u5C1D\u8BD5\u3002\u4ECE\u5DF2\u5B9A\u4F4D\u76EE\u5F55\u7684\u90BB\u4F4D\u63A7\u5236
|
|
522
|
+
// \u6587\u4EF6\u8BFB\u51FA origin \u6CE8\u5165\uFF08\u65E0\u786C\u7F16\u7801\uFF09\uFF1B\u663E\u5F0F env \u4F18\u5148\uFF0C\u4E0D\u8986\u76D6\u3002
|
|
523
|
+
if (located && !process.env.ZCODE_BASE_URL && !process.env.ZCODE_ENDPOINT_ORIGIN) {
|
|
524
|
+
try {
|
|
525
|
+
const ctlPath = path.join(path.dirname(located), 'zcode-builtin-refresh.json');
|
|
526
|
+
const ctlText = fs.__origReadFileSync
|
|
527
|
+
? fs.__origReadFileSync.call(fs, ctlPath, 'utf8')
|
|
528
|
+
: fs.readFileSync(ctlPath, 'utf8');
|
|
529
|
+
const ctl = JSON.parse(ctlText);
|
|
530
|
+
if (ctl && typeof ctl.endpointKey === 'string' && ctl.endpointKey.indexOf('http') === 0) {
|
|
531
|
+
process.env.ZCODE_BASE_URL = ctl.endpointKey;
|
|
532
|
+
}
|
|
533
|
+
} catch { /* \u63A7\u5236\u6587\u4EF6\u7F3A\u5931/\u635F\u574F \u2192 \u4E0D\u6CE8\u5165\uFF08CLI \u7528\u7F3A\u7701 origin \u6D3E\u751F\uFF09 */ }
|
|
534
|
+
}
|
|
418
535
|
}
|
|
419
536
|
|
|
420
537
|
// \u4E0A\u6E38 provider bootstrap \u4EE5 argv[1] \u4E3A\u5165\u53E3\u951A\uFF0C\u4ECE\u8BE5\u8DEF\u5F84\u90BB\u8FD1\u5B9A\u4F4D CLI \u5185\u5EFA
|
|
@@ -2161,7 +2278,8 @@ var ZcodeEngine = class {
|
|
|
2161
2278
|
*/
|
|
2162
2279
|
async attemptAppServerTurn(task, ctx, modelRef, cwd, prompt, opts = {}) {
|
|
2163
2280
|
const rt = this.ensureAppServerRuntime();
|
|
2164
|
-
const
|
|
2281
|
+
const reasoningLevel = modelRef !== void 0 && modelRef !== "" ? this.minimalReasoningFor(modelRef) : void 0;
|
|
2282
|
+
const createParams = buildAppServerCreateParams(task, modelRef, cwd, reasoningLevel);
|
|
2165
2283
|
let currentSessionId;
|
|
2166
2284
|
let signalSessionCreated;
|
|
2167
2285
|
const sessionCreated = new Promise((resolve2) => {
|
|
@@ -2202,26 +2320,52 @@ var ZcodeEngine = class {
|
|
|
2202
2320
|
if (ctx.signal?.aborted === true) return abortedAppServerAttempt(ctx);
|
|
2203
2321
|
return parsedAppServerAttempt(task, r);
|
|
2204
2322
|
} catch (err) {
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
{ escalateOn: "stop-outcome" }
|
|
2213
|
-
);
|
|
2214
|
-
return timeoutAppServerAttempt(err, currentSessionId, stopPath, { retried: opts.retried });
|
|
2215
|
-
}
|
|
2216
|
-
if (!isAppServerRpcError(err) && !rt.conn.alive) {
|
|
2217
|
-
return failedAppServerAttempt(err, currentSessionId, { retried: opts.retried, transient: "conn-closed" });
|
|
2218
|
-
}
|
|
2219
|
-
return failedAppServerAttempt(err, currentSessionId, { retried: opts.retried });
|
|
2323
|
+
return await this.classifyAppServerTurnFailure(err, ctx, {
|
|
2324
|
+
rt,
|
|
2325
|
+
turn,
|
|
2326
|
+
currentSessionId: () => currentSessionId,
|
|
2327
|
+
sessionCreated,
|
|
2328
|
+
retried: opts.retried
|
|
2329
|
+
});
|
|
2220
2330
|
} finally {
|
|
2221
2331
|
if (currentSessionId !== void 0) rt.activeSessions.delete(currentSessionId);
|
|
2222
2332
|
if (ctx.signal !== void 0) ctx.signal.removeEventListener("abort", onAbort);
|
|
2223
2333
|
}
|
|
2224
2334
|
}
|
|
2335
|
+
/**
|
|
2336
|
+
* [attemptAppServerTurn 拆分] 失败分流(catch 半边):
|
|
2337
|
+
* - signal 已 aborted → 中止终态收口;
|
|
2338
|
+
* - [P0-1 U2] 超时入口(D3 v1.1):turn 已被 channel 判死 reject——升级判据不能
|
|
2339
|
+
* 再挂在 turn 落定上(race 恒真,killChain 结构性不可达的 v1 击穿点),改以
|
|
2340
|
+
* stop 应答三态裁决。await 链终局(非 fire-and-forget):outcome 止损文案与
|
|
2341
|
+
* 重试时序(D6,u-z4)都依赖链终局信号——止损完成前不合成终态。timeout 类
|
|
2342
|
+
* (idle/ceiling 都算)是 D6 明文的可重试形态——结构化标记
|
|
2343
|
+
* (TurnTimeoutError 类型化判据,不经字符串匹配,D4 同精神);
|
|
2344
|
+
* - [P0-1 U4] 连接崩溃收割形态(failAllTurns 的错误,D6 第二可重试形态)判据:
|
|
2345
|
+
* 非 RPC error(服务端无明确应答——有应答即精确错误归类,非瞬时崩溃面)且
|
|
2346
|
+
* conn 不存活。时序可靠性:catch 时刻紧随 onClose 收割,连接重建仅由
|
|
2347
|
+
* conn.request 惰性触发——本链路中 runTurn finally 的 closeSession 对死连接
|
|
2348
|
+
* 短路(channel 侧 !alive 守卫)、stop 只属 abort/超时入口(前者已被
|
|
2349
|
+
* signal.aborted 短路、后者走上一分支)——此刻无 request 可重建,判据可靠;
|
|
2350
|
+
* - 其余 → 精确错误终态。
|
|
2351
|
+
*/
|
|
2352
|
+
async classifyAppServerTurnFailure(err, ctx, args) {
|
|
2353
|
+
if (ctx.signal?.aborted === true) return abortedAppServerAttempt(ctx);
|
|
2354
|
+
if (err instanceof TurnTimeoutError) {
|
|
2355
|
+
const stopPath = await this.appServerAbortChain(
|
|
2356
|
+
args.rt,
|
|
2357
|
+
args.turn,
|
|
2358
|
+
args.currentSessionId,
|
|
2359
|
+
args.sessionCreated,
|
|
2360
|
+
{ escalateOn: "stop-outcome" }
|
|
2361
|
+
);
|
|
2362
|
+
return timeoutAppServerAttempt(err, args.currentSessionId(), stopPath, { retried: args.retried });
|
|
2363
|
+
}
|
|
2364
|
+
if (!isAppServerRpcError(err) && !args.rt.conn.alive) {
|
|
2365
|
+
return failedAppServerAttempt(err, args.currentSessionId(), { retried: args.retried, transient: "conn-closed" });
|
|
2366
|
+
}
|
|
2367
|
+
return failedAppServerAttempt(err, args.currentSessionId(), { retried: args.retried });
|
|
2368
|
+
}
|
|
2225
2369
|
/**
|
|
2226
2370
|
* killChain 后等待连接 finalize 实际完成(child 置空 + onClose 广播)再宣告链终局:
|
|
2227
2371
|
* shutdown resolve 于 `exit` 事件,而 finalize 挂 `close`(stdio 排空)——两者之间的
|
|
@@ -2476,10 +2620,21 @@ var ZcodeEngine = class {
|
|
|
2476
2620
|
}
|
|
2477
2621
|
for (const ev of synthesizeCoarseEvents(payload.response, payload.usage)) emit(ev);
|
|
2478
2622
|
}
|
|
2479
|
-
/** [U7] 模型可发现性:
|
|
2623
|
+
/** [U7] 模型可发现性:provider_config 个人 provider 聚合(注册表实况对齐源),失败安全返回清单本身可能为空。 */
|
|
2480
2624
|
listModels() {
|
|
2481
2625
|
return listZcodeModels(this.deps.sources);
|
|
2482
2626
|
}
|
|
2627
|
+
/** 显式模型的最小 reasoning 档(目录 modelRules 值域;per-modelRef 记忆化——
|
|
2628
|
+
* 目录文件在引擎进程生命周期内视为静态,重复 run 不重读)。 */
|
|
2629
|
+
reasoningMemo = /* @__PURE__ */ new Map();
|
|
2630
|
+
minimalReasoningFor(modelRef) {
|
|
2631
|
+
const memoKey = `${locateZcodeBuiltinCatalog(this.deps.sources) ?? "none"}|${modelRef}`;
|
|
2632
|
+
const hit = this.reasoningMemo.get(memoKey);
|
|
2633
|
+
if (hit !== void 0 || this.reasoningMemo.has(memoKey)) return hit;
|
|
2634
|
+
const level = resolveZcodeMinimalReasoningLevel(modelRef, this.deps.sources);
|
|
2635
|
+
this.reasoningMemo.set(memoKey, level);
|
|
2636
|
+
return level;
|
|
2637
|
+
}
|
|
2483
2638
|
/**
|
|
2484
2639
|
* [u-h2 D2-2] 派发同步期 model 校验:委托 resolveZcodeModelRef(与 run prepare 期
|
|
2485
2640
|
* 显式路径同一函数——canonicalRef 归一化、短名缺省 provider、凭据与清单校验单一
|
|
@@ -2488,11 +2643,11 @@ var ZcodeEngine = class {
|
|
|
2488
2643
|
*
|
|
2489
2644
|
* [R4/D6-②] 缺席语义:本实现是进程内形态 + 协议诊断面(宿主 cli 形态消费的是
|
|
2490
2645
|
* RemoteEngine 的 manifest 本地判定,不经本方法——SDK protocol methods.ts 明示
|
|
2491
|
-
* validateModel 为诊断面)。缺席 modelRef
|
|
2492
|
-
*
|
|
2493
|
-
*
|
|
2494
|
-
* port-contract
|
|
2495
|
-
* server handler 签名,非本包单方面可完成)。
|
|
2646
|
+
* validateModel 为诊断面)。缺席 modelRef 时返回空串 canonical(= create 帧省略
|
|
2647
|
+
* model 键、CLI 自身缺省解析——2026-09-29 account 体系迁移后 plan 家族兜底 id
|
|
2648
|
+
* 已不可用;record 留痕侧按 R4/D6-② 空串归一为「用户未指定」条件留空)。帧应答
|
|
2649
|
+
* 形态维持 {canonicalRef: string}(SDK port-contract 契约必填——「帧字段缺席」
|
|
2650
|
+
* 的 optional 对齐需放宽 SDK 契约与 server handler 签名,非本包单方面可完成)。
|
|
2496
2651
|
*/
|
|
2497
2652
|
validateModel(modelRef) {
|
|
2498
2653
|
return { canonicalRef: resolveZcodeModelRef(modelRef, this.deps.sources) };
|
|
@@ -2768,10 +2923,13 @@ function appendSchemaRetryDirective(basePrompt, validationError) {
|
|
|
2768
2923
|
Your previous answer failed schema validation: ${validationError}
|
|
2769
2924
|
Answer again. Output ONLY the JSON value conforming to the schema above \u2014 no prose, no markdown fences, no extra text.`;
|
|
2770
2925
|
}
|
|
2771
|
-
function buildAppServerCreateParams(task, modelRef, cwd) {
|
|
2926
|
+
function buildAppServerCreateParams(task, modelRef, cwd, reasoningLevel) {
|
|
2772
2927
|
const denyTools = (task.denyTools ?? []).filter((t) => typeof t === "string" && t.trim() !== "");
|
|
2773
2928
|
const thoughtLevel = task.thinkingLevel?.trim();
|
|
2774
|
-
const model = modelRef !== void 0 && modelRef !== "" ?
|
|
2929
|
+
const model = modelRef !== void 0 && modelRef !== "" ? {
|
|
2930
|
+
...splitZcodeModelRef(modelRef),
|
|
2931
|
+
...reasoningLevel !== void 0 && reasoningLevel !== "" ? { options: { reasoningLevel } } : {}
|
|
2932
|
+
} : void 0;
|
|
2775
2933
|
return {
|
|
2776
2934
|
workspacePath: cwd,
|
|
2777
2935
|
mode: "yolo",
|
|
@@ -2917,6 +3075,7 @@ function createDefaultZcodeEngine() {
|
|
|
2917
3075
|
var import_subagent_engine_sdk13 = require("@zhushanwen/subagent-engine-sdk");
|
|
2918
3076
|
|
|
2919
3077
|
// src/server.ts
|
|
3078
|
+
var logger5 = (0, import_subagent_engine_sdk14.getLogger)("subagents");
|
|
2920
3079
|
var REVERSE_TIMEOUT_DEFAULT_MS = 6e4;
|
|
2921
3080
|
var EngineProtocolServer = class {
|
|
2922
3081
|
write;
|
|
@@ -3030,22 +3189,23 @@ var EngineProtocolServer = class {
|
|
|
3030
3189
|
...ctx.cwd !== void 0 ? { cwd: ctx.cwd } : {}
|
|
3031
3190
|
};
|
|
3032
3191
|
const ctxModel = (0, import_subagent_engine_sdk13.parseCtxModel)(ctx.ctxModel);
|
|
3033
|
-
const stream = ctx.streamMode === "stream" ? {
|
|
3034
|
-
|
|
3035
|
-
|
|
3192
|
+
const stream = ctx.streamMode === "stream" ? {
|
|
3193
|
+
onDelta: (delta) => {
|
|
3194
|
+
void this.reverseRequestInternal("host/streamDelta", { runId, delta }).catch(this.warnReverseFailure("host/streamDelta", `run ${runId}`));
|
|
3195
|
+
}
|
|
3196
|
+
} : void 0;
|
|
3036
3197
|
const runCtx = {
|
|
3037
3198
|
taskId: runId,
|
|
3038
3199
|
signal: controller.signal,
|
|
3039
3200
|
onEvent: (event) => this.emitEvent(runId, event),
|
|
3040
3201
|
...ctxModel !== void 0 ? { ctxModel } : {},
|
|
3041
3202
|
...stream !== void 0 ? { stream } : {},
|
|
3042
|
-
...ctx.schemaEnv !== void 0 ? { schemaEnv: ctx.schemaEnv } : {},
|
|
3043
3203
|
...ctx.engineFallback !== void 0 ? { engineFallback: ctx.engineFallback } : {},
|
|
3044
3204
|
// [U6 / §3.2.6 要点 3] resume 锚点透传(宿主 → 引擎的续聊通道:zcode 锚
|
|
3045
3205
|
// sessionRef {sessionId, dbPath},引擎侧 resume 读 + 新 session 注入消费)。
|
|
3046
3206
|
...params.resume !== void 0 ? { resume: params.resume } : {},
|
|
3047
3207
|
onHandleReady: (partial) => {
|
|
3048
|
-
void this.reverseRequestInternal("host/handleReady", { runId, sessionRef: partial.sessionRef });
|
|
3208
|
+
void this.reverseRequestInternal("host/handleReady", { runId, sessionRef: partial.sessionRef }).catch(this.warnReverseFailure("host/handleReady", `run ${runId}`));
|
|
3049
3209
|
}
|
|
3050
3210
|
};
|
|
3051
3211
|
try {
|
|
@@ -3085,6 +3245,19 @@ var EngineProtocolServer = class {
|
|
|
3085
3245
|
* 应答超时兜底 reject——数据面通道(host/log 等)core 10s 应答,reject 由调用方
|
|
3086
3246
|
* 吞掉留痕(数据面丢失不拖死主链路)。
|
|
3087
3247
|
*/
|
|
3248
|
+
/**
|
|
3249
|
+
* fire-and-forget 反向请求(`void this.reverseRequestInternal(...)` 形态)的
|
|
3250
|
+
* rejection 兜底:60s 超时(reverseRequestInternal 计时器)或宿主 error 帧
|
|
3251
|
+
* (settleReverse)都会 reject——无 handler 即 unhandled rejection(Node ≥15
|
|
3252
|
+
* 默认崩引擎进程)。失败只降级该次通道上报,warn 留痕不断流。
|
|
3253
|
+
*/
|
|
3254
|
+
warnReverseFailure(method, context) {
|
|
3255
|
+
return (err) => {
|
|
3256
|
+
logger5.warn(`[protocol] ${method} reverse request failed (${context}); continuing without it`, {
|
|
3257
|
+
detail: (0, import_subagent_engine_sdk4.toErrorMessage)(err)
|
|
3258
|
+
});
|
|
3259
|
+
};
|
|
3260
|
+
}
|
|
3088
3261
|
/** 反向请求发送(公开面:main.ts 的 host/log 桥接消费;内部 run 通道同路)。 */
|
|
3089
3262
|
reverseRequest(method, params) {
|
|
3090
3263
|
return this.reverseRequestInternal(method, params);
|
|
@@ -3100,7 +3273,14 @@ var EngineProtocolServer = class {
|
|
|
3100
3273
|
if (typeof timer.unref === "function") timer.unref();
|
|
3101
3274
|
this.reversePending.set(id, { resolve: resolve2, reject, timer });
|
|
3102
3275
|
this.reverseClock?.started(id);
|
|
3103
|
-
|
|
3276
|
+
try {
|
|
3277
|
+
this.write({ id, method, params });
|
|
3278
|
+
} catch (err) {
|
|
3279
|
+
this.reversePending.delete(id);
|
|
3280
|
+
clearTimeout(timer);
|
|
3281
|
+
this.reverseClock?.settled(id);
|
|
3282
|
+
reject(new Error(`reverse request ${method} (${id}) could not be written: ${(0, import_subagent_engine_sdk4.toErrorMessage)(err)}`));
|
|
3283
|
+
}
|
|
3104
3284
|
});
|
|
3105
3285
|
}
|
|
3106
3286
|
/** 反向请求应答落位(ack 两阶段:{ack:true}/{unsupported:true}/{ok:true} 均先 ack 计时面)。 */
|
package/dist/main.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/zcode-subagent-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "zcode subagent engine as an independent CLI package (W5 of subagent-engine-protocolization): speaks engine-protocol v1 over NDJSON stdio, depends only on @zhushanwen/subagent-engine-sdk (never subagent-core)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"taiji": {
|
|
30
30
|
"subagentEngine": {
|
|
31
31
|
"id": "zcode",
|
|
32
|
+
"processModel": "shared-service",
|
|
32
33
|
"bin": "zcode-subagent-cli",
|
|
33
34
|
"protocol": 1,
|
|
34
35
|
"envPrefixes": [
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
"dist/"
|
|
62
63
|
],
|
|
63
64
|
"dependencies": {
|
|
64
|
-
"@zhushanwen/subagent-engine-sdk": "0.
|
|
65
|
+
"@zhushanwen/subagent-engine-sdk": "0.7.0"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
68
|
"@types/node": "^24.0.0",
|