@zhushanwen/subagent-core 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -2
- package/agents/analyst.md +60 -0
- package/agents/coder.md +69 -0
- package/agents/debugger.md +66 -0
- package/agents/doc-reviewer.md +49 -0
- package/agents/explorer.md +63 -0
- package/agents/general-purpose.md +32 -0
- package/agents/orchestrator.md +61 -0
- package/agents/planner.md +53 -0
- package/agents/researcher.md +67 -0
- package/agents/reviewer.md +73 -0
- package/dist/chunk-4KN4TTG7.js +240 -0
- package/dist/chunk-APZY4IME.js +27 -0
- package/dist/chunk-X7SZ5HLQ.js +66 -0
- package/dist/execution/engine/engines/zcode/constants.cjs +65 -0
- package/dist/execution/engine/engines/zcode/constants.d.cts +93 -1
- package/dist/execution/engine/engines/zcode/constants.d.ts +93 -1
- package/dist/execution/engine/engines/zcode/constants.js +43 -1
- package/dist/execution/engine/engines/zcode/reader.d.cts +1 -1
- package/dist/execution/engine/engines/zcode/reader.d.ts +1 -1
- package/dist/execution/engine/engines/zcode/reader.js +4 -234
- package/dist/execution/engine/paths.js +7 -19
- package/dist/index.cjs +14709 -100
- package/dist/index.d.cts +4053 -200
- package/dist/index.d.ts +4053 -200
- package/dist/index.js +14358 -102
- package/dist/{types-BxyAidGf.d.cts → types-DpUO16pj.d.cts} +464 -1
- package/dist/{types-BxyAidGf.d.ts → types-DpUO16pj.d.ts} +464 -1
- package/package.json +6 -3
- package/src/__tests__/review-fix-loop-script.test.ts +90 -2
- package/src/__tests__/review-fix-loop-utils.test.ts +21 -0
- package/src/__tests__/smoke.test.ts +9 -2
- package/src/execution/__tests__/agent-profile.test.ts +232 -0
- package/src/execution/__tests__/agents-assembly.test.ts +219 -0
- package/src/execution/__tests__/chat-engine-routing.test.ts +71 -0
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +1 -0
- package/src/execution/__tests__/create-concurrency-pool.test.ts +194 -0
- package/src/execution/__tests__/delivery-methods.test.ts +2 -0
- package/src/execution/__tests__/descendant-sweep.test.ts +269 -0
- package/src/execution/__tests__/dialog-queue.test.ts +199 -1
- package/src/execution/__tests__/epipe-fallback.test.ts +2 -0
- package/src/execution/__tests__/execution-runtime-face.test.ts +272 -0
- package/src/execution/__tests__/finalize-record.test.ts +106 -0
- package/src/execution/__tests__/gc-timer.test.ts +2 -0
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +2 -0
- package/src/execution/__tests__/get-state-handshake.test.ts +127 -0
- package/src/execution/__tests__/keep-alive-no-progress.test.ts +378 -0
- package/src/execution/__tests__/kill-all-escalation.test.ts +196 -0
- package/src/execution/__tests__/lifecycle-manager-idle-timer-identity.test.ts +117 -0
- package/src/execution/__tests__/lifecycle-manager.test.ts +39 -0
- package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +99 -0
- package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +113 -0
- package/src/execution/__tests__/notify-ledger.test.ts +294 -0
- package/src/execution/__tests__/record-store-orphan-revive.test.ts +159 -0
- package/src/execution/__tests__/record-store.test.ts +83 -0
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +4 -0
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +1 -0
- package/src/execution/__tests__/run-spawn-edges.test.ts +407 -17
- package/src/execution/__tests__/run-spawn-integration.test.ts +1 -1
- package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +12 -4
- package/src/execution/__tests__/service-kill-escalation.test.ts +89 -0
- package/src/execution/__tests__/session-pending.test.ts +228 -0
- package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +110 -0
- package/src/execution/__tests__/session-runner-close-prune.test.ts +181 -0
- package/src/execution/__tests__/session-runner-epipe.test.ts +1 -0
- package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +226 -0
- package/src/execution/__tests__/settled-watchdog.test.ts +289 -0
- package/src/execution/__tests__/spawned-children.test.ts +153 -10
- package/src/execution/__tests__/subagent-actions-core.test.ts +997 -0
- package/src/execution/__tests__/subagent-service-message-close.test.ts +71 -10
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +174 -0
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +266 -0
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +3 -0
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +316 -0
- package/src/execution/__tests__/timeout-integration.test.ts +7 -7
- package/src/execution/__tests__/ui-request-handler-factory.test.ts +95 -1
- package/src/execution/__tests__/ui-request-queue.test.ts +25 -0
- package/src/execution/__tests__/worktree-git-ops.test.ts +571 -0
- package/src/execution/__tests__/worktree-reconcile-aging.test.ts +204 -0
- package/src/execution/agent-registry.ts +225 -1
- package/src/execution/agents-assembly.ts +88 -0
- package/src/execution/concurrency-pool.ts +71 -9
- package/src/execution/dialog-queue.ts +101 -3
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +49 -2
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +87 -1
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +26 -0
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +83 -1
- package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +131 -0
- package/src/execution/engine/__tests__/registry.test.ts +90 -1
- package/src/execution/engine/engine-discovery.ts +12 -16
- package/src/execution/engine/engines/pi/task-spec-mapper.ts +3 -3
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +274 -0
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +36 -0
- package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +472 -0
- package/src/execution/engine/engines/zcode/__tests__/preparer-appserver.test.ts +387 -0
- package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +780 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +815 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +462 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +119 -1
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +136 -6
- package/src/execution/engine/engines/zcode/appserver-home.ts +442 -0
- package/src/execution/engine/engines/zcode/appserver-probe.ts +141 -0
- package/src/execution/engine/engines/zcode/connection.ts +585 -0
- package/src/execution/engine/engines/zcode/constants.ts +129 -0
- package/src/execution/engine/engines/zcode/golden-sample.ts +54 -8
- package/src/execution/engine/engines/zcode/preparer.ts +25 -22
- package/src/execution/engine/engines/zcode/session-channel.ts +656 -0
- package/src/execution/engine/engines/zcode/zcode-engine.ts +909 -41
- package/src/execution/engine/host-task-spec.ts +3 -3
- package/src/execution/engine/port.ts +41 -1
- package/src/execution/engine/registry.ts +53 -0
- package/src/execution/finalize-record.ts +63 -5
- package/src/execution/get-state-handshake.ts +85 -10
- package/src/execution/lifecycle-manager.ts +27 -3
- package/src/execution/manifest-store.ts +53 -62
- package/src/execution/notifier.ts +10 -10
- package/src/execution/notify-ledger.ts +117 -16
- package/src/execution/record-entry.ts +8 -2
- package/src/execution/record-store.ts +29 -15
- package/src/execution/session-pending.ts +213 -62
- package/src/execution/session-runner.ts +974 -128
- package/src/execution/sessions-index.ts +10 -55
- package/src/execution/settled-watchdog.ts +99 -0
- package/src/execution/subagent-actions-core.ts +686 -0
- package/src/execution/subagent-service.ts +396 -49
- package/src/execution/ui-request-handler-factory.ts +27 -4
- package/src/execution/worktree-git-ops.ts +397 -0
- package/src/execution/worktree-manager.ts +72 -10
- package/src/execution/worktree-registry.ts +6 -12
- package/src/index.ts +413 -6
- package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +42 -3
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +2 -4
- package/src/orchestration/__tests__/args-meta.test.ts +358 -0
- package/src/orchestration/__tests__/error-recovery-handlers.test.ts +1 -8
- package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +312 -0
- package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +382 -0
- package/src/orchestration/__tests__/file-run-store-prune.test.ts +168 -0
- package/src/orchestration/__tests__/file-run-store-throttle.test.ts +168 -0
- package/src/orchestration/__tests__/file-run-store.test.ts +389 -0
- package/src/orchestration/__tests__/helpers/flush-microtasks.ts +13 -0
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +34 -0
- package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +357 -0
- package/src/orchestration/__tests__/lifecycle-recover-crashed.test.ts +289 -0
- package/src/orchestration/__tests__/lifecycle.test.ts +77 -0
- package/src/orchestration/__tests__/run-snapshot.test.ts +353 -0
- package/src/orchestration/__tests__/script-generate.test.ts +314 -0
- package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +275 -0
- package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +78 -1
- package/src/orchestration/__tests__/workflow-files.test.ts +186 -0
- package/src/orchestration/__tests__/workflow-run-summary.test.ts +119 -0
- package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +124 -0
- package/src/orchestration/agent-opts-resolver.ts +7 -7
- package/src/orchestration/args-meta.ts +198 -0
- package/src/orchestration/error-recovery.ts +416 -146
- package/src/orchestration/execute-agent-call.ts +9 -9
- package/src/orchestration/file-run-store.ts +327 -0
- package/src/orchestration/launcher.ts +35 -26
- package/src/orchestration/lifecycle.ts +355 -79
- package/src/orchestration/models/agent-call.ts +7 -7
- package/src/orchestration/models/budget.ts +5 -5
- package/src/orchestration/models/run-runtime.ts +13 -13
- package/src/orchestration/models/trace.ts +8 -8
- package/src/orchestration/models/workflow-run.ts +27 -27
- package/src/orchestration/models/workflow-script.ts +4 -4
- package/src/orchestration/run-snapshot.ts +266 -0
- package/src/orchestration/script-generate.ts +154 -0
- package/src/orchestration/script-lint.ts +33 -33
- package/src/orchestration/worker-handle.ts +10 -10
- package/src/orchestration/worker-host.ts +10 -10
- package/src/orchestration/worker-script-builder.ts +401 -346
- package/src/orchestration/workflow-files.ts +37 -11
- package/src/orchestration/workflow-run-summary.ts +69 -0
- package/src/orchestration/workflow-script-registry-impl.ts +31 -9
- package/src/shared/__tests__/agent-ref.test.ts +209 -2
- package/src/shared/__tests__/atomic-write.test.ts +267 -0
- package/src/shared/__tests__/bounded-serialize.test.ts +236 -0
- package/src/shared/__tests__/injection-render.test.ts +518 -0
- package/src/shared/__tests__/resource-discovery-host-roots.test.ts +474 -0
- package/src/shared/__tests__/resource-discovery.test.ts +3 -2
- package/src/shared/agent-ref.ts +143 -2
- package/src/shared/atomic-write.ts +320 -0
- package/src/shared/bounded-serialize.ts +154 -0
- package/src/shared/injection-render.ts +279 -0
- package/src/shared/meta-parser.ts +41 -1
- package/src/shared/resource-discovery.ts +104 -37
- package/src/shared/resource-meta.ts +14 -0
- package/src/shared/xml-injection.ts +9 -9
- package/workflows/README.md +9 -9
- package/workflows/chain.js +4 -2
- package/workflows/map-reduce.js +5 -3
- package/workflows/parallel.js +5 -3
- package/workflows/review-fix-loop-utils.cjs +14 -3
- package/workflows/review-fix-loop.js +18 -7
- package/workflows/scatter-gather.js +4 -2
- package/dist/chunk-3VOERJPJ.js +0 -22
|
@@ -1,3 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModelRegistry 的最小接口(duck-typed,测试可 mock)。
|
|
3
|
+
* 字段结构与 Pi SDK 的 ctx.modelRegistry 对齐。
|
|
4
|
+
*/
|
|
5
|
+
interface ModelRegistryLike {
|
|
6
|
+
/** 返回所有已配置鉴权的可用模型。 */
|
|
7
|
+
getAvailable(): ModelInfo[];
|
|
8
|
+
/** 按 (provider, modelId) 查找。 */
|
|
9
|
+
find(provider: string, modelId: string): ModelInfo | undefined;
|
|
10
|
+
/** 校验模型鉴权是否就绪。 */
|
|
11
|
+
hasConfiguredAuth(model: unknown): boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 模型信息(registry 返回元素 / ctx.model 鸭子类型兼容)。
|
|
15
|
+
* ctx.model(SDK Model<Api>)是此类型的超集,运行时直接当 ModelInfo 用。
|
|
16
|
+
*/
|
|
17
|
+
interface ModelInfo {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
provider: string;
|
|
21
|
+
reasoning: boolean;
|
|
22
|
+
thinkingLevelMap?: Record<string, unknown>;
|
|
23
|
+
contextWindow?: number;
|
|
24
|
+
}
|
|
25
|
+
/** agent .md frontmatter 解析结果。 */
|
|
26
|
+
interface AgentConfig {
|
|
27
|
+
/** agent 名(文件名 basename)。 */
|
|
28
|
+
name: string;
|
|
29
|
+
/** system prompt(markdown 正文)。 */
|
|
30
|
+
systemPrompt: string;
|
|
31
|
+
/** tool allowlist(三层过滤之一)。 */
|
|
32
|
+
tools?: string[];
|
|
33
|
+
/** 默认模型 override("provider/modelId")。agent 作者显式指定。 */
|
|
34
|
+
model?: string;
|
|
35
|
+
/** 默认 thinkingLevel override。 */
|
|
36
|
+
thinkingLevel?: string;
|
|
37
|
+
/** 默认 background 模式(true 时无显式 wait 走 background)。 */
|
|
38
|
+
defaultBackground?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* 执行引擎 id(agent .md frontmatter engine 字段,D9 per-agent 主通道)。
|
|
41
|
+
* 解析期已对注册表校验(未注册 id 在 agent-registry 抛 EngineNotFoundError);
|
|
42
|
+
* 执行侧(P4 路由层)按 调用参数 > 本字段 > 全局默认 三层取值。
|
|
43
|
+
*/
|
|
44
|
+
engine?: string;
|
|
45
|
+
}
|
|
46
|
+
/** 解析结果(model 实例 + 生效的 thinkingLevel)。 */
|
|
47
|
+
interface ResolvedModel {
|
|
48
|
+
model: ModelInfo;
|
|
49
|
+
thinkingLevel: string | undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
1
52
|
/**
|
|
2
53
|
* 唯一执行状态。所有路径共用。v4 B-1 两态收敛:旧 idle 折入 running、
|
|
3
54
|
* 旧 cancelled 折入 closed(closedReason='cancelled' 区分)。
|
|
@@ -28,6 +79,13 @@ type ExecutionStatus = "running" | "closed";
|
|
|
28
79
|
* 不分),message/fork-from 据此给出可行动指引。
|
|
29
80
|
*/
|
|
30
81
|
type ClosedReason = 'parent-shutdown' | 'parent-fork' | 'parent-new' | 'user-close' | 'cancelled' | 'gc' | 'disconnected';
|
|
82
|
+
/**
|
|
83
|
+
* [v8.5 D] 透明重生守卫拒绝专用错误:messageHandler 的 endedMessageGuard 必须原样
|
|
84
|
+
* 透传本类错误(自带完整行动语言),不得按 A1 分流规则改写——否则 worktree/异进程
|
|
85
|
+
* 占用文案会被「fork-from 指引」覆盖,误导 agent 走已被判死的通道。
|
|
86
|
+
*/
|
|
87
|
+
declare class ResurrectDeniedError extends Error {
|
|
88
|
+
}
|
|
31
89
|
/**
|
|
32
90
|
* 终态三态对外语义(U3 C-outcome 一等披露)。
|
|
33
91
|
*
|
|
@@ -40,6 +98,27 @@ type ClosedReason = 'parent-shutdown' | 'parent-fork' | 'parent-new' | 'user-clo
|
|
|
40
98
|
* 「父进程关闭时子 agent 未完成即失败」,选定行为而非疏漏,勿当 bug 改回 cancelled。
|
|
41
99
|
*/
|
|
42
100
|
type ExecutionOutcome = "completed" | "failed" | "cancelled";
|
|
101
|
+
/**
|
|
102
|
+
* 对外投影的 outcome 联合:含历史 record(outcome 字段诞生前的存量数据)兼容态。
|
|
103
|
+
* 投影层(projectOutcome 唯一出口)对无 outcome 字段的 closed record 按
|
|
104
|
+
* deriveOutcome(closedReason, error) 兜底派生;"closed-legacy" 预留给连派生输入都
|
|
105
|
+
* 不足以判读的存量形态,消费方必须处理该成员(不得因未知值崩溃)。
|
|
106
|
+
*/
|
|
107
|
+
type ProjectedOutcome = ExecutionOutcome | "closed-legacy";
|
|
108
|
+
/**
|
|
109
|
+
* 对外四态(设计决策 10 细则 3):内部 ExecutionStatus(v4 B-1 两态)收敛为 agent
|
|
110
|
+
* 可理解的状态语义。真实映射只有两条:
|
|
111
|
+
* running → active / closed → ended(closed 统一终态,含 cancelled)。
|
|
112
|
+
* mapExternalState 不消费 ClosedReason——closed 恒映射 ended。
|
|
113
|
+
*
|
|
114
|
+
* waiting / error 是历史多态映射(idle→waiting / failed+crashed→error)的遗留声明:
|
|
115
|
+
* 对外四态联合契约不变,但当前状态机不产生这两个值。
|
|
116
|
+
*
|
|
117
|
+
* 原始 ExecutionStatus 进 list item 的 status 字段供调试;state 是对外主字段。
|
|
118
|
+
* 映射实现见 subagent-actions.ts mapExternalState——未来内部加态必须扩展该处,
|
|
119
|
+
* 漏加会在 default 分支编译报错,不影响对外契约。
|
|
120
|
+
*/
|
|
121
|
+
type ExternalState = "active" | "waiting" | "ended" | "error";
|
|
43
122
|
/** 执行模式。background = 调用方立即拿 handle 返回,子 agent 在 detached promise 里跑。 */
|
|
44
123
|
type ExecutionMode = "background";
|
|
45
124
|
/**
|
|
@@ -101,6 +180,39 @@ interface AgentUsageTotal extends AgentUsage$1 {
|
|
|
101
180
|
/** 累计成本(USD,来自 SdkEvent.message.usage.cost.total 求和)。无成本数据时为 0。 */
|
|
102
181
|
cost: number;
|
|
103
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* eventLog 条目(getEventLog 派生产出的元素)。所有字段 readonly。
|
|
185
|
+
*
|
|
186
|
+
* text_output / thinking 类型已移除——它们是 100 字切片的碎片副产物,
|
|
187
|
+
* 现在完整内容收口在 record.turns[] 里,eventLog 只承载离散语义事件
|
|
188
|
+
* (tool 调用 / turn 边界 / error)。
|
|
189
|
+
*/
|
|
190
|
+
interface AgentEventLogEntry {
|
|
191
|
+
readonly type: "tool_start" | "tool_end" | "turn_end" | "error";
|
|
192
|
+
readonly label: string;
|
|
193
|
+
/** 事件发生的墙钟时间戳(Date.now(),ms)。由 getEventLog 从 turns[] 派生时记录。 */
|
|
194
|
+
readonly ts: number;
|
|
195
|
+
readonly status?: "running" | "done" | "failed";
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* [STEP3] displayItem:从 turns[] 派生的展示项(对齐 nicobailon getDisplayItems)。
|
|
199
|
+
*
|
|
200
|
+
* 与 eventLog 的区别:eventLog 承载离散语义事件(tool_start/tool_end/turn_end),
|
|
201
|
+
* displayItem 承载「可渲染单元」(toolCall 含完整 name+args 供 formatToolCall 格式化;
|
|
202
|
+
* text 含 assistant 正文)。renderResult compact 分支改用 displayItems 后,
|
|
203
|
+
* 行格式与 nicobailon 完全一致(→ formatToolCall)。
|
|
204
|
+
*/
|
|
205
|
+
interface DisplayItem {
|
|
206
|
+
readonly type: "toolCall" | "text";
|
|
207
|
+
/** toolCall:tool 名称(bash/read/edit...);text:无。 */
|
|
208
|
+
readonly name?: string;
|
|
209
|
+
/** toolCall:tool 原始 args(供 formatToolCall 提取路径/命令);text:无。 */
|
|
210
|
+
readonly args?: Record<string, unknown>;
|
|
211
|
+
/** toolCall:执行状态(running 时无✓/✗标记);text:正文文本。 */
|
|
212
|
+
readonly status?: "running" | "done" | "failed";
|
|
213
|
+
/** text:assistant 正文(compact 时取首行/截断)。 */
|
|
214
|
+
readonly text?: string;
|
|
215
|
+
}
|
|
104
216
|
/** tool 调用结果(tool_execution_end 时累积,含 structured-output 的 details)。 */
|
|
105
217
|
interface ToolCallResult {
|
|
106
218
|
content?: unknown[];
|
|
@@ -188,6 +300,20 @@ interface WorktreeHandle {
|
|
|
188
300
|
/** 主仓库根目录(cleanup/scan 需要,不再靠路径反推)。 */
|
|
189
301
|
readonly mainCwd: string;
|
|
190
302
|
}
|
|
303
|
+
/** alive marker:子进程存活标记,用于心跳检测和 crash 推断。 */
|
|
304
|
+
interface AliveMarker {
|
|
305
|
+
readonly pid: number;
|
|
306
|
+
readonly id: string;
|
|
307
|
+
readonly startedAt: number;
|
|
308
|
+
}
|
|
309
|
+
/** fork depth 超限错误。 */
|
|
310
|
+
declare class ForkDepthExceededError extends Error {
|
|
311
|
+
constructor(message: string);
|
|
312
|
+
}
|
|
313
|
+
/** worktree 有未提交变更错误。 */
|
|
314
|
+
declare class DirtyWorktreeError extends Error {
|
|
315
|
+
constructor(message: string);
|
|
316
|
+
}
|
|
191
317
|
/**
|
|
192
318
|
* 所有执行路径的唯一状态源。
|
|
193
319
|
*
|
|
@@ -354,6 +480,343 @@ interface ExecutionRecord {
|
|
|
354
480
|
hadWorktree?: boolean;
|
|
355
481
|
controller: AbortController | undefined;
|
|
356
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* Tool 返回的 details(内层扁平结构)。
|
|
485
|
+
* 由 project(record) 唯一产出——sync/bg 两路径字段一致。
|
|
486
|
+
* 含 mode + sessionFile(供外层 SubagentToolResult 分组 + spinner 判断)。
|
|
487
|
+
*
|
|
488
|
+
* 分层(spec FR-3):此为**内层**,不感知 action/外层分组。
|
|
489
|
+
* 外层 SubagentToolResult 由 adapter 包裹产出(加 action/subagentId/sessionFile + 分组)。
|
|
490
|
+
*/
|
|
491
|
+
interface SubagentToolDetails {
|
|
492
|
+
status: ExecutionStatus;
|
|
493
|
+
/**
|
|
494
|
+
* 终态三态对外语义(U3 C-outcome,projectOutcome 唯一出口)。running → undefined;
|
|
495
|
+
* 历史数据无 outcome 字段时兜底派生(见 ProjectedOutcome)。
|
|
496
|
+
*/
|
|
497
|
+
outcome?: ProjectedOutcome;
|
|
498
|
+
mode: ExecutionMode;
|
|
499
|
+
agent: string;
|
|
500
|
+
model: string;
|
|
501
|
+
thinkingLevel: string | undefined;
|
|
502
|
+
/** 短标签(≤35 字符),来自 record.slug。旧 record 反序列化时为空串。 */
|
|
503
|
+
slug: string;
|
|
504
|
+
turns: number;
|
|
505
|
+
totalTokens: number;
|
|
506
|
+
elapsedSeconds: number;
|
|
507
|
+
eventLog: AgentEventLogEntry[];
|
|
508
|
+
/** [STEP3] 从 turns[] 派生的展示项(对齐 nicobailon getDisplayItems)。 */
|
|
509
|
+
displayItems: DisplayItem[];
|
|
510
|
+
result?: string;
|
|
511
|
+
error?: string;
|
|
512
|
+
/** running 时的当前活动行(tool/thinking/text 优先级)。 */
|
|
513
|
+
currentActivity?: {
|
|
514
|
+
type: "tool" | "text" | "thinking";
|
|
515
|
+
label: string;
|
|
516
|
+
};
|
|
517
|
+
/** schema 模式下,structured-output tool 的 result.details(对齐 workflow agent-pool)。 */
|
|
518
|
+
parsedOutput?: unknown;
|
|
519
|
+
/** session jsonl 文件名(不含目录)。窗口期内可能 undefined(session 尚未创建成功)。 */
|
|
520
|
+
sessionFile?: string;
|
|
521
|
+
/** [MF#3] worktree 模式下子 agent 改动的 patch 文件路径(worktree 外,供调用方应用)。 */
|
|
522
|
+
patchFile?: string;
|
|
523
|
+
}
|
|
524
|
+
/** Hub.execute 的入参(sync/bg 共用)。mode 由 Hub 内部判定,不暴露给调用方。 */
|
|
525
|
+
interface ExecuteOptions {
|
|
526
|
+
task: string;
|
|
527
|
+
/**
|
|
528
|
+
* 短标签(≤35 字符),简述本次执行用途,展示在 TUI。必填。
|
|
529
|
+
* workflow 内 agent() 调用时从 AgentCallOpts.description 透传而来。
|
|
530
|
+
*/
|
|
531
|
+
slug: string;
|
|
532
|
+
agent?: string;
|
|
533
|
+
model?: string;
|
|
534
|
+
thinkingLevel?: string;
|
|
535
|
+
skillPath?: string;
|
|
536
|
+
appendSystemPrompt?: string[];
|
|
537
|
+
schema?: Record<string, unknown>;
|
|
538
|
+
/** D-A6 bridge: workflow schemaEnv 经 ExecuteOptions 透传到 runSpawn childEnv。 */
|
|
539
|
+
schemaEnv?: string;
|
|
540
|
+
/**
|
|
541
|
+
* Turn 上限 limiter。显式 0/负 = 显式不限:压过 SPAWN_WATCHDOG_ENV 兑底不挂
|
|
542
|
+
* watchdog(SP-6 参数 > env,U5);undefined 未传才由 env 兑底。
|
|
543
|
+
*/
|
|
544
|
+
maxTurns?: number;
|
|
545
|
+
graceTurns?: number;
|
|
546
|
+
/** sync 模式来自 Pi tool 框架;background 模式 hub 忽略,自建 controller。 */
|
|
547
|
+
signal?: AbortSignal;
|
|
548
|
+
/** 主 agent 当前模型(模型解析第三层兼底)。execute 调用方从 ctx.model 传入。 */
|
|
549
|
+
ctxModel?: ModelInfo;
|
|
550
|
+
/** background 完成回调(sync 不调)。 */
|
|
551
|
+
onComplete?: (record: RecordSnapshot) => void;
|
|
552
|
+
/** 是否继承父会话上下文(fork 模式,只继承上下文)。 */
|
|
553
|
+
fork?: boolean;
|
|
554
|
+
/**
|
|
555
|
+
* [v8.5 B] fork-from 显式指定继承源 session 文件(非主 session)。
|
|
556
|
+
* 与 fork:true 的区别:fork:true 用主 session 作 --fork 源;本字段用任意已有
|
|
557
|
+
* session 文件(断联 subagent 接续场景)作源。优先级高于 fork;传了本字段时
|
|
558
|
+
* fork 取值不影响 spawn 参数。仅 pi 引擎支持(同 fork)。仅 background tool
|
|
559
|
+
* 层 fork-from action 使用;workflow / executeAndAwait 不消费。
|
|
560
|
+
*/
|
|
561
|
+
forkFromSessionFile?: string;
|
|
562
|
+
/** 文件系统隔离:true=创建新 git worktree,WorktreeHandle=复用外部已创建的;undefined=不隔离(parent cwd)。 */
|
|
563
|
+
worktree?: boolean | WorktreeHandle;
|
|
564
|
+
/** 覆盖执行 cwd(默认 mainCwd)。 */
|
|
565
|
+
cwd?: string;
|
|
566
|
+
/**
|
|
567
|
+
* 可持续对话模式(决策 8:独立 chatMode 标志,不扩展 ExecutionMode)。
|
|
568
|
+
* true = record 标记 chatMode,轮次完成进 idle 态(保留 record + worktree,等待 message 续聊);
|
|
569
|
+
* undefined/false = 一次性模式(默认,行为完全不变)。service.execute 透传到 createRecordForMode。
|
|
570
|
+
*/
|
|
571
|
+
conversation?: boolean;
|
|
572
|
+
/**
|
|
573
|
+
* 空闲超时毫秒数(仅 conversation 模式有意义)。覆盖默认 5min idle timeout。
|
|
574
|
+
* 优先级:参数 > env XYZ_SUBAGENT_IDLE_TIMEOUT_MS > 默认 300000ms。
|
|
575
|
+
* 显式传 0/负数 = 禁用 idle GC(不挂 timer;旧实现 0 会落成 setTimeout(0) 立即 kill)。
|
|
576
|
+
*/
|
|
577
|
+
idleTimeoutMs?: number;
|
|
578
|
+
/**
|
|
579
|
+
* 实际执行引擎 id(P4 路由留痕):pi 引擎由 PiEngine.run 在还原 opts 时写入;
|
|
580
|
+
* 缺省(历史调用方不设)= pi 投影。createRecordForMode 读入 record identity。
|
|
581
|
+
*/
|
|
582
|
+
engine?: string;
|
|
583
|
+
/**
|
|
584
|
+
* 引擎 fallback 留痕(D9①:probe 失败路由回默认引擎时由路由层写入)。
|
|
585
|
+
* from = 请求引擎 id,reason 恒 'engine_probe_failed'(GUI 警告条数据源)。
|
|
586
|
+
*/
|
|
587
|
+
engineFallback?: {
|
|
588
|
+
from: string;
|
|
589
|
+
reason: string;
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* execute 返回值。
|
|
594
|
+
* background: { mode:"background", subagentId, sessionFile, details } —— 立即返回。
|
|
595
|
+
* subagentId 供后续 cancel/list 用;sessionFile 窗口期可能 undefined。
|
|
596
|
+
*/
|
|
597
|
+
type ExecutionHandle = {
|
|
598
|
+
mode: "background";
|
|
599
|
+
subagentId: string;
|
|
600
|
+
sessionFile: string | undefined;
|
|
601
|
+
details: SubagentToolDetails;
|
|
602
|
+
};
|
|
603
|
+
/** list 的 item 结构。 */
|
|
604
|
+
interface SubagentListItem {
|
|
605
|
+
subagentId: string;
|
|
606
|
+
agent: string;
|
|
607
|
+
/** 短标签(≤35 字符),来自 record.slug。旧 record 反序列化时为空串。 */
|
|
608
|
+
slug: string;
|
|
609
|
+
/** 对外四态(决策 10 细则 3,主字段)。由 mapExternalState(status) 派生。 */
|
|
610
|
+
state: ExternalState;
|
|
611
|
+
/** 原始内部状态(调试用,供 details 展示)。 */
|
|
612
|
+
status: ExecutionStatus;
|
|
613
|
+
mode: ExecutionMode;
|
|
614
|
+
/** 运行秒数(running 态实时计算,终态 endedAt-startedAt)。 */
|
|
615
|
+
duration: number;
|
|
616
|
+
model: string;
|
|
617
|
+
totalTokens: number;
|
|
618
|
+
/** session jsonl 文件名(窗口期内可能 undefined)。 */
|
|
619
|
+
sessionFile?: string;
|
|
620
|
+
/** 直接父 subagent record ID(顶层 record 为 undefined)。[v4 A-6] 从
|
|
621
|
+
* record.parentRecordId 派生,配合 A-5 直接父守卫(message/close 仅作用于直接子)。 */
|
|
622
|
+
parent?: string;
|
|
623
|
+
/** 可冷路径 resume(running 且无活进程句柄)。[v4 A-6] B-1「可续聊」对外表达,
|
|
624
|
+
* agent 据 list 判断哪些 running subagent 实际可续聊(vs 正在忙)。 */
|
|
625
|
+
resumable?: boolean;
|
|
626
|
+
/**
|
|
627
|
+
* 终态三态对外语义(U3 C-outcome 一等披露,projectOutcome 唯一出口):
|
|
628
|
+
* completed / failed / cancelled,历史 record 无 outcome 字段时兜底派生,
|
|
629
|
+
* 不可判读的存量形态为 "closed-legacy"。GUI pane / agent 据此判读成败,
|
|
630
|
+
* 无需翻 error 字段原文(S5)。
|
|
631
|
+
*/
|
|
632
|
+
outcome?: ProjectedOutcome;
|
|
633
|
+
}
|
|
634
|
+
/** background 启动的内层响应(挂在 SubagentToolResult.bgResponse)。 */
|
|
635
|
+
interface BgResponse {
|
|
636
|
+
status: "running";
|
|
637
|
+
mode: "background";
|
|
638
|
+
/** 启动提示文案("detached, will notify on completion")。 */
|
|
639
|
+
message: string;
|
|
640
|
+
/**
|
|
641
|
+
* 终态三态语义(U3 C-outcome 对外 JSON 契约完备位)。start 时点 record 尚未终态,
|
|
642
|
+
* 恒 undefined(JSON.stringify 落键省略);终态成败语义经 list items[].outcome
|
|
643
|
+
* 披露。旧字段 status/mode/message 原样保留(向后兼容)。
|
|
644
|
+
*/
|
|
645
|
+
outcome?: ProjectedOutcome;
|
|
646
|
+
/**
|
|
647
|
+
* 通知投递契约回显位(U1 预置,U2 通知账本的契约声明)。恒值
|
|
648
|
+
* "ledger+at-least-once":主 agent 在当前 run 结束或有限延迟内收到完成通知,
|
|
649
|
+
* 送达保证为 at-least-once + notifyId 幂等可识别。字段与填充由 U1 负责,
|
|
650
|
+
* 值语义由 U2(execution/notify-ledger.ts)兑现。
|
|
651
|
+
*/
|
|
652
|
+
notifyContract: "ledger+at-least-once";
|
|
653
|
+
}
|
|
654
|
+
/** list 的内层响应(挂在 SubagentToolResult.listResponse)。 */
|
|
655
|
+
interface ListResponse {
|
|
656
|
+
/** items 中 status==="running" 的计数(受 limit 截断如实反映,非全局总数)。 */
|
|
657
|
+
running: number;
|
|
658
|
+
items: SubagentListItem[];
|
|
659
|
+
}
|
|
660
|
+
/** cancel 的内层响应(挂在 SubagentToolResult.cancelResponse)。 */
|
|
661
|
+
interface CancelResponse {
|
|
662
|
+
cancelled: true;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* message 的内层响应(挂在 SubagentToolResult.messageResponse,决策 10 瘦身)。
|
|
666
|
+
*
|
|
667
|
+
* [R1 删除记录] 旧 PendingMessage(在途消息缓存条目,消费确认制,设计决策 6 状态×
|
|
668
|
+
* interrupt 映射)已随 deliverToRunning 一并删除——SP-5 upgrade 后无生产调用方,
|
|
669
|
+
* 配套三段消费链(push / message_start shift / redeliverPending 补投)全部不可达。
|
|
670
|
+
* 详见 subagent-service.ts 的删除记录注释。
|
|
671
|
+
*/
|
|
672
|
+
interface MessageResponse {
|
|
673
|
+
delivered: true;
|
|
674
|
+
}
|
|
675
|
+
/** close 的内层响应(挂在 SubagentToolResult.closeResponse,决策 10 瘦身)。 */
|
|
676
|
+
interface CloseResponse {
|
|
677
|
+
closed: true;
|
|
678
|
+
}
|
|
679
|
+
/** fork-from 的内层响应:新 subagent id + 作为继承源的旧记录 session 文件。
|
|
680
|
+
* [v8.5 B] 断联恢复通道——新 subagent 以 --fork 方式继承旧会话历史,源文件只读
|
|
681
|
+
* 不续写(pi fork 建 branched session,copy-on-write)。 */
|
|
682
|
+
interface ForkFromResponse {
|
|
683
|
+
/** 新 subagent record id(接续对话用 action:'message')。 */
|
|
684
|
+
newSubagentId: string;
|
|
685
|
+
/** 作为继承源的旧 subagent session jsonl 绝对路径。 */
|
|
686
|
+
sourceSessionFile: string;
|
|
687
|
+
}
|
|
688
|
+
/** /subagents list 左列展示单元。来自内存(running) 或 session.jsonl 重建(终态)。 */
|
|
689
|
+
interface SubagentRecord {
|
|
690
|
+
id: string;
|
|
691
|
+
agent: string;
|
|
692
|
+
/** 任务提示词(详情面板置顶展示)。磁盘/内存源均有。 */
|
|
693
|
+
task: string;
|
|
694
|
+
/** 短标签(≤35 字符)。磁盘重建源旧文件可能缺失→兜底空串。 */
|
|
695
|
+
slug: string;
|
|
696
|
+
status: ExecutionStatus;
|
|
697
|
+
/** L2 关闭原因子枚举(仅 status="closed" 时有意义)。SP-1 新增。 */
|
|
698
|
+
closedReason?: ClosedReason;
|
|
699
|
+
mode: ExecutionMode;
|
|
700
|
+
startedAt: number;
|
|
701
|
+
/** 根 Pi session ID(session 隔离过滤用)。递归链上所有层 record 同值。 */
|
|
702
|
+
rootSessionId: string | undefined;
|
|
703
|
+
/** 直接父 subagent record ID(层级树构建用)。顶层 record 为 undefined。 */
|
|
704
|
+
parentRecordId: string | undefined;
|
|
705
|
+
/** subagent 递归深度。顶层 =0,每层嵌套 +1。 */
|
|
706
|
+
depth: number;
|
|
707
|
+
endedAt: number | undefined;
|
|
708
|
+
turns: number;
|
|
709
|
+
totalTokens: number;
|
|
710
|
+
model: string;
|
|
711
|
+
thinkingLevel: string | undefined;
|
|
712
|
+
eventLog: AgentEventLogEntry[];
|
|
713
|
+
/** [STEP3] 从 turns[] 派生的展示项(对齐 nicobailon getDisplayItems)。 */
|
|
714
|
+
displayItems: DisplayItem[];
|
|
715
|
+
/** running 时的当前活动行(仅内存源;磁盘重建无此数据)。streaming 可观测性用。 */
|
|
716
|
+
currentActivity?: {
|
|
717
|
+
type: "tool" | "text" | "thinking";
|
|
718
|
+
label: string;
|
|
719
|
+
};
|
|
720
|
+
result?: string;
|
|
721
|
+
error?: string;
|
|
722
|
+
sessionFile?: string;
|
|
723
|
+
/** [MF#3] worktree 模式下子 agent 改动的 patch 文件路径(worktree 外,供调用方应用)。 */
|
|
724
|
+
patchFile?: string;
|
|
725
|
+
/**
|
|
726
|
+
* [review round2] 创建时启用 worktree 隔离(磁盘重建源从 session entry 恢复;内存源由
|
|
727
|
+
* recordToSubagent 从 worktreeHandle 投影)。getRecordForAction 跨重启重建时据此拒绝续聊。
|
|
728
|
+
*/
|
|
729
|
+
worktree?: boolean;
|
|
730
|
+
/**
|
|
731
|
+
* 对话轮次计数(仅 chatMode idle record 有意义)。round 仅在内存维护(doFinalizeRoundToIdle
|
|
732
|
+
* 递增),跨重启不恢复(round 无磁盘持久化);非对话模式 / 非 idle record 为 undefined。内存源由 recordToSubagent 从
|
|
733
|
+
* ExecutionRecord.round 投影。
|
|
734
|
+
*/
|
|
735
|
+
round?: number;
|
|
736
|
+
/**
|
|
737
|
+
* 对话模式标志(与 ExecutionRecord.chatMode 同义;投影给 GUI 侧 streaming/waiting/done
|
|
738
|
+
* 细分判据——one-shot 轮终(chatMode 非 true + result 有值)显示完成态,chat 轮终显示
|
|
739
|
+
* 等续聊。内存源由 recordToSubagent 投影,磁盘源经 subagent-record entry 重建)。
|
|
740
|
+
*/
|
|
741
|
+
chatMode?: boolean;
|
|
742
|
+
/**
|
|
743
|
+
* 执行态信号(与 ExecutionRecord.resumable 同义):true = 无活进程驱动的 running
|
|
744
|
+
* (轮终 idle / 重建孤儿兜底),GUI 侧据此排除「真在跑」判定。
|
|
745
|
+
*/
|
|
746
|
+
resumable?: boolean;
|
|
747
|
+
/** 外部 Pi 实例(进程隔离模式下由外部启动的子进程)。 */
|
|
748
|
+
externalInstance?: AliveMarker;
|
|
749
|
+
/** fork 模式下的 worktree handle。 */
|
|
750
|
+
worktreeHandle?: WorktreeHandle;
|
|
751
|
+
/**
|
|
752
|
+
* 实际执行引擎 id(P4 路由留痕)。缺省 = pi 投影(存量 record 零迁移);
|
|
753
|
+
* GUI 警告条/引擎标记的数据源之一。
|
|
754
|
+
*/
|
|
755
|
+
engine?: string;
|
|
756
|
+
/** 引擎 fallback 留痕(D9①:probe 失败路由回默认引擎)。GUI 警告条数据源。 */
|
|
757
|
+
engineFallback?: {
|
|
758
|
+
from: string;
|
|
759
|
+
reason: string;
|
|
760
|
+
};
|
|
761
|
+
/**
|
|
762
|
+
* 引擎自描述定位符(U1:EngineHandleData 的持久化消费面子集,引擎无关——
|
|
763
|
+
* sessionRef 整体透传不枚举内部键)。read 降级链①②级的数据源(runtime
|
|
764
|
+
* subagent-engine-history);缺省 = pi(走 JSONL 直读链)。
|
|
765
|
+
*/
|
|
766
|
+
engineHandle?: {
|
|
767
|
+
sessionRef: Record<string, string>;
|
|
768
|
+
journalPath?: string;
|
|
769
|
+
poolKey: string;
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* 全局配置(~/.pi/agent/subagents/config.json)。
|
|
774
|
+
*
|
|
775
|
+
* 模型解析已退化为「主 agent model 优先,仅 override 时查 registry」——
|
|
776
|
+
* 不再有 category/fallback/yolo 字段。config.json 只保留 maxConcurrent
|
|
777
|
+
* (pool 大小)。旧 config.json 中的 categories/fallback 等字段读取时忽略。
|
|
778
|
+
*/
|
|
779
|
+
interface SubagentsGlobalConfig {
|
|
780
|
+
version: number;
|
|
781
|
+
maxConcurrent: number;
|
|
782
|
+
/**
|
|
783
|
+
* 全局默认执行引擎(D9 三层优先级的最底层:调用参数 > agent frontmatter > 本值)。
|
|
784
|
+
* 缺省 'pi'(P4 路由层 DEFAULT_ENGINE_ID)。加载期只做类型校验,注册表校验归路由层。
|
|
785
|
+
*/
|
|
786
|
+
defaultEngine?: string;
|
|
787
|
+
/** 引擎路由策略(D9①):strict=true 时一切 probe 失败直接报错(不 fallback)。 */
|
|
788
|
+
engineRouting?: {
|
|
789
|
+
strict: boolean;
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Record 的只读视图。store.snapshot() 返回。
|
|
794
|
+
* TUI 拿到此类型,保证不会回写 Core 状态。
|
|
795
|
+
*
|
|
796
|
+
* 不含 eventLog——snapshot 的消费点(cancel 判 mode/status、hasRunning 判 mode、
|
|
797
|
+
* toNotifyRecord 取 result/error)均不读 eventLog。需要 eventLog 的场景用 project()
|
|
798
|
+
* 投影的 SubagentToolDetails。需要完整内容用 record.turns[](Core 内部)。
|
|
799
|
+
*/
|
|
800
|
+
interface RecordSnapshot {
|
|
801
|
+
readonly id: string;
|
|
802
|
+
readonly agent: string;
|
|
803
|
+
readonly model: string;
|
|
804
|
+
readonly thinkingLevel: string | undefined;
|
|
805
|
+
readonly mode: ExecutionMode;
|
|
806
|
+
readonly task: string;
|
|
807
|
+
/** 短标签(≤35 字符)。来自 record.slug。 */
|
|
808
|
+
readonly slug: string;
|
|
809
|
+
readonly status: ExecutionStatus;
|
|
810
|
+
/** 对话模式标志(与 ExecutionRecord.chatMode 同源)。cancel 别名判定用。 */
|
|
811
|
+
readonly chatMode?: boolean;
|
|
812
|
+
readonly turns: number;
|
|
813
|
+
readonly totalTokens: number;
|
|
814
|
+
readonly startedAt: number;
|
|
815
|
+
readonly endedAt: number | undefined;
|
|
816
|
+
readonly result: string | undefined;
|
|
817
|
+
readonly error: string | undefined;
|
|
818
|
+
readonly sessionFile: string | undefined;
|
|
819
|
+
}
|
|
357
820
|
|
|
358
821
|
/**
|
|
359
822
|
* Workflow Extension — Engine 共享类型
|
|
@@ -872,4 +1335,4 @@ type InteractResult = {
|
|
|
872
1335
|
message: string;
|
|
873
1336
|
};
|
|
874
1337
|
|
|
875
|
-
export type
|
|
1338
|
+
export { type AgentTaskSpec as A, type BgResponse as B, type ClosedReason as C, type DoneReason as D, type EngineCapabilities as E, type ForkFromResponse as F, type SubagentListItem as G, DirtyWorktreeError as H, type InteractAction as I, ForkDepthExceededError as J, type PersonaSpec as K, type ListResponse as L, type ModelInfo as M, type ReplayedTurn as N, ResurrectDeniedError as O, type ProbeReport as P, type RunStatus as R, type SessionView as S, type TracePatch as T, type WorkerLogEntry as W, type AgentEvent as a, type EngineHandleData as b, type EngineHandle as c, type AgentOutcome as d, type InteractResult as e, type AgentUsage as f, type AgentCallOpts as g, type AgentResult as h, type ExecutionTraceNode as i, type SubagentsGlobalConfig as j, type ModelRegistryLike as k, type AgentConfig as l, type ResolvedModel as m, type ExecutionRecord as n, type RecordSnapshot as o, type SubagentRecord as p, type ExecuteOptions as q, type ExecutionHandle as r, type ExecutionStatus as s, type ExecutionMode as t, type AgentEventLogEntry as u, type DisplayItem as v, type CancelResponse as w, type CloseResponse as x, type MessageResponse as y, type ExternalState as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/subagent-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Cross-host shared subagent execution layer and workflow orchestration core (dual-form npm package: TS source for workspace, dist ESM+CJS for npm)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -76,13 +76,15 @@
|
|
|
76
76
|
"files": [
|
|
77
77
|
"src/",
|
|
78
78
|
"workflows/",
|
|
79
|
-
"
|
|
79
|
+
"agents/",
|
|
80
|
+
"dist/",
|
|
81
|
+
"dist.bundle/"
|
|
80
82
|
],
|
|
81
83
|
"dependencies": {
|
|
82
84
|
"ajv": "^8.20.0",
|
|
83
85
|
"proper-lockfile": "^4.1.2",
|
|
84
86
|
"yaml": "^2.9.0",
|
|
85
|
-
"@xyz-agent/extension-protocol": "0.
|
|
87
|
+
"@xyz-agent/extension-protocol": "0.8.0"
|
|
86
88
|
},
|
|
87
89
|
"devDependencies": {
|
|
88
90
|
"@types/node": "^24.0.0",
|
|
@@ -93,6 +95,7 @@
|
|
|
93
95
|
},
|
|
94
96
|
"scripts": {
|
|
95
97
|
"build": "tsup",
|
|
98
|
+
"build:bundle": "tsup",
|
|
96
99
|
"test": "vitest run",
|
|
97
100
|
"typecheck": "tsc --noEmit"
|
|
98
101
|
}
|
|
@@ -12,11 +12,14 @@
|
|
|
12
12
|
// (旧实现不排除 error 分支,agent 失败被误诊为引擎透传未上线并烧掉 once 名额)
|
|
13
13
|
// - A11:model 缺省回退 "(default)"(请求时参数语义)
|
|
14
14
|
// - A12:promptMode=null(aggregator/fixer)必须保持 null,不被 || 误转 "full"
|
|
15
|
-
import {
|
|
15
|
+
import { execFile } from "node:child_process";
|
|
16
|
+
import { copyFileSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
16
18
|
import { join } from "node:path";
|
|
19
|
+
import { promisify } from "node:util";
|
|
17
20
|
import vm from "node:vm";
|
|
18
21
|
|
|
19
|
-
import { describe, expect, it } from "vitest";
|
|
22
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
20
23
|
|
|
21
24
|
const WORKFLOW_SOURCE = readFileSync(
|
|
22
25
|
join(__dirname, "..", "..", "workflows", "review-fix-loop.js"),
|
|
@@ -286,3 +289,88 @@ describe("review-fix-loop.js 模块形态约束", () => {
|
|
|
286
289
|
await expect(import("../../workflows/review-fix-loop.js")).rejects.toThrow();
|
|
287
290
|
});
|
|
288
291
|
});
|
|
292
|
+
|
|
293
|
+
// ── RX2-F2:fixAgent=fallow-scan 显式拒收(脚本顶层参数校验,非函数段) ──
|
|
294
|
+
// 拒收逻辑位于脚本顶层(FIX_AGENT_RAW 解析后、resolveAgentDefs 前),函数段抽取法
|
|
295
|
+
// 覆盖不到;改用 review-fix-loop-scriptpath-failfast.test.ts 同款「AsyncFunction 包装
|
|
296
|
+
// + node -e 真实子进程」探针跑整脚本顶层副本。拒收点在 RUN_ROOT 落盘 / lockReviewBase
|
|
297
|
+
// 之前,探针无文件系统副作用、恒非零退出。
|
|
298
|
+
describe("review-fix-loop.js fixAgent=fallow-scan 显式拒收(RX2-F2)", () => {
|
|
299
|
+
const run = promisify(execFile);
|
|
300
|
+
|
|
301
|
+
/** execFile reject 侧的最小形状(Node ExecException 子集)。 */
|
|
302
|
+
interface ExecFailure extends Error {
|
|
303
|
+
code?: number | string;
|
|
304
|
+
stderr?: string;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function isExecFailure(e: unknown): e is ExecFailure {
|
|
308
|
+
return e instanceof Error;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
let sandboxDir = "";
|
|
312
|
+
|
|
313
|
+
beforeEach(() => {
|
|
314
|
+
sandboxDir = mkdtempSync(join(tmpdir(), "rfl-fixagent-guard-"));
|
|
315
|
+
const workflowsDir = join(__dirname, "..", "..", "workflows");
|
|
316
|
+
// 副本以 .cjs 落 sandbox(require 解析形态对齐 worker 宿主);utils 锚定加载经
|
|
317
|
+
// workerData.scriptPath(副本同目录),白名单校验前即需要它
|
|
318
|
+
copyFileSync(join(workflowsDir, "review-fix-loop.js"), join(sandboxDir, "review-fix-loop.cjs"));
|
|
319
|
+
copyFileSync(join(workflowsDir, "review-fix-loop-utils.cjs"), join(sandboxDir, "review-fix-loop-utils.cjs"));
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
afterEach(() => {
|
|
323
|
+
rmSync(sandboxDir, { recursive: true, force: true });
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
/** -e 探针体:AsyncFunction 复刻 worker 模板宿主形态(workerData/$ARGS/log 注入)。 */
|
|
327
|
+
function probeCode(argsJson: string): string {
|
|
328
|
+
const copyPath = join(sandboxDir, "review-fix-loop.cjs");
|
|
329
|
+
return [
|
|
330
|
+
"const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;",
|
|
331
|
+
"const src = require('fs').readFileSync(" + JSON.stringify(copyPath) + ", 'utf8');",
|
|
332
|
+
"const runner = new AsyncFunction('workerData', '$ARGS', 'require', 'log', src + '\\n');",
|
|
333
|
+
"const workerData = { scriptPath: " + JSON.stringify(join(sandboxDir, "review-fix-loop.cjs")) + " };",
|
|
334
|
+
"const $ARGS = " + argsJson + ";",
|
|
335
|
+
// $MODEL 是 worker 模板全局(主模型注入)——对照用例会推进到 fixAgent 解析之后
|
|
336
|
+
// 的 MODEL = $MODEL 行(:204),缺席会 ReferenceError 而非到达批次校验
|
|
337
|
+
"const $MODEL = 'probe-model';",
|
|
338
|
+
"runner(workerData, $ARGS, require, function () {}).catch(function (e) {",
|
|
339
|
+
" require('fs').writeSync(2, String((e && e.message) || e) + '\\n');",
|
|
340
|
+
" process.exit(1);",
|
|
341
|
+
"});",
|
|
342
|
+
].join("\n");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function runProbeExpectFailure(argsJson: string): Promise<string> {
|
|
346
|
+
const outcome = await run(process.execPath, ["-e", probeCode(argsJson)], {
|
|
347
|
+
cwd: sandboxDir,
|
|
348
|
+
timeout: 30_000,
|
|
349
|
+
}).then(
|
|
350
|
+
(): ExecFailure | null => null,
|
|
351
|
+
(e: unknown): ExecFailure | null => (isExecFailure(e) ? e : null),
|
|
352
|
+
);
|
|
353
|
+
if (outcome === null) {
|
|
354
|
+
throw new Error("expected non-zero exit, but node exited 0 with args: " + argsJson);
|
|
355
|
+
}
|
|
356
|
+
return String(outcome.stderr ?? "");
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
it("fixAgent=fallow-scan → 非零退出 + 保留字错误 + fallowScan=true 恢复指引", async () => {
|
|
360
|
+
const stderr = await runProbeExpectFailure(
|
|
361
|
+
'{ targetType: "file", target: "probe", fixAgent: "fallow-scan" }',
|
|
362
|
+
);
|
|
363
|
+
expect(stderr).toContain("内部保留字");
|
|
364
|
+
expect(stderr).toContain("fallowScan=true");
|
|
365
|
+
// 旧实现静默映射 FALLOW_DEF(fix 派发退化为通用 subagent)——不会到达此处报错
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
it("对照:合法形态 fixAgent(.md 路径)不触发保留字拒收(后续批次校验照常 fail)", async () => {
|
|
369
|
+
const stderr = await runProbeExpectFailure(
|
|
370
|
+
'{ targetType: "file", target: "probe", fixAgent: "/tmp/rx2-f2-fake-agent.md" }',
|
|
371
|
+
);
|
|
372
|
+
// 推进到批次解析才失败(缺批次参数)——证明拒收只对字面值 fallow-scan 触发
|
|
373
|
+
expect(stderr).toContain("缺少批次参数");
|
|
374
|
+
expect(stderr).not.toContain("内部保留字");
|
|
375
|
+
});
|
|
376
|
+
});
|
|
@@ -1140,6 +1140,27 @@ describe("findIssueKey — 归一化键空间查找", () => {
|
|
|
1140
1140
|
expect(findIssueKey(issues, "MF-1")).toBe("MF-1 (fixed)");
|
|
1141
1141
|
expect(findIssueKey(issues, "mf-1 (by design)")).toBe("MF-1 (fixed)");
|
|
1142
1142
|
});
|
|
1143
|
+
|
|
1144
|
+
it("原型链键(__proto__/toString/constructor)→ 不命中(Object.hasOwn 首查,zsw 侧同款修复上收)", () => {
|
|
1145
|
+
// 旧 truthy 查表(issues[issueId])会让 Object.prototype 上的成员误命中:
|
|
1146
|
+
// issues["__proto__"] 取到原型对象(truthy)→ 返回 "__proto__" 当台账键 →
|
|
1147
|
+
// 调用方读 issues["__proto__"].severity 得 undefined/函数污染 fix 对账。
|
|
1148
|
+
// ID 来自 LLM 产出,原型链键是真实攻击面而非理论边界。
|
|
1149
|
+
const issues = { "MF-1": { severity: "major" } };
|
|
1150
|
+
expect(findIssueKey(issues, "__proto__")).toBeUndefined();
|
|
1151
|
+
expect(findIssueKey(issues, "toString")).toBeUndefined();
|
|
1152
|
+
expect(findIssueKey(issues, "constructor")).toBeUndefined();
|
|
1153
|
+
expect(findIssueKey(issues, "hasOwnProperty")).toBeUndefined();
|
|
1154
|
+
});
|
|
1155
|
+
|
|
1156
|
+
it("own 键且值 falsy(null)→ 仍命中该键(hasOwn 与 truthy 查表的等价性由归一化回退段兜底)", () => {
|
|
1157
|
+
// 旧 truthy 查表在值 falsy 时不直接命中,但归一化回退段(Object.keys 只枚举
|
|
1158
|
+
// own 键)会命中同一键——两形态最终返回一致,hasOwn 只是路径更短、且对原型链
|
|
1159
|
+
// 键正确拒绝。断言钉住该等价性,防未来有人「顺手」改回 truthy 形态。
|
|
1160
|
+
const issues = { "MF-1": null };
|
|
1161
|
+
expect(findIssueKey(issues, "MF-1")).toBe("MF-1");
|
|
1162
|
+
expect(findIssueKey(issues, "mf-1")).toBe("MF-1");
|
|
1163
|
+
});
|
|
1143
1164
|
});
|
|
1144
1165
|
|
|
1145
1166
|
describe("T-2 端到端:normIssueId/findIssueKey 在 validateFixResult 的真实消费", () => {
|