@feng0531/dsh-execution-bus 0.12.1 → 1.0.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.
Files changed (44) hide show
  1. package/README.md +47 -264
  2. package/cordis.patch.yml +1 -1
  3. package/dist/error-codes.d.ts +14 -0
  4. package/dist/error-codes.js +15 -0
  5. package/dist/mode.d.ts +2 -2
  6. package/dist/mode.js +7 -7
  7. package/dist/plugin.d.ts +2 -6
  8. package/dist/plugin.js +28 -232
  9. package/dist/preset.d.ts +1 -1
  10. package/dist/preset.js +4 -6
  11. package/dist/product.d.ts +91 -195
  12. package/dist/product.js +66 -146
  13. package/dist/runtime/executor.d.ts +18 -0
  14. package/dist/runtime/executor.js +239 -0
  15. package/dist/runtime/plan.d.ts +30 -0
  16. package/dist/runtime/plan.js +185 -0
  17. package/dist/runtime/service.d.ts +66 -0
  18. package/dist/runtime/service.js +185 -0
  19. package/dist/runtime/store.d.ts +45 -0
  20. package/dist/runtime/store.js +102 -0
  21. package/docs/DECLARATIVE-RUNTIME.md +44 -0
  22. package/docs/FLOW-TEST.md +7 -54
  23. package/docs/INTEGRATION.md +3 -1
  24. package/docs/PRODUCT.md +15 -42
  25. package/docs/RETROSPECTIVE.md +51 -0
  26. package/docs/host-compatibility.md +11 -74
  27. package/docs/protocol.md +27 -135
  28. package/docs/releases/1.0.0.md +33 -0
  29. package/docs/validation.md +23 -62
  30. package/package.json +4 -6
  31. package/dist/bus.d.ts +0 -153
  32. package/dist/bus.js +0 -833
  33. package/dist/diagnostics.d.ts +0 -41
  34. package/dist/diagnostics.js +0 -32
  35. package/dist/execution.d.ts +0 -70
  36. package/dist/execution.js +0 -193
  37. package/dist/handlers.d.ts +0 -27
  38. package/dist/handlers.js +0 -194
  39. package/dist/json.d.ts +0 -4
  40. package/dist/json.js +0 -46
  41. package/dist/limits.d.ts +0 -20
  42. package/dist/limits.js +0 -23
  43. package/dist/protocol.d.ts +0 -62
  44. package/dist/protocol.js +0 -54
package/dist/plugin.js CHANGED
@@ -1,234 +1,30 @@
1
- import { randomUUID } from "node:crypto";
2
- import { ADMISSION_DEFAULTS, REQUEST_DESCRIPTION, REQUEST_PARAMETERS, STATE_PARAMETERS, } from "./product.js";
3
- import { ExecutionOwner } from "./execution.js";
4
- import { ExecutionBus, parse } from "./bus.js";
5
- import { ERRORS } from "./error-codes.js";
6
- import { testHandler, readHandler, globHandler, grepHandler, editHandler, writeHandler, pwshHandler, } from "./handlers.js";
7
- /** DSH 0.2.1-rc.2 的 PTC 在程序结束(含时间预算到期)时用它作为子调用中断原因;
8
- * 用户/会话取消使用调用方提供的原因,不匹配该固定字符串。 */
9
- const PTC_PROGRAM_SETTLED = "run_code settled";
10
- function isPtcProgramEnd(signal) {
11
- return signal.aborted && signal.reason === PTC_PROGRAM_SETTLED;
12
- }
13
- const REQUEST_KEYS = new Set(["requestId", "messageId", "handler", "input"]);
14
- const CONTROL_KEYS = new Set(["requestId", "messageId", "type"]);
15
- /** 工具入口兼容两种形状:0.11.0 简化调用 {requestId,handler,input,messageId?}
16
- * 或 {requestId,type,messageId?},以及完整 v1 消息。简化形状在进入总线前补齐协议字段。 */
17
- function normalizeToolInput(raw) {
18
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
19
- return raw;
20
- const input = raw;
21
- if (Object.hasOwn(input, "protocolVersion"))
22
- return raw;
23
- if (Object.keys(input).some((key) => !REQUEST_KEYS.has(key) && !CONTROL_KEYS.has(key)) ||
24
- typeof input.requestId !== "string")
25
- throw Error(ERRORS.INVALID_REQUEST);
26
- const messageId = typeof input.messageId === "string" ? input.messageId : randomUUID();
27
- if (Object.hasOwn(input, "handler")) {
28
- if (Object.hasOwn(input, "type") ||
29
- typeof input.handler !== "string")
30
- throw Error(ERRORS.INVALID_REQUEST);
31
- return {
32
- protocolVersion: 1,
33
- messageId,
34
- requestId: input.requestId,
35
- type: "request",
36
- payload: { handler: input.handler, input: input.input },
37
- };
38
- }
39
- if (typeof input.type !== "string" ||
40
- !["status", "result", "cancel"].includes(input.type))
41
- throw Error(ERRORS.INVALID_REQUEST);
42
- return {
43
- protocolVersion: 1,
44
- messageId,
45
- requestId: input.requestId,
46
- type: input.type,
47
- payload: {},
48
- };
49
- }
50
- export const name = "execution-bus";
51
- export const inject = ["tools", "jobs"];
1
+ import { RUNTIME_CANCEL_DESCRIPTION, RUNTIME_RESULT_DESCRIPTION, RUNTIME_RESUME_DESCRIPTION, RUNTIME_RUN_DESCRIPTION, RUNTIME_RUN_ID_PARAMETERS, RUNTIME_RUN_PARAMETERS, RUNTIME_STATUS_DESCRIPTION, RUNTIME_STATUS_PARAMETERS, } from "./product.js";
2
+ import { RuntimeService } from "./runtime/service.js";
3
+ export const name = "xiao-he-runtime";
4
+ export const inject = ["tools"];
5
+ /** 声明式运行时插件:只暴露 runtime_* 工具,执行/持久化在 RuntimeService。 */
52
6
  export function apply(ctx) {
53
- const bus = new ExecutionBus(undefined, ADMISSION_DEFAULTS);
54
- bus.register("test", testHandler);
55
- bus.register("host.read", readHandler);
56
- bus.register("host.glob", globHandler);
57
- bus.register("host.grep", grepHandler);
58
- bus.register("host.edit", editHandler);
59
- bus.register("host.write", writeHandler);
60
- bus.register("host.pwsh", pwshHandler);
61
- const executions = new ExecutionOwner();
62
- ctx.effect(() => () => executions.close(() => bus.close()));
63
- ctx.tools.register({
64
- name: "execution_bus_state",
65
- description: "Read a bounded metadata-only snapshot of this agent session’s bus tasks. No inputs/results, no cross-session access. Do not poll during an awaited request.",
66
- parameters: STATE_PARAMETERS,
67
- output: {
68
- schema: {},
69
- render: (_a, v) => [{ type: "text", text: JSON.stringify(v) }],
70
- },
71
- async execute(raw, exec) {
72
- if (executions.phase !== "open")
73
- throw Error(ERRORS.CLOSED);
74
- if (!exec.agent)
75
- throw Error(ERRORS.OWNING_SESSION_REQUIRED);
76
- if (!raw ||
77
- typeof raw !== "object" ||
78
- Array.isArray(raw) ||
79
- Reflect.ownKeys(raw).length)
80
- throw Error(ERRORS.INVALID_STATE_QUERY);
81
- return bus.inspect({
82
- sessionId: String(exec.agent.id),
83
- callId: String(exec.callId),
84
- });
85
- },
86
- });
87
- ctx.tools.register({
88
- name: "execution_bus",
89
- description: REQUEST_DESCRIPTION,
90
- parameters: REQUEST_PARAMETERS,
91
- output: {
92
- schema: {},
93
- render: (_a, v) => [{ type: "text", text: JSON.stringify(v) }],
94
- },
95
- execute(raw, exec) {
96
- if (executions.phase !== "open")
97
- return Promise.reject(Error(ERRORS.CLOSED));
98
- return executions.track(dispatch(raw, exec));
99
- },
100
- });
101
- async function dispatch(raw, exec) {
102
- if (!exec.agent)
103
- throw Error(ERRORS.OWNING_SESSION_REQUIRED);
104
- const agent = exec.agent;
105
- const owner = {
106
- sessionId: String(agent.id),
107
- callId: String(exec.callId),
108
- };
109
- const m = parse(normalizeToolInput(raw));
110
- if (m.type !== "request")
111
- return bus.command(owner, m);
112
- // 宿主工具转发:仅 host.* handler 注入对应工具的 capability。
113
- const hostTool = hostToolFor(m.payload.handler);
114
- let projection;
115
- const attached = bus.submit(owner, m, (event) => projection?.progress(event), hostTool
116
- ? makeHostInvoke(exec, agent, hostTool.name, hostTool.errorCode)
117
- : undefined);
118
- // 1) 终态复用:已有执行直接读结果,不是新工作受理、不再申请 Job。
119
- const terminal = await readTerminal(attached);
120
- if (terminal)
121
- return terminal;
122
- // 2) 新执行:取得或创建宿主 Job 投影。
123
- const execution = await projectExecution(owner, m, attached, agent.id, (handle) => (projection = handle));
124
- // 3) 挂接取消生命周期,等待投影结算后返回执行快照。
125
- return await awaitProjection(exec, attached, execution);
126
- }
127
- /** 把 host.<tool> handler 名映射到宿主工具名与失败错误码。 */
128
- function hostToolFor(handler) {
129
- if (typeof handler !== "string" || !handler.startsWith("host."))
130
- return undefined;
131
- const name = handler.slice("host.".length);
132
- if (!name)
133
- return undefined;
134
- return {
135
- name,
136
- errorCode: name === "read" ? ERRORS.HOST_READ_FAILED : ERRORS.HOST_TOOL_FAILED,
137
- };
138
- }
139
- /** 为一类宿主工具构造转发能力:出队时重新进入宿主工具管线,沿用宿主权限与工作目录。 */
140
- function makeHostInvoke(exec, agent, toolName, errorCode) {
141
- return async (input, signal) => {
142
- const result = await ctx.tools.execute({
143
- name: toolName,
144
- callId: (String(exec.callId) +
145
- ":bus:" +
146
- randomUUID()),
147
- rootCallId: exec.rootCallId,
148
- parent: exec.token,
149
- agent,
150
- arguments: input,
151
- signal,
152
- });
153
- if (result.isError)
154
- throw Error(errorCode);
155
- return result.value;
156
- };
157
- }
158
- // —— 三个职责单一的拆分函数(闭包内共享 ctx/bus/executions) ——
159
- /** accepted 已是终态时直接返回现有结果;否则返回 undefined 走新执行路径。 */
160
- async function readTerminal(attached) {
161
- const state = attached.accepted.payload.state;
162
- if (state === "queued" || state === "running")
163
- return undefined;
164
- try {
165
- const value = await attached.done;
166
- attached.returned();
167
- return markReused(value, attached);
168
- }
169
- finally {
170
- attached.detach();
171
- }
172
- }
173
- /** 命中已存在的共享投影则复用,否则创建投影;创建失败按 HOST_JOB_UNAVAILABLE 结算。 */
174
- async function projectExecution(owner, m, attached, ownerId, onProjected) {
175
- const jobKey = JSON.stringify([owner.sessionId, m.requestId]);
176
- const existing = executions.get(jobKey);
177
- if (existing) {
178
- // 只让第一个附着把进度投影到共享 Job;后续附着立即解除。
179
- attached.detach();
180
- return existing;
181
- }
182
- try {
183
- const created = executions.create(jobKey, ctx.jobs, ownerId, attached);
184
- onProjected(created);
185
- return created;
186
- }
187
- catch {
188
- attached.cancel();
189
- await attached.done;
190
- attached.detach();
191
- throw Error(ERRORS.HOST_JOB_UNAVAILABLE);
192
- }
193
- }
194
- /** 本次调用是否复用了已有执行;仅在真复用时追加标记,保持首次快照形状不变。 */
195
- function markReused(view, attached) {
196
- return attached.reused ? { ...view, reused: true } : view;
197
- }
198
- /** 外层取消映射:PTC 程序结束(含预算到期)只停止本次等待,已受理执行与
199
- * 宿主 Job 保留,同会话可用同 requestId 的 status/result 取回;其他取消原因
200
- * (用户/会话中断)仍请求取消整个执行。 */
201
- async function awaitProjection(exec, attached, execution) {
202
- let release;
203
- const detachedView = new Promise((resolve) => (release = resolve));
204
- const abort = () => {
205
- if (!isPtcProgramEnd(exec.signal)) {
206
- attached.cancel();
207
- return;
208
- }
209
- attached.detach();
210
- release(attached.snapshot());
211
- };
212
- exec.signal.addEventListener("abort", abort, { once: true });
213
- if (exec.signal.aborted)
214
- abort();
215
- const settled = execution.settled.then(() => ({ kind: "settled" }), (error) => ({ kind: "error", error }));
216
- try {
217
- const outcome = await Promise.race([
218
- settled,
219
- detachedView.then((view) => ({ kind: "detached", view })),
220
- ]);
221
- if (outcome.kind === "detached")
222
- return markReused(outcome.view, attached);
223
- if (outcome.kind === "error")
224
- throw outcome.error;
225
- const value = await attached.done;
226
- attached.returned();
227
- return markReused(value, attached);
228
- }
229
- finally {
230
- exec.signal.removeEventListener("abort", abort);
231
- attached.detach();
232
- }
233
- }
7
+ const runtime = new RuntimeService(ctx);
8
+ ctx.effect(() => () => runtime.dispose());
9
+ const register = (toolName, description, parameters, execute) => {
10
+ ctx.tools.register({
11
+ name: toolName,
12
+ description,
13
+ parameters,
14
+ output: {
15
+ schema: {},
16
+ render: (_args, value) => [
17
+ { type: "text", text: JSON.stringify(value) },
18
+ ],
19
+ },
20
+ async execute(raw, exec) {
21
+ return execute(raw, exec);
22
+ },
23
+ });
24
+ };
25
+ register("runtime_run", RUNTIME_RUN_DESCRIPTION, RUNTIME_RUN_PARAMETERS, (raw, exec) => runtime.run(raw, exec));
26
+ register("runtime_status", RUNTIME_STATUS_DESCRIPTION, RUNTIME_STATUS_PARAMETERS, (raw, exec) => runtime.status(raw, exec));
27
+ register("runtime_result", RUNTIME_RESULT_DESCRIPTION, RUNTIME_RUN_ID_PARAMETERS, (raw, exec) => runtime.result(raw, exec));
28
+ register("runtime_cancel", RUNTIME_CANCEL_DESCRIPTION, RUNTIME_RUN_ID_PARAMETERS, (raw, exec) => runtime.cancel(raw, exec));
29
+ register("runtime_resume", RUNTIME_RESUME_DESCRIPTION, RUNTIME_RUN_ID_PARAMETERS, (raw, exec) => runtime.resume(raw, exec));
234
30
  }
package/dist/preset.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Context, Service } from "@deepseek-ai/cordis";
2
2
  import type { PresetDefinition } from "@deepseek-ai/dsh-agent-preset-registry";
3
- export declare const PRESET_ID: "execution-bus-test";
3
+ export declare const PRESET_ID: "xiao-he-runtime";
4
4
  /** Capture the host-declared composition without evaluating !!js or changing disabled rows. */
5
5
  export declare function derivePreset(content: string): PresetDefinition;
6
6
  /** Host-plane registrar. readDocument is a public serialized declaration, not a private registry read. */
package/dist/preset.js CHANGED
@@ -6,14 +6,12 @@ import { setTimeout as pause } from "node:timers/promises";
6
6
  import { PRODUCT } from "./product.js";
7
7
  import { ERRORS } from "./error-codes.js";
8
8
  export const PRESET_ID = PRODUCT.presetId;
9
- /** 校验派生源组合:拒绝已含总线,以及缺少公开基准地址的相对模块/include 子文件。 */
9
+ /** 校验派生源组合:拒绝已含运行时,以及缺少公开基准地址的相对模块/include 子文件。 */
10
10
  function validateDerivation(rows) {
11
11
  for (const row of rows) {
12
- if (row.id === "xiao-he-execution-bus" ||
12
+ if (row.id === "xiao-he-runtime" ||
13
13
  row.name?.startsWith("@feng0531/dsh-execution-bus"))
14
14
  throw Error(ERRORS.PTC_PRESET_ALREADY_CONTAINS_BUS);
15
- // readDocument 不发布声明方的 baseUrl,不能把相对模块/include
16
- // 静默重定位到 registrar 的不同上下文。
17
15
  if (row.name?.startsWith(".") ||
18
16
  row.name === "@deepseek-ai/cordis-plugin-include")
19
17
  throw Error(ERRORS.PTC_PRESET_RELATIVE_BASE_UNSUPPORTED);
@@ -35,11 +33,11 @@ export function derivePreset(content) {
35
33
  id: PRESET_ID,
36
34
  name: PRODUCT.name,
37
35
  order: 20,
38
- description: "继承宿主 PTC 工具组合,叠加执行请求排队、等待与结果回传。普通任务使用原工具,授权和沙箱由宿主管理;不支持重启恢复。",
36
+ description: "继承宿主 PTC 工具组合,叠加声明式运行时(runtime_*):DAG 计划、并行/重试/超时、落盘与恢复。普通任务使用原工具,授权和沙箱由宿主管理;不保证 exactly-once。",
39
37
  plugins: [
40
38
  ...rows,
41
39
  {
42
- id: "xiao-he-execution-bus",
40
+ id: "xiao-he-runtime",
43
41
  name: PRODUCT.modeEntry,
44
42
  },
45
43
  ],
package/dist/product.d.ts CHANGED
@@ -1,210 +1,106 @@
1
- /** Stable product identities and policy. Historical IDs are compatibility contracts, not display names. */
1
+ /** Stable product identities and model-visible runtime policy. */
2
2
  export declare const PRODUCT: Readonly<{
3
3
  name: "萧何 / Xiao He";
4
4
  packageName: "@feng0531/dsh-execution-bus";
5
- presetId: "execution-bus-test";
6
- presetRowId: "preset-execution-bus-test";
5
+ presetId: "xiao-he-runtime";
6
+ presetRowId: "preset-xiao-he-runtime";
7
7
  modeEntry: "@feng0531/dsh-execution-bus/mode";
8
- modePluginName: "execution-bus-mode";
8
+ modePluginName: "xiao-he-runtime-mode";
9
9
  }>;
10
- export declare const CORE_DEFAULTS: Readonly<{
11
- concurrency: 2;
12
- queueLimit: 32;
13
- recordLimit: 256;
14
- resultBytes: 65536;
15
- retentionMs: 3600000;
16
- }>;
17
- export declare const ADMISSION_DEFAULTS: Readonly<{
18
- sessionQueueLimit: 16;
19
- maxQueueWaitMs: 120000;
20
- }>;
21
- export declare const HANDLER_LIMITS: Readonly<{
22
- readLines: 100;
23
- readPathChars: 2048;
24
- diagnosticDelayMs: 30000;
25
- }>;
26
- /** 调度策略:类别优先级 + 等待老化 + 长任务诊断阈值。 */
27
- export declare const SCHEDULER_POLICY: Readonly<{
28
- longRunningMs: 30000;
29
- queueAgingMs: 30000;
30
- queueClassOrder: Readonly<Record<string, number>>;
31
- }>;
32
- export declare const REQUEST_PARAMETERS: {
33
- readonly oneOf: readonly [...{
34
- type: "object";
35
- additionalProperties: false;
36
- required: string[];
37
- properties: {
38
- requestId: {
39
- readonly type: "string";
40
- };
41
- messageId: {
42
- readonly type: "string";
43
- };
44
- handler: {
45
- type: "string";
46
- const: "host.read" | "host.glob" | "host.grep" | "host.edit" | "host.write" | "host.pwsh" | "test";
47
- };
48
- input: {
49
- readonly type: "object";
50
- readonly additionalProperties: false;
51
- readonly required: readonly ["delayMs", "fail"];
52
- readonly properties: {
53
- readonly delayMs: {
54
- readonly type: "integer";
55
- readonly description: "Diagnostic delay in milliseconds (0-30000).";
56
- };
57
- readonly fail: {
58
- readonly type: "boolean";
59
- readonly description: "Settle as a controlled failure when true.";
60
- };
61
- };
62
- } | {
63
- readonly type: "object";
64
- readonly additionalProperties: false;
65
- readonly required: readonly ["file_path"];
66
- readonly properties: {
67
- readonly file_path: {
68
- readonly type: "string";
69
- readonly description: "Path resolved against the session working directory.";
70
- };
71
- readonly offset: {
72
- readonly type: "integer";
73
- readonly description: "1-based first line to read.";
74
- };
75
- readonly limit: {
76
- readonly type: "integer";
77
- readonly description: "Maximum lines to read (<=100).";
78
- };
79
- };
80
- } | {
81
- readonly type: "object";
82
- readonly additionalProperties: false;
83
- readonly required: readonly ["pattern"];
84
- readonly properties: {
85
- readonly pattern: {
86
- readonly type: "string";
87
- readonly description: "Glob pattern; a bare pattern matches basenames at any depth.";
88
- };
89
- readonly path: {
90
- readonly type: "string";
91
- readonly description: "Directory to search; defaults to the session working directory.";
92
- };
93
- };
94
- } | {
95
- readonly type: "object";
96
- readonly additionalProperties: false;
97
- readonly required: readonly ["pattern"];
98
- readonly properties: {
99
- readonly pattern: {
100
- readonly type: "string";
101
- readonly description: "Ripgrep regular expression.";
102
- };
103
- readonly path: {
104
- readonly type: "string";
105
- readonly description: "File or directory to search; defaults to the session working directory.";
106
- };
107
- readonly include: {
108
- readonly type: "string";
109
- readonly description: "One positive glob filter; negation and comma lists are rejected.";
110
- };
111
- };
112
- } | {
113
- readonly type: "object";
114
- readonly additionalProperties: false;
115
- readonly required: readonly ["file_path", "old_string", "new_string"];
116
- readonly properties: {
117
- readonly file_path: {
118
- readonly type: "string";
119
- readonly description: "File to edit.";
120
- };
121
- readonly old_string: {
122
- readonly type: "string";
123
- readonly description: "Literal text to replace.";
124
- };
125
- readonly new_string: {
126
- readonly type: "string";
127
- readonly description: "Replacement text.";
128
- };
129
- readonly replace_all: {
130
- readonly type: "boolean";
131
- readonly description: "Replace every occurrence.";
132
- };
10
+ export declare const RUNTIME_RUN_PARAMETERS: {
11
+ readonly type: "object";
12
+ readonly properties: {
13
+ readonly plan: {
14
+ readonly type: "object";
15
+ readonly properties: {
16
+ readonly goal: {
17
+ readonly type: "string";
18
+ readonly maxLength: 500;
133
19
  };
134
- } | {
135
- readonly type: "object";
136
- readonly additionalProperties: false;
137
- readonly required: readonly ["file_path", "content"];
138
- readonly properties: {
139
- readonly file_path: {
140
- readonly type: "string";
141
- readonly description: "File to write.";
142
- };
143
- readonly content: {
144
- readonly type: "string";
145
- readonly description: "Full file content.";
146
- };
20
+ readonly concurrency: {
21
+ readonly type: "integer";
22
+ readonly minimum: 1;
23
+ readonly maximum: 4;
147
24
  };
148
- } | {
149
- readonly type: "object";
150
- readonly additionalProperties: false;
151
- readonly required: readonly ["description", "command"];
152
- readonly properties: {
153
- readonly description: {
154
- readonly type: "string";
155
- readonly description: "Clear, concise description of what the command does (shown in the UI).";
156
- };
157
- readonly command: {
158
- readonly type: "string";
159
- readonly description: "PowerShell command to execute.";
160
- };
161
- readonly timeoutMs: {
162
- readonly type: "number";
163
- readonly description: "Positive timeout in milliseconds.";
164
- };
165
- readonly workdir: {
166
- readonly type: "string";
167
- readonly description: "Working directory; defaults to the session working directory.";
168
- };
169
- readonly run_in_background: {
170
- readonly type: "boolean";
171
- readonly description: "Return a host Job id immediately instead of waiting.";
172
- };
173
- readonly sandbox_permissions: {
174
- readonly type: "string";
175
- readonly enum: readonly ["workspace-write", "danger-full-access"];
176
- readonly description: "Narrowest wider sandbox mode; must be paired with justification.";
177
- };
178
- readonly justification: {
179
- readonly type: "string";
180
- readonly description: "Required with sandbox_permissions; one sentence of reason.";
181
- };
25
+ readonly steps: {
26
+ readonly type: "array";
27
+ readonly items: {
28
+ readonly type: "object";
29
+ readonly properties: {
30
+ readonly id: {
31
+ readonly type: "string";
32
+ readonly description: "步骤唯一 ID(字母开头,可含字母/数字/_-)";
33
+ };
34
+ readonly tool: {
35
+ readonly type: "string";
36
+ readonly enum: readonly ["read", "glob", "grep", "edit", "write", "pwsh"];
37
+ readonly description: "允许的宿主工具";
38
+ };
39
+ readonly input: {
40
+ readonly type: "object";
41
+ readonly description: "宿主工具参数,按工具 schema 校验";
42
+ };
43
+ readonly depends_on: {
44
+ readonly type: "array";
45
+ readonly items: {
46
+ readonly type: "string";
47
+ };
48
+ readonly description: "依赖步骤 ID;全部成功后本步骤才执行";
49
+ };
50
+ readonly retry: {
51
+ readonly type: "integer";
52
+ readonly minimum: 0;
53
+ readonly maximum: 3;
54
+ readonly description: "仅幂等工具 read/glob/grep 允许 >0;重试次数不含首次";
55
+ };
56
+ readonly timeout_ms: {
57
+ readonly type: "integer";
58
+ readonly minimum: 1000;
59
+ readonly maximum: 600000;
60
+ };
61
+ };
62
+ readonly required: readonly ["id", "tool", "input"];
63
+ readonly additionalProperties: false;
64
+ };
65
+ readonly minItems: 1;
66
+ readonly maxItems: 32;
182
67
  };
183
68
  };
69
+ readonly required: readonly ["steps"];
70
+ readonly additionalProperties: false;
184
71
  };
185
- }[], {
186
- readonly type: "object";
187
- readonly additionalProperties: false;
188
- readonly required: readonly ["requestId", "type"];
189
- readonly properties: {
190
- readonly requestId: {
191
- readonly type: "string";
192
- };
193
- readonly messageId: {
194
- readonly type: "string";
195
- };
196
- readonly type: {
197
- readonly type: "string";
198
- readonly enum: readonly ["status", "result", "cancel"];
199
- readonly description: "Read the saved snapshot or request cancellation for this requestId.";
200
- };
72
+ readonly async: {
73
+ readonly type: "boolean";
74
+ readonly description: "true 时立即返回 runId,用 runtime_status/runtime_result 取回";
201
75
  };
202
- }];
76
+ };
77
+ readonly required: readonly ["plan"];
78
+ readonly additionalProperties: false;
203
79
  };
204
- export declare const STATE_PARAMETERS: {
80
+ export declare const RUNTIME_RUN_ID_PARAMETERS: {
205
81
  readonly type: "object";
206
- readonly properties: {};
82
+ readonly properties: {
83
+ readonly runId: {
84
+ readonly type: "string";
85
+ readonly description: "runtime_run 返回的运行 ID";
86
+ };
87
+ };
88
+ readonly required: readonly ["runId"];
89
+ readonly additionalProperties: false;
90
+ };
91
+ export declare const RUNTIME_STATUS_PARAMETERS: {
92
+ readonly type: "object";
93
+ readonly properties: {
94
+ readonly runId: {
95
+ readonly type: "string";
96
+ readonly description: "可选:指定运行 ID;省略时列出最近运行";
97
+ };
98
+ };
207
99
  readonly additionalProperties: false;
208
100
  };
209
- export declare const REQUEST_DESCRIPTION = "\u8427\u4F55 / Xiao He. Submit a request and WAIT for its terminal snapshot; the simplified call takes {requestId, handler, input} (messageId optional) and control calls take {requestId, type:\"status\"|\"result\"|\"cancel\"}. Use only when coordination helps: the same logical operation may be retried or deduplicated (reuse requestId), work must outlive a run_code budget end, or multiple steps must await one execution. Duration alone is not a reason \u2014 for a one-off long command use the original tool or its background Job. A PTC program end only stops waiting: accepted work continues and the same requestId can be retrieved with type:\"result\" or cancelled. Do not poll status inside the same run_code program as an unfinished request: end that program and retrieve in a later step. The snapshot may contain reused:true when this call attached to an existing execution. The full v1 envelope is still accepted. Diagnostic handler only: test {delayMs:0..30000,fail:boolean}; never use it for real work. Acceptance is volatile, not success. No polling or restart resume.";
210
- export declare const MODE_INSTRUCTIONS: string;
101
+ export declare const RUNTIME_RUN_DESCRIPTION = "\u8427\u4F55\u58F0\u660E\u5F0F\u8FD0\u884C\u65F6\uFF1A\u63D0\u4EA4 DAG \u8BA1\u5212\uFF08steps\uFF1Aid/tool/input/depends_on/retry/timeout_ms\uFF09\uFF0C\u7531\u7A0B\u5E8F\u6309\u4F9D\u8D56\u5E76\u884C\u6267\u884C\u3001\u5BF9\u53EA\u8BFB\u6B65\u9AA4\u91CD\u8BD5\u3001\u9010\u6B65\u843D\u76D8\u3002\u9ED8\u8BA4\u7B49\u5F85\u5B8C\u6210\u8FD4\u56DE\u6B65\u9AA4\u72B6\u6001\uFF1Basync:true \u7ACB\u5373\u8FD4\u56DE runId\uFF0C\u7528 runtime_status/runtime_result \u53D6\u56DE\uFF0Cruntime_cancel \u53D6\u6D88\u3002\u4EC5\u5141\u8BB8 read/glob/grep/edit/write/pwsh\uFF1B\u526F\u4F5C\u7528\u6B65\u9AA4\u4E0D\u91CD\u8BD5\u3001\u5D29\u6E83\u540E\u5728\u9014\u6B65\u9AA4\u6807\u8BB0 unknown\uFF08\u4E0D\u505A exactly-once \u56DE\u6EDA\uFF09\u3002\u7B80\u5355\u4E00\u6B21\u8C03\u7528\u8BF7\u76F4\u63A5\u7528\u539F\u5DE5\u5177\u3002";
102
+ export declare const RUNTIME_STATUS_DESCRIPTION = "\u8BFB\u53D6\u672C\u4F1A\u8BDD\u7684\u8FD0\u884C\u5143\u6570\u636E\uFF1A\u4E0D\u5E26 runId \u5217\u51FA\u6700\u8FD1\u8FD0\u884C\uFF0C\u5E26 runId \u8FD4\u56DE\u6307\u5B9A\u8FD0\u884C\u4E0E\u6B65\u9AA4\u72B6\u6001\uFF08\u4E0D\u542B\u7ED3\u679C\uFF09\u3002\u4E0D\u8981\u8F6E\u8BE2\u6B63\u5728\u7B49\u5F85\u7684 runtime_run\u3002";
103
+ export declare const RUNTIME_RESULT_DESCRIPTION = "\u8BFB\u53D6\u6307\u5B9A\u8FD0\u884C\u5DF2\u4FDD\u5B58\u7684\u6B65\u9AA4\u7ED3\u679C\uFF08\u5355\u6B65\u7ED3\u679C\u8D85\u8FC7 64KiB \u65F6\u53EA\u8FD4\u56DE truncated/bytes \u6807\u8BB0\uFF09\u3002";
104
+ export declare const RUNTIME_CANCEL_DESCRIPTION = "\u8BF7\u6C42\u53D6\u6D88\u6307\u5B9A\u8FD0\u884C\uFF1A\u505C\u6B62\u8C03\u5EA6\u3001\u5411\u540E\u53D1\u6B65\u9AA4\u4F20\u64AD\u53D6\u6D88\uFF1B\u5DF2\u5F00\u59CB\u7684\u526F\u4F5C\u7528\u6B65\u9AA4\u72B6\u6001\u53EF\u80FD\u4E3A unknown\u3002";
105
+ export declare const RUNTIME_RESUME_DESCRIPTION = "\u6062\u590D interrupted \u8FD0\u884C\uFF1A\u53EA\u8BFB\u6B65\u9AA4\u91CD\u65B0\u6392\u961F\uFF0C\u526F\u4F5C\u7528\u5728\u9014\u6B65\u9AA4\u6807\u8BB0 failed\uFF08RUNTIME_INTERRUPTED\uFF09\uFF1B\u4E0D\u81EA\u52A8\u6267\u884C\uFF0C\u9700\u663E\u5F0F\u8C03\u7528\u3002";
106
+ export declare const RUNTIME_INSTRUCTIONS = "\u8427\u4F55\u58F0\u660E\u5F0F\u8FD0\u884C\u65F6\uFF1A\u5F53\u4EFB\u52A1\u80FD\u5199\u6210\u7A33\u5B9A\u7684 DAG\uFF08\u8BFB\u53D6/\u641C\u7D22/\u7F16\u8F91/\u5199\u5165/\u547D\u4EE4\uFF0C\u6B65\u9AA4\u95F4\u6709\u660E\u786E\u4F9D\u8D56\uFF09\u65F6\uFF0C\u7528 runtime_run \u63D0\u4EA4\u8BA1\u5212\uFF0C\u800C\u4E0D\u662F\u5728 run_code \u91CC\u5199\u5FAA\u73AF\u6216\u53CD\u590D\u7B49\u5F85\u3002\u72EC\u7ACB\u6B65\u9AA4\u4F1A\u5E76\u884C\uFF1B\u53EA\u8BFB\u6B65\u9AA4\u53EF retry\uFF1B\u8FD0\u884C\u8BB0\u5F55\u843D\u76D8\uFF0C\u53EF\u7528 runtime_status/runtime_result/runtime_cancel/runtime_resume\u3002\u526F\u4F5C\u7528\u6B65\u9AA4\u4E0D\u91CD\u8BD5\u3001\u5D29\u6E83\u540E\u5728\u9014\u6B65\u9AA4\u53EF\u80FD unknown\uFF0C\u4E0D\u4FDD\u8BC1 exactly-once\uFF1B\u7B80\u5355\u4E00\u6B21\u6027\u64CD\u4F5C\u4ECD\u7528\u539F\u5DE5\u5177\u6216\u5BBF\u4E3B\u540E\u53F0 Job\uFF0C\u4E0D\u8981\u4E3A\u5305\u88C5\u800C\u5305\u88C5\u3002";