@zhushanwen/subagent-engine-sdk 0.4.0 → 0.5.1
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-7I4XGL5J.js → chunk-BBWUC2EE.js} +2 -2
- package/dist/{chunk-3K2P2CM2.js → chunk-CNQTJJF5.js} +1 -1
- package/dist/{chunk-DSQ7JQKM.js → chunk-GSW3DMN6.js} +5 -5
- package/dist/{chunk-BBVZK5DL.js → chunk-M3SZTDNQ.js} +20 -20
- package/dist/{chunk-HYES77BR.js → chunk-MSAJXIP4.js} +2 -2
- package/dist/{chunk-FJT23P7T.js → chunk-QOEXD2FT.js} +1 -1
- package/dist/{chunk-LKPVN3N6.js → chunk-W3BKI2BP.js} +3 -3
- package/dist/{chunk-WS4WAZVR.js → chunk-WMDMXP2F.js} +2 -2
- package/dist/{chunk-GT6YLLN4.js → chunk-X24IVQKJ.js} +5 -5
- package/dist/{chunk-365AUV6N.js → chunk-YE472JOO.js} +2 -2
- package/dist/{contract-types-C71Sqq8d.d.cts → contract-types-Dsvy79r3.d.cts} +9 -10
- package/dist/{contract-types-C71Sqq8d.d.ts → contract-types-Dsvy79r3.d.ts} +9 -10
- package/dist/data-dir.cjs +6 -6
- package/dist/data-dir.d.cts +4 -4
- package/dist/data-dir.d.ts +4 -4
- package/dist/data-dir.js +3 -3
- package/dist/env.cjs +20 -20
- package/dist/env.d.cts +12 -5
- package/dist/env.d.ts +12 -5
- package/dist/env.js +1 -1
- package/dist/{error-codes-D5YlWaBx.d.ts → error-codes-DMGeUUUm.d.ts} +12 -12
- package/dist/{error-codes-CiOO3PMg.d.cts → error-codes-pT7RYTqQ.d.cts} +12 -12
- package/dist/index.cjs +42 -42
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +12 -12
- package/dist/journal-io.d.cts +1 -1
- package/dist/journal-io.d.ts +1 -1
- package/dist/journal-replay.d.cts +1 -1
- package/dist/journal-replay.d.ts +1 -1
- package/dist/kill-chain.d.cts +2 -2
- package/dist/kill-chain.d.ts +2 -2
- package/dist/kill-chain.js +2 -2
- package/dist/logs/stderr-rotation.cjs +2 -2
- package/dist/logs/stderr-rotation.d.cts +1 -1
- package/dist/logs/stderr-rotation.d.ts +1 -1
- package/dist/logs/stderr-rotation.js +1 -1
- package/dist/nesting-guard.cjs +2 -2
- package/dist/nesting-guard.d.cts +2 -2
- package/dist/nesting-guard.d.ts +2 -2
- package/dist/nesting-guard.js +1 -1
- package/dist/node-executor.cjs +2 -2
- package/dist/node-executor.d.cts +5 -5
- package/dist/node-executor.d.ts +5 -5
- package/dist/node-executor.js +2 -2
- package/dist/port-contract.d.cts +1 -1
- package/dist/port-contract.d.ts +1 -1
- package/dist/protocol/index.cjs +2 -2
- package/dist/protocol/index.d.cts +5 -5
- package/dist/protocol/index.d.ts +5 -5
- package/dist/protocol/index.js +1 -1
- package/dist/relay-env.cjs +5 -5
- package/dist/relay-env.d.cts +5 -5
- package/dist/relay-env.d.ts +5 -5
- package/dist/relay-env.js +1 -1
- package/dist/spawn.cjs +1 -1
- package/dist/spawn.d.cts +2 -2
- package/dist/spawn.d.ts +2 -2
- package/dist/spawn.js +1 -1
- package/dist/ui-channels.cjs +2 -2
- package/dist/ui-channels.js +1 -1
- package/package.json +2 -4
- package/src/best-effort.ts +0 -37
- package/src/cli-entry.ts +0 -82
- package/src/data-dir.ts +0 -89
- package/src/env.ts +0 -265
- package/src/error-message.ts +0 -22
- package/src/index.ts +0 -63
- package/src/journal-io.ts +0 -82
- package/src/journal-replay.ts +0 -436
- package/src/kill-chain.ts +0 -265
- package/src/logger.ts +0 -105
- package/src/logs/stderr-rotation.ts +0 -166
- package/src/nesting-guard.ts +0 -140
- package/src/node-executor.ts +0 -272
- package/src/paths.ts +0 -48
- package/src/port-contract.ts +0 -150
- package/src/protocol/contract-types.ts +0 -379
- package/src/protocol/engine-protocol.ts +0 -91
- package/src/protocol/error-codes.ts +0 -180
- package/src/protocol/frames.ts +0 -143
- package/src/protocol/index.ts +0 -12
- package/src/protocol/methods.ts +0 -237
- package/src/protocol/reverse-channels.ts +0 -123
- package/src/protocol/schema.ts +0 -185
- package/src/relay-env.ts +0 -60
- package/src/schema-emulation.ts +0 -192
- package/src/spawn.ts +0 -246
- package/src/ui-channels.ts +0 -219
- package/src/ui-types.ts +0 -101
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
var NUL = "\0";
|
|
3
3
|
function normalizeChannelName(markerLiteral) {
|
|
4
4
|
let name = markerLiteral;
|
|
5
|
-
if (name.startsWith("
|
|
6
|
-
name = name.slice("
|
|
5
|
+
if (name.startsWith("TAIJI_")) {
|
|
6
|
+
name = name.slice("TAIJI_".length);
|
|
7
7
|
}
|
|
8
8
|
if (name.endsWith(":")) {
|
|
9
9
|
name = name.slice(0, -1);
|
|
@@ -33,7 +33,7 @@ function spawnEngineChild(opts) {
|
|
|
33
33
|
return child;
|
|
34
34
|
}
|
|
35
35
|
var DEFAULT_ENGINE_HOST_REQUEST_TIMEOUT_MS = 3e4;
|
|
36
|
-
var ENGINE_HOST_REQUEST_TIMEOUT_ENV = "
|
|
36
|
+
var ENGINE_HOST_REQUEST_TIMEOUT_ENV = "TAIJI_ENGINE_HOST_REQUEST_TIMEOUT_MS";
|
|
37
37
|
var SWEEP_INTERVAL_MS = 1e3;
|
|
38
38
|
function resolveHostRequestTimeoutMs(opts) {
|
|
39
39
|
if (opts.hostRequestTimeoutMs !== void 0) return opts.hostRequestTimeoutMs;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// src/relay-env.ts
|
|
2
|
-
var RELAY_ENV_SOCKET = "
|
|
3
|
-
var RELAY_ENV_NODE = "
|
|
4
|
-
var RELAY_ENV_SCRIPT = "
|
|
5
|
-
var RELAY_ENV_SESSION_ID = "
|
|
6
|
-
var RELAY_ENV_RECORD_ID = "
|
|
2
|
+
var RELAY_ENV_SOCKET = "TAIJI_SUBAGENT_RELAY_SOCKET";
|
|
3
|
+
var RELAY_ENV_NODE = "TAIJI_SUBAGENT_RELAY_NODE";
|
|
4
|
+
var RELAY_ENV_SCRIPT = "TAIJI_SUBAGENT_RELAY_SCRIPT";
|
|
5
|
+
var RELAY_ENV_SESSION_ID = "TAIJI_SUBAGENT_RELAY_SESSION_ID";
|
|
6
|
+
var RELAY_ENV_RECORD_ID = "TAIJI_SUBAGENT_RELAY_RECORD_ID";
|
|
7
7
|
var RELAY_PROTOCOL_VERSION = 1;
|
|
8
8
|
var RELAY_EXIT_CODES = {
|
|
9
9
|
/** 握手被拒:协议版本不匹配(安装损坏,重装应用)。 */
|
|
@@ -5,25 +5,25 @@ import {
|
|
|
5
5
|
// src/env.ts
|
|
6
6
|
var logger = getLogger("engine-sdk/env");
|
|
7
7
|
var ENGINE_ENV_PREFIXES = [
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
8
|
+
"TAIJI_",
|
|
9
|
+
"TAIJI_AGENT_",
|
|
10
|
+
"TAIJI_SUBAGENT_"
|
|
11
11
|
];
|
|
12
12
|
var ENGINE_ENV_DENY_LIST = [
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
13
|
+
"TAIJI_AGENT_PACKAGED",
|
|
14
|
+
"TAIJI_RUNTIME_TOKEN",
|
|
15
|
+
"TAIJI_AGENT_API_KEY",
|
|
16
|
+
"TAIJI_SUBAGENT_RELAY_SESSION_ID",
|
|
17
|
+
"TAIJI_SUBAGENT_RELAY_RECORD_ID"
|
|
18
18
|
];
|
|
19
19
|
var ENGINE_ENV_L0_INFRA_KEYS = [
|
|
20
|
-
"
|
|
21
|
-
"
|
|
20
|
+
"TAIJI_AGENT_DATA_DIR",
|
|
21
|
+
"TAIJI_AGENT_ENGINE_NODE",
|
|
22
22
|
"ELECTRON_RUN_AS_NODE",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
23
|
+
"TAIJI_AGENT_SUBAGENT",
|
|
24
|
+
"TAIJI_SUBAGENT_RELAY_SOCKET",
|
|
25
|
+
"TAIJI_SUBAGENT_RELAY_NODE",
|
|
26
|
+
"TAIJI_SUBAGENT_RELAY_SCRIPT"
|
|
27
27
|
];
|
|
28
28
|
var ENV_PREFIX_SHAPE_RE = /^[A-Za-z0-9_]+$/;
|
|
29
29
|
function deleteEnvKeysCaseInsensitive(env, names) {
|
|
@@ -73,14 +73,14 @@ function applyManifestAllowlist(env, opts) {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
function injectL0InfraKeys(env, opts) {
|
|
76
|
-
env.
|
|
77
|
-
if (opts.engineNode !== void 0) env.
|
|
76
|
+
env.TAIJI_AGENT_DATA_DIR = opts.dataDir;
|
|
77
|
+
if (opts.engineNode !== void 0) env.TAIJI_AGENT_ENGINE_NODE = opts.engineNode;
|
|
78
78
|
if (opts.electronRunAsNode === true) env.ELECTRON_RUN_AS_NODE = "1";
|
|
79
|
-
env.
|
|
79
|
+
env.TAIJI_AGENT_SUBAGENT = "1";
|
|
80
80
|
if (opts.relay !== void 0) {
|
|
81
|
-
env.
|
|
82
|
-
env.
|
|
83
|
-
env.
|
|
81
|
+
env.TAIJI_SUBAGENT_RELAY_SOCKET = opts.relay.socket;
|
|
82
|
+
env.TAIJI_SUBAGENT_RELAY_NODE = opts.relay.node;
|
|
83
|
+
env.TAIJI_SUBAGENT_RELAY_SCRIPT = opts.relay.script;
|
|
84
84
|
}
|
|
85
85
|
if (opts.identityEnv !== void 0) {
|
|
86
86
|
for (const [key, value] of Object.entries(opts.identityEnv)) {
|
|
@@ -18,8 +18,8 @@ function positiveIntEnv(env, key) {
|
|
|
18
18
|
}
|
|
19
19
|
function stderrRotationParams(env) {
|
|
20
20
|
return {
|
|
21
|
-
maxBytes: positiveIntEnv(env, "
|
|
22
|
-
keepDays: positiveIntEnv(env, "
|
|
21
|
+
maxBytes: positiveIntEnv(env, "TAIJI_LOG_MAX_BYTES") ?? DEFAULT_STDERR_MAX_BYTES,
|
|
22
|
+
keepDays: positiveIntEnv(env, "TAIJI_LOG_KEEP_DAYS") ?? DEFAULT_STDERR_KEEP_DAYS
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
function stderrLogPathFor(engineDataDir, pid, prefix) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EngineSdkError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WMDMXP2F.js";
|
|
4
4
|
|
|
5
5
|
// src/node-executor.ts
|
|
6
6
|
import { spawn } from "child_process";
|
|
7
|
-
var ENGINE_NODE_ENV = "
|
|
7
|
+
var ENGINE_NODE_ENV = "TAIJI_AGENT_ENGINE_NODE";
|
|
8
8
|
var PROBE_TIMEOUT_MS = 5e3;
|
|
9
9
|
function probeNodeExecutor(execPath, isElectron) {
|
|
10
10
|
return new Promise((resolve) => {
|
|
@@ -64,7 +64,7 @@ async function resolvePiExtensionLaunch(entryPath, entryArgs, env) {
|
|
|
64
64
|
if (engineNode === void 0 || engineNode === "") {
|
|
65
65
|
throw engineNotFound(
|
|
66
66
|
`pi extension host must spawn engines via injected executor ${ENGINE_NODE_ENV}, but it is not set (host process.execPath is the pi binary, not a node executor)`,
|
|
67
|
-
`The
|
|
67
|
+
`The taiji runtime injects ${ENGINE_NODE_ENV} when spawning the pi host. If you are running the extension inside a packaged app, report this as a packaging regression; standalone pi installs do not use the pi-extension host kind.`
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
const isElectron = env.ELECTRON_RUN_AS_NODE === "1";
|
|
@@ -17,7 +17,7 @@ var CRASH_REBUILD_BACKOFF_MS = [
|
|
|
17
17
|
CRASH_REBUILD_BACKOFF_STEP_3_MS
|
|
18
18
|
];
|
|
19
19
|
var STDERR_TAIL_CHARS = 400;
|
|
20
|
-
var ENGINE_EVENT_COALESCE_ENV = "
|
|
20
|
+
var ENGINE_EVENT_COALESCE_ENV = "TAIJI_ENGINE_EVENT_COALESCE";
|
|
21
21
|
var ENGINE_EVENT_COALESCE_DEFAULT = "0";
|
|
22
22
|
|
|
23
23
|
// src/protocol/error-codes.ts
|
|
@@ -71,7 +71,7 @@ function engineConversationUnsupportedError(engineId) {
|
|
|
71
71
|
return new EngineSdkError(
|
|
72
72
|
"engine_capability_unsupported",
|
|
73
73
|
`engine '${engineId}' \u4E0D\u652F\u6301 resume \u7EED\u804A\uFF08capabilities.conversation = 'unsupported'\uFF0Cmanifest \u65E0 conversation gate \u4F4D\uFF09`,
|
|
74
|
-
`\
|
|
74
|
+
`\u6539\u7528\u58F0\u660E conversation \u80FD\u529B\u7684\u5F15\u64CE\u7EED\u804A\uFF08\u6216\u4EE5\u65B0\u4EFB\u52A1\u91CD\u6D3E\uFF09\uFF0C\u6216\u4FEE manifest capabilities / \u5347\u7EA7\u5F15\u64CE\u5305\uFF08\u82E5\u5F15\u64CE\u5B9E\u9645\u652F\u6301\u8BE5\u80FD\u529B\uFF09`,
|
|
75
75
|
{ engineId, capability: "conversation", declared: "unsupported" }
|
|
76
76
|
);
|
|
77
77
|
}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
|
|
5
5
|
// src/data-dir.ts
|
|
6
6
|
var logger = getLogger("subagents");
|
|
7
|
-
var
|
|
7
|
+
var TAIJI_DATA_DIR_ENV = "TAIJI_AGENT_DATA_DIR";
|
|
8
8
|
var WARNED_SLOT_KEY = /* @__PURE__ */ Symbol.for("@zhushanwen/subagent-engine-sdk.data-dir-warned");
|
|
9
9
|
function getWarnedSlot() {
|
|
10
10
|
let slot = Reflect.get(globalThis, WARNED_SLOT_KEY);
|
|
@@ -18,19 +18,19 @@ function resetDataDirWarnForTests() {
|
|
|
18
18
|
getWarnedSlot().current = false;
|
|
19
19
|
}
|
|
20
20
|
function resolveEngineDataDir(env, opts = {}) {
|
|
21
|
-
const fromEnv = env[
|
|
21
|
+
const fromEnv = env[TAIJI_DATA_DIR_ENV]?.trim();
|
|
22
22
|
if (fromEnv !== void 0 && fromEnv !== "") return fromEnv;
|
|
23
23
|
const fallback = opts.fallbackDataRoot?.trim();
|
|
24
24
|
if (fallback === void 0 || fallback === "") {
|
|
25
25
|
throw new Error(
|
|
26
|
-
`[subagent-engine-sdk] engine_not_found: ${
|
|
26
|
+
`[subagent-engine-sdk] engine_not_found: ${TAIJI_DATA_DIR_ENV} is not set and no fallback data root was injected. Recovery: the host must inject ${TAIJI_DATA_DIR_ENV} into the engine process env (taiji runtime / pi extension host do this at spawn), or pass { fallbackDataRoot } when calling resolveEngineDataDir from a host that resolves the data root itself.`
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
if (!getWarnedSlot().current) {
|
|
30
30
|
getWarnedSlot().current = true;
|
|
31
31
|
const warn = opts.warn ?? defaultWarn;
|
|
32
32
|
warn(
|
|
33
|
-
`[engine-data-dir] ${
|
|
33
|
+
`[engine-data-dir] ${TAIJI_DATA_DIR_ENV} is not set; engine journal/pool fall back to the injected data root (${fallback}). The taiji host normally injects this env \u2014 if you are running inside taiji, check the runtime spawn env; standalone installs intentionally use the injected root.`
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
return fallback;
|
|
@@ -40,7 +40,7 @@ function defaultWarn(msg) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export {
|
|
43
|
-
|
|
43
|
+
TAIJI_DATA_DIR_ENV,
|
|
44
44
|
resetDataDirWarnForTests,
|
|
45
45
|
resolveEngineDataDir
|
|
46
46
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/nesting-guard.ts
|
|
2
2
|
import { AsyncLocalStorage } from "async_hooks";
|
|
3
|
-
var NESTED_SPAWN_ENV = "
|
|
3
|
+
var NESTED_SPAWN_ENV = "TAIJI_AGENT_SUBAGENT";
|
|
4
4
|
var NATIVE_NESTED_KEYS = ["CLAUDECODE", "ZSW_NESTED"];
|
|
5
5
|
var NATIVE_NESTED_PREFIXES = ["PI_SUBAGENT_"];
|
|
6
6
|
var NestedSpawnRejectedError = class extends Error {
|
|
@@ -9,7 +9,7 @@ var NestedSpawnRejectedError = class extends Error {
|
|
|
9
9
|
recovery;
|
|
10
10
|
constructor() {
|
|
11
11
|
super(
|
|
12
|
-
"nested_spawn_rejected: this process is already a subagent (
|
|
12
|
+
"nested_spawn_rejected: this process is already a subagent (TAIJI_AGENT_SUBAGENT=1)"
|
|
13
13
|
);
|
|
14
14
|
this.name = "NestedSpawnRejectedError";
|
|
15
15
|
this.recovery = "Subagents must not spawn further subagents (unbounded recursion guard). Do the work directly inside the current task instead of delegating.";
|
|
@@ -161,13 +161,14 @@ interface EngineCapabilities {
|
|
|
161
161
|
/** 注意区分「引擎 RPC 层有此能力」与「subagent 链路已接通」。 */
|
|
162
162
|
steer: "native" | "emulated" | "unsupported";
|
|
163
163
|
/**
|
|
164
|
-
* [H1 D5 语义收窄
|
|
164
|
+
* [H1 D5 语义收窄 + modeless] 「怎么续」形态轴兼 message 资格轴:
|
|
165
|
+
* 位非 'unsupported' = 引擎可续聊(core capability-gate 的 message 资格门消费),
|
|
166
|
+
* 值区分续聊形态——native(原地续写)/ cold(冷恢复重建 + 新 run + resume 锚点)。
|
|
165
167
|
* 原名字沿用——conversation 位保留、语义从「interact 长驻控制面」收窄为
|
|
166
|
-
* 「resume
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* 注入 vs 原地续写)。
|
|
168
|
+
* 「resume 续聊能力」。[modeless 波2] 会话形态键只剩 run.params.resume(协议
|
|
169
|
+
* task.conversation 已删),本轴不再是 per-run 模式开关——描述各引擎的真实
|
|
170
|
+
* 续聊差异(gate 判据仍是 `=== "unsupported"` 拒绝,"cold" 与 "native" 等价
|
|
171
|
+
* 放行)。
|
|
171
172
|
*/
|
|
172
173
|
conversation: "native" | "cold" | "unsupported";
|
|
173
174
|
/** 决定 persona 路由策略(file/flag/prompt 通道)。 */
|
|
@@ -280,7 +281,7 @@ interface ModelCatalogEntry {
|
|
|
280
281
|
*
|
|
281
282
|
* 字段裁决(对照 core orchestration/models/types.ts AgentCallOpts,2026-09-09):
|
|
282
283
|
* - 入选 = 引擎消费面:任务语义(prompt/schema/thinkingLevel/skill/skillPath/agent/persona 注入)、
|
|
283
|
-
* 轮次预算(maxTurns/graceTurns/
|
|
284
|
+
* 轮次预算(maxTurns/graceTurns/idleTimeoutMs)、隔离与权限(worktree/
|
|
284
285
|
* fork/forkSource/denyTools/permissionMode)、诊断(description/scene);
|
|
285
286
|
* - 排除并改挂 run.params.ctx(协议层已单列,task 内双写会分叉):model(→ctx.model)、
|
|
286
287
|
* schemaEnv(→ctx.schemaEnv)、cwd(→ctx.cwd)、engineFallback(→ctx.engineFallback);
|
|
@@ -327,9 +328,7 @@ interface AgentCallOpts {
|
|
|
327
328
|
forkSource?: string;
|
|
328
329
|
/** Filesystem isolation: 新建 worktree | 复用外部已创建 worktree | 不隔离。 */
|
|
329
330
|
worktree?: boolean | WorktreeHandle;
|
|
330
|
-
/**
|
|
331
|
-
conversation?: boolean;
|
|
332
|
-
/** 空闲超时毫秒数(仅 conversation 模式有意义)。显式 0/负 = 禁用 idle GC。 */
|
|
331
|
+
/** 空闲超时毫秒数([modeless] 全体 record 的 idle 回收节奏;显式 0/负 = 禁用 idle GC)。 */
|
|
333
332
|
idleTimeoutMs?: number;
|
|
334
333
|
/** 工具 denylist(各引擎做语法映射)。 */
|
|
335
334
|
denyTools?: string[];
|
|
@@ -161,13 +161,14 @@ interface EngineCapabilities {
|
|
|
161
161
|
/** 注意区分「引擎 RPC 层有此能力」与「subagent 链路已接通」。 */
|
|
162
162
|
steer: "native" | "emulated" | "unsupported";
|
|
163
163
|
/**
|
|
164
|
-
* [H1 D5 语义收窄
|
|
164
|
+
* [H1 D5 语义收窄 + modeless] 「怎么续」形态轴兼 message 资格轴:
|
|
165
|
+
* 位非 'unsupported' = 引擎可续聊(core capability-gate 的 message 资格门消费),
|
|
166
|
+
* 值区分续聊形态——native(原地续写)/ cold(冷恢复重建 + 新 run + resume 锚点)。
|
|
165
167
|
* 原名字沿用——conversation 位保留、语义从「interact 长驻控制面」收窄为
|
|
166
|
-
* 「resume
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* 注入 vs 原地续写)。
|
|
168
|
+
* 「resume 续聊能力」。[modeless 波2] 会话形态键只剩 run.params.resume(协议
|
|
169
|
+
* task.conversation 已删),本轴不再是 per-run 模式开关——描述各引擎的真实
|
|
170
|
+
* 续聊差异(gate 判据仍是 `=== "unsupported"` 拒绝,"cold" 与 "native" 等价
|
|
171
|
+
* 放行)。
|
|
171
172
|
*/
|
|
172
173
|
conversation: "native" | "cold" | "unsupported";
|
|
173
174
|
/** 决定 persona 路由策略(file/flag/prompt 通道)。 */
|
|
@@ -280,7 +281,7 @@ interface ModelCatalogEntry {
|
|
|
280
281
|
*
|
|
281
282
|
* 字段裁决(对照 core orchestration/models/types.ts AgentCallOpts,2026-09-09):
|
|
282
283
|
* - 入选 = 引擎消费面:任务语义(prompt/schema/thinkingLevel/skill/skillPath/agent/persona 注入)、
|
|
283
|
-
* 轮次预算(maxTurns/graceTurns/
|
|
284
|
+
* 轮次预算(maxTurns/graceTurns/idleTimeoutMs)、隔离与权限(worktree/
|
|
284
285
|
* fork/forkSource/denyTools/permissionMode)、诊断(description/scene);
|
|
285
286
|
* - 排除并改挂 run.params.ctx(协议层已单列,task 内双写会分叉):model(→ctx.model)、
|
|
286
287
|
* schemaEnv(→ctx.schemaEnv)、cwd(→ctx.cwd)、engineFallback(→ctx.engineFallback);
|
|
@@ -327,9 +328,7 @@ interface AgentCallOpts {
|
|
|
327
328
|
forkSource?: string;
|
|
328
329
|
/** Filesystem isolation: 新建 worktree | 复用外部已创建 worktree | 不隔离。 */
|
|
329
330
|
worktree?: boolean | WorktreeHandle;
|
|
330
|
-
/**
|
|
331
|
-
conversation?: boolean;
|
|
332
|
-
/** 空闲超时毫秒数(仅 conversation 模式有意义)。显式 0/负 = 禁用 idle GC。 */
|
|
331
|
+
/** 空闲超时毫秒数([modeless] 全体 record 的 idle 回收节奏;显式 0/负 = 禁用 idle GC)。 */
|
|
333
332
|
idleTimeoutMs?: number;
|
|
334
333
|
/** 工具 denylist(各引擎做语法映射)。 */
|
|
335
334
|
denyTools?: string[];
|
package/dist/data-dir.cjs
CHANGED
|
@@ -20,7 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/data-dir.ts
|
|
21
21
|
var data_dir_exports = {};
|
|
22
22
|
__export(data_dir_exports, {
|
|
23
|
-
|
|
23
|
+
TAIJI_DATA_DIR_ENV: () => TAIJI_DATA_DIR_ENV,
|
|
24
24
|
resetDataDirWarnForTests: () => resetDataDirWarnForTests,
|
|
25
25
|
resolveEngineDataDir: () => resolveEngineDataDir
|
|
26
26
|
});
|
|
@@ -75,7 +75,7 @@ function getLogger(component) {
|
|
|
75
75
|
|
|
76
76
|
// src/data-dir.ts
|
|
77
77
|
var logger = getLogger("subagents");
|
|
78
|
-
var
|
|
78
|
+
var TAIJI_DATA_DIR_ENV = "TAIJI_AGENT_DATA_DIR";
|
|
79
79
|
var WARNED_SLOT_KEY = /* @__PURE__ */ Symbol.for("@zhushanwen/subagent-engine-sdk.data-dir-warned");
|
|
80
80
|
function getWarnedSlot() {
|
|
81
81
|
let slot = Reflect.get(globalThis, WARNED_SLOT_KEY);
|
|
@@ -89,19 +89,19 @@ function resetDataDirWarnForTests() {
|
|
|
89
89
|
getWarnedSlot().current = false;
|
|
90
90
|
}
|
|
91
91
|
function resolveEngineDataDir(env, opts = {}) {
|
|
92
|
-
const fromEnv = env[
|
|
92
|
+
const fromEnv = env[TAIJI_DATA_DIR_ENV]?.trim();
|
|
93
93
|
if (fromEnv !== void 0 && fromEnv !== "") return fromEnv;
|
|
94
94
|
const fallback = opts.fallbackDataRoot?.trim();
|
|
95
95
|
if (fallback === void 0 || fallback === "") {
|
|
96
96
|
throw new Error(
|
|
97
|
-
`[subagent-engine-sdk] engine_not_found: ${
|
|
97
|
+
`[subagent-engine-sdk] engine_not_found: ${TAIJI_DATA_DIR_ENV} is not set and no fallback data root was injected. Recovery: the host must inject ${TAIJI_DATA_DIR_ENV} into the engine process env (taiji runtime / pi extension host do this at spawn), or pass { fallbackDataRoot } when calling resolveEngineDataDir from a host that resolves the data root itself.`
|
|
98
98
|
);
|
|
99
99
|
}
|
|
100
100
|
if (!getWarnedSlot().current) {
|
|
101
101
|
getWarnedSlot().current = true;
|
|
102
102
|
const warn = opts.warn ?? defaultWarn;
|
|
103
103
|
warn(
|
|
104
|
-
`[engine-data-dir] ${
|
|
104
|
+
`[engine-data-dir] ${TAIJI_DATA_DIR_ENV} is not set; engine journal/pool fall back to the injected data root (${fallback}). The taiji host normally injects this env \u2014 if you are running inside taiji, check the runtime spawn env; standalone installs intentionally use the injected root.`
|
|
105
105
|
);
|
|
106
106
|
}
|
|
107
107
|
return fallback;
|
|
@@ -111,7 +111,7 @@ function defaultWarn(msg) {
|
|
|
111
111
|
}
|
|
112
112
|
// Annotate the CommonJS export names for ESM import in node:
|
|
113
113
|
0 && (module.exports = {
|
|
114
|
-
|
|
114
|
+
TAIJI_DATA_DIR_ENV,
|
|
115
115
|
resetDataDirWarnForTests,
|
|
116
116
|
resolveEngineDataDir
|
|
117
117
|
});
|
package/dist/data-dir.d.cts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
declare const
|
|
1
|
+
/** taiji 数据目录 env 名(与 packages/shared/src/paths.ts 的 SSOT 变量同名)。 */
|
|
2
|
+
declare const TAIJI_DATA_DIR_ENV = "TAIJI_AGENT_DATA_DIR";
|
|
3
3
|
/** 测试隔离专用:重置 warn-once 标记(生产禁用)。 */
|
|
4
4
|
declare function resetDataDirWarnForTests(): void;
|
|
5
5
|
/**
|
|
6
6
|
* 解析引擎数据目录(journal 落盘 / 隔离池的根):
|
|
7
|
-
* 1. env[
|
|
7
|
+
* 1. env[TAIJI_AGENT_DATA_DIR](宿主注入,权威通道);
|
|
8
8
|
* 2. 缺失 + opts.fallbackDataRoot 显式传入(宿主解析过的数据根)→ 用之 + warn 一次
|
|
9
9
|
* (非权威通道回退必须可观测——journal 落点变化不留静默漂移);
|
|
10
10
|
* 3. 两者皆缺 → 抛错(engine_not_found 语义:错误含 env 名、期望值示例与恢复动作;
|
|
@@ -17,4 +17,4 @@ declare function resolveEngineDataDir(env: NodeJS.ProcessEnv, opts?: {
|
|
|
17
17
|
warn?: (msg: string) => void;
|
|
18
18
|
}): string;
|
|
19
19
|
|
|
20
|
-
export {
|
|
20
|
+
export { TAIJI_DATA_DIR_ENV, resetDataDirWarnForTests, resolveEngineDataDir };
|
package/dist/data-dir.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
declare const
|
|
1
|
+
/** taiji 数据目录 env 名(与 packages/shared/src/paths.ts 的 SSOT 变量同名)。 */
|
|
2
|
+
declare const TAIJI_DATA_DIR_ENV = "TAIJI_AGENT_DATA_DIR";
|
|
3
3
|
/** 测试隔离专用:重置 warn-once 标记(生产禁用)。 */
|
|
4
4
|
declare function resetDataDirWarnForTests(): void;
|
|
5
5
|
/**
|
|
6
6
|
* 解析引擎数据目录(journal 落盘 / 隔离池的根):
|
|
7
|
-
* 1. env[
|
|
7
|
+
* 1. env[TAIJI_AGENT_DATA_DIR](宿主注入,权威通道);
|
|
8
8
|
* 2. 缺失 + opts.fallbackDataRoot 显式传入(宿主解析过的数据根)→ 用之 + warn 一次
|
|
9
9
|
* (非权威通道回退必须可观测——journal 落点变化不留静默漂移);
|
|
10
10
|
* 3. 两者皆缺 → 抛错(engine_not_found 语义:错误含 env 名、期望值示例与恢复动作;
|
|
@@ -17,4 +17,4 @@ declare function resolveEngineDataDir(env: NodeJS.ProcessEnv, opts?: {
|
|
|
17
17
|
warn?: (msg: string) => void;
|
|
18
18
|
}): string;
|
|
19
19
|
|
|
20
|
-
export {
|
|
20
|
+
export { TAIJI_DATA_DIR_ENV, resetDataDirWarnForTests, resolveEngineDataDir };
|
package/dist/data-dir.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
TAIJI_DATA_DIR_ENV,
|
|
3
3
|
resetDataDirWarnForTests,
|
|
4
4
|
resolveEngineDataDir
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-X24IVQKJ.js";
|
|
6
6
|
import "./chunk-75QEMUGV.js";
|
|
7
7
|
import "./chunk-JSBRDJBE.js";
|
|
8
8
|
export {
|
|
9
|
-
|
|
9
|
+
TAIJI_DATA_DIR_ENV,
|
|
10
10
|
resetDataDirWarnForTests,
|
|
11
11
|
resolveEngineDataDir
|
|
12
12
|
};
|
package/dist/env.cjs
CHANGED
|
@@ -78,25 +78,25 @@ function getLogger(component) {
|
|
|
78
78
|
// src/env.ts
|
|
79
79
|
var logger = getLogger("engine-sdk/env");
|
|
80
80
|
var ENGINE_ENV_PREFIXES = [
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
81
|
+
"TAIJI_",
|
|
82
|
+
"TAIJI_AGENT_",
|
|
83
|
+
"TAIJI_SUBAGENT_"
|
|
84
84
|
];
|
|
85
85
|
var ENGINE_ENV_DENY_LIST = [
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
86
|
+
"TAIJI_AGENT_PACKAGED",
|
|
87
|
+
"TAIJI_RUNTIME_TOKEN",
|
|
88
|
+
"TAIJI_AGENT_API_KEY",
|
|
89
|
+
"TAIJI_SUBAGENT_RELAY_SESSION_ID",
|
|
90
|
+
"TAIJI_SUBAGENT_RELAY_RECORD_ID"
|
|
91
91
|
];
|
|
92
92
|
var ENGINE_ENV_L0_INFRA_KEYS = [
|
|
93
|
-
"
|
|
94
|
-
"
|
|
93
|
+
"TAIJI_AGENT_DATA_DIR",
|
|
94
|
+
"TAIJI_AGENT_ENGINE_NODE",
|
|
95
95
|
"ELECTRON_RUN_AS_NODE",
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
96
|
+
"TAIJI_AGENT_SUBAGENT",
|
|
97
|
+
"TAIJI_SUBAGENT_RELAY_SOCKET",
|
|
98
|
+
"TAIJI_SUBAGENT_RELAY_NODE",
|
|
99
|
+
"TAIJI_SUBAGENT_RELAY_SCRIPT"
|
|
100
100
|
];
|
|
101
101
|
var ENV_PREFIX_SHAPE_RE = /^[A-Za-z0-9_]+$/;
|
|
102
102
|
function deleteEnvKeysCaseInsensitive(env, names) {
|
|
@@ -146,14 +146,14 @@ function applyManifestAllowlist(env, opts) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
function injectL0InfraKeys(env, opts) {
|
|
149
|
-
env.
|
|
150
|
-
if (opts.engineNode !== void 0) env.
|
|
149
|
+
env.TAIJI_AGENT_DATA_DIR = opts.dataDir;
|
|
150
|
+
if (opts.engineNode !== void 0) env.TAIJI_AGENT_ENGINE_NODE = opts.engineNode;
|
|
151
151
|
if (opts.electronRunAsNode === true) env.ELECTRON_RUN_AS_NODE = "1";
|
|
152
|
-
env.
|
|
152
|
+
env.TAIJI_AGENT_SUBAGENT = "1";
|
|
153
153
|
if (opts.relay !== void 0) {
|
|
154
|
-
env.
|
|
155
|
-
env.
|
|
156
|
-
env.
|
|
154
|
+
env.TAIJI_SUBAGENT_RELAY_SOCKET = opts.relay.socket;
|
|
155
|
+
env.TAIJI_SUBAGENT_RELAY_NODE = opts.relay.node;
|
|
156
|
+
env.TAIJI_SUBAGENT_RELAY_SCRIPT = opts.relay.script;
|
|
157
157
|
}
|
|
158
158
|
if (opts.identityEnv !== void 0) {
|
|
159
159
|
for (const [key, value] of Object.entries(opts.identityEnv)) {
|
package/dist/env.d.cts
CHANGED
|
@@ -21,9 +21,16 @@ interface EngineChildEnvOptions {
|
|
|
21
21
|
engineNode?: string;
|
|
22
22
|
/** L0:执行器为 Electron 二进制 → 注入 ELECTRON_RUN_AS_NODE=1 */
|
|
23
23
|
electronRunAsNode?: boolean;
|
|
24
|
-
/** L0:relay 三键(宿主 relay 激活时传;三键必经 L0——L1 拒绝
|
|
24
|
+
/** L0:relay 三键(宿主 relay 激活时传;三键必经 L0——L1 拒绝 TAIJI_SUBAGENT_ 前缀、L2 是 manifest 面,两层都到不了) */
|
|
25
25
|
relay?: EngineRelayEnv;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* L0:引擎侧身份 env 透传通道(identityEnv)。现行事实(ext-simplify-17 D4,
|
|
28
|
+
* 20260914 真机探针证实):PI_SUBAGENT_ROOT_SESSION_ID / PI_SUBAGENT_SELF_RECORD_ID
|
|
29
|
+
* 两键已无写入方(本通道现无人传值),引擎链统一 subagent 标记 = TAIJI_AGENT_SUBAGENT=1
|
|
30
|
+
* (见 injectL0InfraKeys 恒注入),base-tool-enhance 判据已重锚新标记。通道保留待
|
|
31
|
+
* 另行裁决,读者见 docs/architecture/ext-simplify-17-shared-extraction.md §3.1 D4
|
|
32
|
+
* 与探针报告 .tmp/dev-flow/ext-simplify-17-d4-probe.md。
|
|
33
|
+
*/
|
|
27
34
|
identityEnv?: Record<string, string | undefined>;
|
|
28
35
|
/** L2:manifest 声明的 envPrefixes 放行清单(保留前缀拒绝 + 形态校验) */
|
|
29
36
|
envPrefixes?: readonly string[];
|
|
@@ -38,8 +45,8 @@ interface EngineChildEnvOptions {
|
|
|
38
45
|
* L0 键在最后写入故不受 L1 剥除影响(交集为 ∅ 由测试断言兜底)。
|
|
39
46
|
*
|
|
40
47
|
* 层规格(impl-plan §2.12 三层表):
|
|
41
|
-
* - L0 基础设施键:
|
|
42
|
-
* (条件)/
|
|
48
|
+
* - L0 基础设施键:TAIJI_AGENT_DATA_DIR / TAIJI_AGENT_ENGINE_NODE / ELECTRON_RUN_AS_NODE
|
|
49
|
+
* (条件)/ TAIJI_AGENT_SUBAGENT=1 / relay 三键 / identityEnv(injectL0InfraKeys);
|
|
43
50
|
* - L1 deny + 显式剥除(恒高于 manifest 放行):ENGINE_ENV_DENY_LIST
|
|
44
51
|
* (deny 两键 + 凭证键 + 父身份键 + 防御性剥除三死名);
|
|
45
52
|
* - L2 manifest 放行:envPrefixes 声明前缀的 processEnv 键(保留前缀拒绝、
|
|
@@ -62,7 +69,7 @@ interface BuildOutboundChildEnvOptions {
|
|
|
62
69
|
* execFile 等)复用——R3 MF-C:deny 键不进 git 子进程,git hooks 等后代不再可能
|
|
63
70
|
* 消费生命周期标志 / WS 令牌。
|
|
64
71
|
*
|
|
65
|
-
* 与 @
|
|
72
|
+
* 与 @taiji/shared 版 buildOutboundChildEnv 的刻意差异:**缺省不做白名单过滤**
|
|
66
73
|
* (prefixes 省略 = 全量继承父 env + deny 剥除)。理由:SDK 消费面(zsw 宿主 /
|
|
67
74
|
* 引擎 CLI)不可 import shared 的 ENV_WHITELIST_PREFIXES;引擎 spawn 的基座由
|
|
68
75
|
* 调用方先经 buildEngineChildEnv 组装(其 baseEnv 已是 core 过滤后的),而
|
package/dist/env.d.ts
CHANGED
|
@@ -21,9 +21,16 @@ interface EngineChildEnvOptions {
|
|
|
21
21
|
engineNode?: string;
|
|
22
22
|
/** L0:执行器为 Electron 二进制 → 注入 ELECTRON_RUN_AS_NODE=1 */
|
|
23
23
|
electronRunAsNode?: boolean;
|
|
24
|
-
/** L0:relay 三键(宿主 relay 激活时传;三键必经 L0——L1 拒绝
|
|
24
|
+
/** L0:relay 三键(宿主 relay 激活时传;三键必经 L0——L1 拒绝 TAIJI_SUBAGENT_ 前缀、L2 是 manifest 面,两层都到不了) */
|
|
25
25
|
relay?: EngineRelayEnv;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* L0:引擎侧身份 env 透传通道(identityEnv)。现行事实(ext-simplify-17 D4,
|
|
28
|
+
* 20260914 真机探针证实):PI_SUBAGENT_ROOT_SESSION_ID / PI_SUBAGENT_SELF_RECORD_ID
|
|
29
|
+
* 两键已无写入方(本通道现无人传值),引擎链统一 subagent 标记 = TAIJI_AGENT_SUBAGENT=1
|
|
30
|
+
* (见 injectL0InfraKeys 恒注入),base-tool-enhance 判据已重锚新标记。通道保留待
|
|
31
|
+
* 另行裁决,读者见 docs/architecture/ext-simplify-17-shared-extraction.md §3.1 D4
|
|
32
|
+
* 与探针报告 .tmp/dev-flow/ext-simplify-17-d4-probe.md。
|
|
33
|
+
*/
|
|
27
34
|
identityEnv?: Record<string, string | undefined>;
|
|
28
35
|
/** L2:manifest 声明的 envPrefixes 放行清单(保留前缀拒绝 + 形态校验) */
|
|
29
36
|
envPrefixes?: readonly string[];
|
|
@@ -38,8 +45,8 @@ interface EngineChildEnvOptions {
|
|
|
38
45
|
* L0 键在最后写入故不受 L1 剥除影响(交集为 ∅ 由测试断言兜底)。
|
|
39
46
|
*
|
|
40
47
|
* 层规格(impl-plan §2.12 三层表):
|
|
41
|
-
* - L0 基础设施键:
|
|
42
|
-
* (条件)/
|
|
48
|
+
* - L0 基础设施键:TAIJI_AGENT_DATA_DIR / TAIJI_AGENT_ENGINE_NODE / ELECTRON_RUN_AS_NODE
|
|
49
|
+
* (条件)/ TAIJI_AGENT_SUBAGENT=1 / relay 三键 / identityEnv(injectL0InfraKeys);
|
|
43
50
|
* - L1 deny + 显式剥除(恒高于 manifest 放行):ENGINE_ENV_DENY_LIST
|
|
44
51
|
* (deny 两键 + 凭证键 + 父身份键 + 防御性剥除三死名);
|
|
45
52
|
* - L2 manifest 放行:envPrefixes 声明前缀的 processEnv 键(保留前缀拒绝、
|
|
@@ -62,7 +69,7 @@ interface BuildOutboundChildEnvOptions {
|
|
|
62
69
|
* execFile 等)复用——R3 MF-C:deny 键不进 git 子进程,git hooks 等后代不再可能
|
|
63
70
|
* 消费生命周期标志 / WS 令牌。
|
|
64
71
|
*
|
|
65
|
-
* 与 @
|
|
72
|
+
* 与 @taiji/shared 版 buildOutboundChildEnv 的刻意差异:**缺省不做白名单过滤**
|
|
66
73
|
* (prefixes 省略 = 全量继承父 env + deny 剥除)。理由:SDK 消费面(zsw 宿主 /
|
|
67
74
|
* 引擎 CLI)不可 import shared 的 ENV_WHITELIST_PREFIXES;引擎 spawn 的基座由
|
|
68
75
|
* 调用方先经 buildEngineChildEnv 组装(其 baseEnv 已是 core 过滤后的),而
|
package/dist/env.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as AgentEvent, E as EngineCapabilities } from './contract-types-
|
|
1
|
+
import { a as AgentEvent, E as EngineCapabilities } from './contract-types-Dsvy79r3.js';
|
|
2
2
|
|
|
3
3
|
/** 协议错误对象(error 帧载荷与反向请求错误应答共用形态)。 */
|
|
4
4
|
interface ProtocolError {
|
|
@@ -87,20 +87,20 @@ declare class EngineSdkError extends Error {
|
|
|
87
87
|
}
|
|
88
88
|
declare function engineProtocolMismatchError(engineVersion: number): EngineSdkError;
|
|
89
89
|
/**
|
|
90
|
-
* [
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* engine_capability_unsupported +
|
|
95
|
-
*
|
|
90
|
+
* 引擎 conversation 位拒绝的具名错误([modeless 波2] 语义:无 resume 续聊通道的
|
|
91
|
+
* 引擎,message 续聊资格被拒——manifest conversation 能力轴消费;[modeless 波5
|
|
92
|
+
* 收尾] core capability-gate 的显式参数分支随派发参数删除退役,本构造器消费方 =
|
|
93
|
+
* 引擎侧 resume gate(assertChatConversationSupported)与 message 资格门)。
|
|
94
|
+
* 文案契约:错误码 engine_capability_unsupported + 「换引擎续聊 / 修 manifest /
|
|
95
|
+
* 升级引擎包」恢复指引,两侧一致防漂移。
|
|
96
96
|
*/
|
|
97
97
|
declare function engineConversationUnsupportedError(engineId: string): EngineSdkError;
|
|
98
98
|
/**
|
|
99
|
-
*
|
|
100
|
-
* manifest conversation 位 unsupported 即抛 engineConversationUnsupportedError
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
99
|
+
* resume 会话形态(run.params.resume——唯一会话形态键)派发前的同步 gate:
|
|
100
|
+
* manifest conversation 位 unsupported 即抛 engineConversationUnsupportedError
|
|
101
|
+
* ——进程/record 创建前同步拒(A6 方向防御:manifest/实装漂移时引擎侧自拒,
|
|
102
|
+
* 与 core capability-gate 同一能力位,防两侧判据漂移)。[modeless 波2] 协议
|
|
103
|
+
* task 的 conversation 键已删,本 gate 只对 resume 形态键生效。
|
|
104
104
|
*/
|
|
105
105
|
declare function assertChatConversationSupported(engineId: string, capabilities: Pick<EngineCapabilities, "conversation">): void;
|
|
106
106
|
/** stdout 尾部回显上限(engine_timeout / engine_run_failed 的错误规格载体系数)。 */
|