@zhushanwen/pi-subagent-workflow 7.3.4 → 8.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.
- package/README.md +39 -12
- package/agents/analyst.md +61 -0
- package/agents/coder.md +70 -0
- package/agents/debugger.md +67 -0
- package/agents/doc-reviewer.md +3 -3
- package/agents/explorer.md +50 -18
- package/agents/general-purpose.md +19 -8
- package/agents/orchestrator.md +37 -32
- package/agents/planner.md +45 -11
- package/agents/researcher.md +53 -11
- package/agents/reviewer.md +74 -0
- package/package.json +1 -1
- package/skills/workflow-script-format/SKILL.md +1 -1
- package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +1 -0
- package/src/execution/__tests__/agent-registry.test.ts +13 -11
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +10 -4
- package/src/execution/__tests__/before-agent-start-injection.test.ts +132 -0
- package/src/execution/__tests__/bg-notify-render.test.ts +15 -15
- package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +365 -0
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +190 -0
- package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +215 -0
- package/src/execution/__tests__/conversation-wiring.test.ts +198 -0
- package/src/execution/__tests__/crash-recovery.test.ts +8 -2
- package/src/execution/__tests__/delivery-methods.test.ts +385 -0
- package/src/execution/__tests__/epipe-fallback.test.ts +241 -0
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +49 -2
- package/src/execution/__tests__/execute-nesting.test.ts +20 -72
- package/src/execution/__tests__/execution-record.test.ts +199 -0
- package/src/execution/__tests__/finalize-record.test.ts +170 -14
- package/src/execution/__tests__/format.test.ts +131 -7
- package/src/execution/__tests__/gc-timer.test.ts +184 -0
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +254 -0
- package/src/execution/__tests__/helpers/spawn-mock.ts +25 -7
- package/src/execution/__tests__/index-session-start-identity.test.ts +371 -0
- package/src/execution/__tests__/index-session-start.test.ts +257 -5
- package/src/execution/__tests__/lifecycle-manager-lock.test.ts +211 -0
- package/src/execution/__tests__/lifecycle-manager.test.ts +337 -0
- package/src/execution/__tests__/lifecycle-predicates.test.ts +116 -0
- package/src/execution/__tests__/list-component.test.ts +59 -5
- package/src/execution/__tests__/list-fields.test.ts +109 -0
- package/src/execution/__tests__/model-resolver.test.ts +38 -1
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +287 -0
- package/src/execution/__tests__/nested-visibility.test.ts +325 -0
- package/src/execution/__tests__/notifier-flush.test.ts +209 -7
- package/src/execution/__tests__/one-shot-upgrade.test.ts +205 -0
- package/src/execution/__tests__/parent-child-matrix.test.ts +336 -0
- package/src/execution/__tests__/record-store.test.ts +158 -52
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +11 -12
- package/src/execution/__tests__/recursive-visibility-env.test.ts +18 -20
- package/src/execution/__tests__/resource-policy.test.ts +109 -0
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +267 -0
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +253 -0
- package/src/execution/__tests__/run-spawn-edges.test.ts +18 -25
- package/src/execution/__tests__/run-spawn-integration.test.ts +29 -25
- package/src/execution/__tests__/run-spawn-resume.test.ts +322 -0
- package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +14 -11
- package/src/execution/__tests__/session-pending.test.ts +61 -2
- package/src/execution/__tests__/session-reconstructor.test.ts +4 -4
- package/src/execution/__tests__/session-runner-epipe.test.ts +178 -0
- package/src/execution/__tests__/session-runner-schema-env.test.ts +15 -21
- package/src/execution/__tests__/session-start-reaper.test.ts +10 -8
- package/src/execution/__tests__/spawn-args.test.ts +127 -49
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +1 -0
- package/src/execution/__tests__/spawned-children.test.ts +92 -0
- package/src/execution/__tests__/status-refactor.test.ts +345 -0
- package/src/execution/__tests__/stdin-writer.test.ts +97 -0
- package/src/execution/__tests__/subagent-service-message-close.test.ts +598 -0
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +180 -0
- package/src/execution/__tests__/subagent-service.test.ts +49 -11
- package/src/execution/__tests__/timeout-integration.test.ts +27 -13
- package/src/execution/__tests__/tool-action.test.ts +12 -10
- package/src/execution/__tests__/truncline-snapshot.test.ts +81 -0
- package/src/execution/__tests__/turn-limiter-semantics.test.ts +194 -0
- package/src/execution/__tests__/worktree-manager.test.ts +292 -89
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +13 -12
- package/src/execution/argv-mirror.ts +21 -2
- package/src/execution/execution-record.ts +126 -9
- package/src/execution/finalize-record.ts +90 -13
- package/src/execution/host-mode.ts +1 -1
- package/src/execution/lifecycle-manager.ts +484 -0
- package/src/execution/lifecycle-predicates.ts +65 -0
- package/src/execution/manifest-store.ts +61 -16
- package/src/execution/model-resolver.ts +26 -5
- package/src/execution/notifier.ts +69 -12
- package/src/execution/pi-invocation.ts +21 -1
- package/src/execution/record-store.ts +554 -107
- package/src/execution/session-pending.ts +116 -45
- package/src/execution/session-reconstructor.ts +224 -7
- package/src/execution/session-runner.ts +290 -75
- package/src/execution/sessions-index.ts +304 -0
- package/src/execution/stdin-writer.ts +93 -7
- package/src/execution/stream-sink.ts +20 -3
- package/src/execution/subagent-service.ts +867 -138
- package/src/execution/turn-limiter.ts +14 -0
- package/src/execution/types.ts +204 -22
- package/src/execution/worktree-manager.ts +128 -49
- package/src/execution/worktree-registry.ts +13 -2
- package/src/index.ts +277 -19
- package/src/injectors/subagent-list-injector.ts +26 -8
- package/src/injectors/workflow-list-injector.ts +25 -8
- package/src/interface/__tests__/subagent-tool-prompt.test.ts +18 -5
- package/src/interface/__tests__/tool-render.test.ts +15 -13
- package/src/interface/bg-notify-render.ts +32 -8
- package/src/interface/command-actions.ts +26 -7
- package/src/interface/commands.ts +21 -22
- package/src/interface/format.ts +44 -17
- package/src/interface/gui-mappers.ts +6 -8
- package/src/interface/helpers.ts +170 -10
- package/src/interface/list-component.ts +53 -14
- package/src/interface/subagent-actions.ts +235 -17
- package/src/interface/subagent-tool.ts +82 -17
- package/src/interface/subagents.ts +2 -1
- package/src/interface/tool-render.ts +11 -24
- package/src/interface/tool-workflow.ts +20 -35
- package/src/interface/views/WorkflowsView.ts +89 -32
- package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +264 -0
- package/src/interface/views/__tests__/detail-content-session-file.test.ts +1 -1
- package/src/interface/views/format.ts +3 -3
- package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +325 -0
- package/src/orchestration/__tests__/args-validator.test.ts +1 -1
- package/src/orchestration/__tests__/config-loader.test.ts +38 -0
- package/src/orchestration/__tests__/error-recovery-handlers.test.ts +394 -4
- package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +4 -4
- package/src/orchestration/__tests__/execute-agent-call.test.ts +95 -0
- package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +657 -18
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -2
- package/src/orchestration/__tests__/lifecycle.test.ts +332 -149
- package/src/orchestration/__tests__/skill-discovery.test.ts +157 -0
- package/src/orchestration/__tests__/test-mocks.ts +191 -0
- package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +98 -0
- package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -2
- package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +110 -0
- package/src/orchestration/__tests__/workflows-e2e.test.ts +1 -1
- package/src/orchestration/agent-opts-resolver.ts +4 -1
- package/src/orchestration/args-validator.ts +2 -2
- package/src/orchestration/config-loader.ts +30 -1
- package/src/orchestration/error-recovery.ts +133 -29
- package/src/orchestration/execute-agent-call.ts +31 -7
- package/src/orchestration/jsonl-run-store.ts +287 -40
- package/src/orchestration/launcher.ts +7 -1
- package/src/orchestration/lifecycle.ts +135 -132
- package/src/orchestration/models/__tests__/trace.test.ts +408 -0
- package/src/orchestration/models/budget.ts +1 -1
- package/src/orchestration/models/run-runtime.ts +15 -17
- package/src/orchestration/models/run-spec.ts +2 -2
- package/src/orchestration/models/run-state.ts +3 -3
- package/src/orchestration/models/trace.ts +95 -15
- package/src/orchestration/models/types.ts +8 -9
- package/src/orchestration/models/workflow-run.ts +50 -71
- package/src/orchestration/models/workflow-script.ts +32 -1
- package/src/orchestration/skill-discovery.ts +30 -0
- package/src/orchestration/worker-handle.ts +1 -1
- package/src/orchestration/worker-host.ts +1 -1
- package/src/orchestration/worker-script-builder.ts +29 -10
- package/src/shared/__tests__/agent-ref.test.ts +34 -0
- package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +280 -0
- package/src/shared/__tests__/resource-discovery.test.ts +55 -0
- package/src/shared/__tests__/schema-jsonify.test.ts +81 -0
- package/src/shared/agent-ref.ts +16 -0
- package/src/shared/resource-discovery.ts +147 -58
- package/src/shared/schema-jsonify.ts +53 -0
- package/workflows/README.md +4 -4
- package/agents/code-reviewer.md +0 -47
- package/agents/context-builder.md +0 -21
- package/agents/oracle.md +0 -34
- package/agents/worker.md +0 -20
|
@@ -51,6 +51,14 @@ export interface TurnLimiterOptions {
|
|
|
51
51
|
export interface TurnLimiter {
|
|
52
52
|
/** 每次 turn_end 调用。 */
|
|
53
53
|
onTurnEnd(currentTurns: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* 重置 steered/aborted 标志(新一轮开始)。
|
|
56
|
+
*
|
|
57
|
+
* chatMode 下 agent_settled 时调用——每轮(message → agent_settled)独立计数,
|
|
58
|
+
* maxTurns 不跨轮累计(续聊本质是无限轮,累计上限违背 G1)。
|
|
59
|
+
* 非 chatMode 不调用,行为不变(全程累计)。
|
|
60
|
+
*/
|
|
61
|
+
reset(): void;
|
|
54
62
|
/** 是否已发过 steer(诊断用)。 */
|
|
55
63
|
readonly didSteer: boolean;
|
|
56
64
|
/** 是否已 abort(诊断用)。 */
|
|
@@ -76,8 +84,14 @@ export function createTurnLimiter(opts: TurnLimiterOptions): TurnLimiter {
|
|
|
76
84
|
}
|
|
77
85
|
};
|
|
78
86
|
|
|
87
|
+
const reset = (): void => {
|
|
88
|
+
steered = false;
|
|
89
|
+
aborted = false;
|
|
90
|
+
};
|
|
91
|
+
|
|
79
92
|
return {
|
|
80
93
|
onTurnEnd,
|
|
94
|
+
reset,
|
|
81
95
|
get didSteer(): boolean {
|
|
82
96
|
return steered;
|
|
83
97
|
},
|
package/src/execution/types.ts
CHANGED
|
@@ -16,15 +16,16 @@ import type { ModelInfo, ModelRegistryLike } from "./model-resolver.ts";
|
|
|
16
16
|
// ============================================================
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* 未显式指定 agent
|
|
19
|
+
* 未显式指定 agent 时的兜底名。
|
|
20
20
|
*
|
|
21
21
|
* 必须是真实存在、可被 agentRegistry 发现的 agent(用户 agentDir 内置的通用 agent)。
|
|
22
22
|
* Service 层(resolveIdentity)与 TUI 层(extractAgentName)共用此常量,保证
|
|
23
23
|
* 「调用时显示的名」与「实际加载的 agent.md」一致。
|
|
24
24
|
*
|
|
25
25
|
* [HISTORICAL] 旧实现两处各硬编码:service 用 "default"(虚构名),format 用
|
|
26
|
-
* "worker"
|
|
27
|
-
*
|
|
26
|
+
* "worker"(真实但不是兜底语义,worker agent 已在 2026-08 agent 重构中删除)。
|
|
27
|
+
* 导致不传 agent 时,block 标题显示 worker,但实际执行兜底逻辑不一致。统一为
|
|
28
|
+
* general-purpose 后名实相符。
|
|
28
29
|
*/
|
|
29
30
|
export const DEFAULT_AGENT_NAME = "general-purpose";
|
|
30
31
|
|
|
@@ -32,8 +33,48 @@ export const DEFAULT_AGENT_NAME = "general-purpose";
|
|
|
32
33
|
// 执行状态机
|
|
33
34
|
// ============================================================
|
|
34
35
|
|
|
35
|
-
/**
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* 唯一执行状态。所有路径共用。v4 B-1 两态收敛:旧 idle 折入 running、
|
|
38
|
+
* 旧 cancelled 折入 closed(closedReason='cancelled' 区分)。
|
|
39
|
+
*
|
|
40
|
+
* running = 活跃态。含两种子态(由派生谓词区分,见 lifecycle-predicates.ts):
|
|
41
|
+
* - 对话模式等待续聊(旧 idle):进程可能保活(isIdle=hasIdleTimer)或已回收
|
|
42
|
+
* 待冷路径 resume(isResumable=running && 无活进程句柄)。
|
|
43
|
+
* - 正在执行(有活进程句柄)。
|
|
44
|
+
*
|
|
45
|
+
* closed = 统一终态(done/failed/crashed/cancelled 合并)。具体关闭原因由
|
|
46
|
+
* {@link ClosedReason} 子枚举表达(如 user-close / gc / cancelled / parent-shutdown)。
|
|
47
|
+
* ExecutionRecord.closedReason 携带 L2 原因,投影层按需派生对外语义(error / ended)。
|
|
48
|
+
*/
|
|
49
|
+
export type ExecutionStatus = "running" | "closed";
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* closed 终态的 L2 关闭原因子枚举。
|
|
53
|
+
*
|
|
54
|
+
* 与 ExecutionStatus="closed" 配合使用,表达「为什么关闭」:
|
|
55
|
+
* parent-shutdown — 父进程 session_shutdown 时回收子进程
|
|
56
|
+
* parent-fork — 父进程 fork 新 session 时清理旧子进程
|
|
57
|
+
* parent-new — 父进程创建新 subagent 时清理旧子进程
|
|
58
|
+
* user-close — 用户手动 close action(含对话模式 close)
|
|
59
|
+
* cancelled — 用户取消(close(force:true) / cancelBackground)
|
|
60
|
+
* gc — 通用完成/失败(一次执行自然结束、超时、错误等无专属 reason 的终态)
|
|
61
|
+
*/
|
|
62
|
+
export type ClosedReason = 'parent-shutdown' | 'parent-fork' | 'parent-new' | 'user-close' | 'cancelled' | 'gc';
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 对外四态(设计决策 10 细则 3):内部 ExecutionStatus(v4 B-1 两态)收敛为 agent
|
|
66
|
+
* 可理解的状态语义。真实映射只有两条:
|
|
67
|
+
* running → active / closed → ended(closed 统一终态,含 cancelled)。
|
|
68
|
+
* mapExternalState 不消费 ClosedReason——closed 恒映射 ended。
|
|
69
|
+
*
|
|
70
|
+
* waiting / error 是历史多态映射(idle→waiting / failed+crashed→error)的遗留声明:
|
|
71
|
+
* 对外四态联合契约不变,但当前状态机不产生这两个值。
|
|
72
|
+
*
|
|
73
|
+
* 原始 ExecutionStatus 进 list item 的 status 字段供调试;state 是对外主字段。
|
|
74
|
+
* 映射实现见 subagent-actions.ts mapExternalState——未来内部加态必须扩展该处,
|
|
75
|
+
* 漏加会在 default 分支编译报错,不影响对外契约。
|
|
76
|
+
*/
|
|
77
|
+
export type ExternalState = "active" | "waiting" | "ended" | "error";
|
|
37
78
|
|
|
38
79
|
/** 执行模式。background = 调用方立即拿 handle 返回,子 agent 在 detached promise 里跑。 */
|
|
39
80
|
export type ExecutionMode = "background";
|
|
@@ -129,6 +170,8 @@ export type SdkEvent = {
|
|
|
129
170
|
usage?: AgentUsage & { cost?: { total: number } };
|
|
130
171
|
stopReason?: string;
|
|
131
172
|
errorMessage?: string;
|
|
173
|
+
/** 消息角色(message_start 事件携带,user/assistant/toolResult/custom)。 */
|
|
174
|
+
role?: string;
|
|
132
175
|
};
|
|
133
176
|
assistantMessageEvent?: { type?: string; delta?: string };
|
|
134
177
|
reason?: string;
|
|
@@ -217,18 +260,9 @@ export interface AgentResult {
|
|
|
217
260
|
// ExecutionRecord —— 唯一状态对象(Core 拥有,Runtime 引用)
|
|
218
261
|
// ============================================================
|
|
219
262
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
* 收口设计:一次执行的完整内容(text/thinking/toolCalls/usage)按 turn 收口在
|
|
224
|
-
* `turns: Turn[]` 里。eventLog / currentActivity / result 文本均从 turns[] 派生
|
|
225
|
-
* (getEventLog / getCurrentActivity / getFullText),不再独立存储切片或缓冲。
|
|
226
|
-
*
|
|
227
|
-
* 生命周期:createRecord() 创建 → updateFromEvent() 实时更新(累积进 turns)→
|
|
228
|
-
* completeRecord() 冻结 → archive 立即移出内存(读时从 session.jsonl 重建)。
|
|
229
|
-
*
|
|
230
|
-
* TUI 永远拿 RecordSnapshot(.slice() 快照),不直接持此可变对象。
|
|
231
|
-
*/
|
|
263
|
+
// 本 section 先声明 ExecutionRecord 的组成值对象(WorktreeHandle / AliveMarker /
|
|
264
|
+
// PatchResult 等),ExecutionRecord 本体及其文档注释在 section 末尾。
|
|
265
|
+
|
|
232
266
|
/**
|
|
233
267
|
* worktree handle 值对象。仅 worktree:true 时持有——worktree 是独立维度,
|
|
234
268
|
* 需显式开启,fork alone 不创建 worktree。
|
|
@@ -296,6 +330,18 @@ export class DirtyWorktreeError extends Error {
|
|
|
296
330
|
}
|
|
297
331
|
}
|
|
298
332
|
|
|
333
|
+
/**
|
|
334
|
+
* 所有执行路径的唯一状态源。
|
|
335
|
+
*
|
|
336
|
+
* 收口设计:一次执行的完整内容(text/thinking/toolCalls/usage)按 turn 收口在
|
|
337
|
+
* `turns: Turn[]` 里。eventLog / currentActivity / result 文本均从 turns[] 派生
|
|
338
|
+
* (getEventLog / getCurrentActivity / getFullText),不再独立存储切片或缓冲。
|
|
339
|
+
*
|
|
340
|
+
* 生命周期:createRecord() 创建 → updateFromEvent() 实时更新(累积进 turns)→
|
|
341
|
+
* completeRecord() 冻结 → archive 立即移出内存(读时从 session.jsonl 重建)。
|
|
342
|
+
*
|
|
343
|
+
* TUI 永远拿 RecordSnapshot(.slice() 快照),不直接持此可变对象。
|
|
344
|
+
*/
|
|
299
345
|
export interface ExecutionRecord {
|
|
300
346
|
/** 唯一 ID(sync: "run-N",bg: "bg-N-xxx")。 */
|
|
301
347
|
readonly id: string;
|
|
@@ -318,9 +364,26 @@ export interface ExecutionRecord {
|
|
|
318
364
|
readonly parentRecordId: string | undefined;
|
|
319
365
|
/** subagent 递归深度。顶层(主 session 直接创建)=0,每层嵌套 +1。 */
|
|
320
366
|
readonly depth: number;
|
|
367
|
+
/**
|
|
368
|
+
* 对话模式标志(可持续对话 subagent)。true = 轮次完成进 idle 态(保留 record +
|
|
369
|
+
* worktree)等待续聊,而非一次性终态化。
|
|
370
|
+
* undefined/false = 一次性模式(默认,行为完全不变)。
|
|
371
|
+
* 向后兼容:旧 record / 旧 session 文件无此字段,按一次性模式处理。
|
|
372
|
+
*/
|
|
373
|
+
readonly chatMode?: boolean;
|
|
374
|
+
/**
|
|
375
|
+
* 空闲超时毫秒数(仅 chatMode 有意义)。覆盖默认 5min idle timeout。
|
|
376
|
+
* 优先级:参数 > env XYZ_SUBAGENT_IDLE_TIMEOUT_MS > 默认 300000ms。
|
|
377
|
+
* 向后兼容:旧 record 无此字段,按默认值处理。
|
|
378
|
+
*/
|
|
379
|
+
readonly idleTimeoutMs?: number;
|
|
321
380
|
|
|
322
381
|
// ── 状态(实时更新)──
|
|
323
382
|
status: ExecutionStatus;
|
|
383
|
+
/** L2 关闭原因子枚举(仅 status="closed" 时有意义)。表达「为什么关闭」。
|
|
384
|
+
* 由 tryTransition(record, "closed", reason) 写入;投影层按需派生对外语义。
|
|
385
|
+
* 向后兼容:旧 record 无此字段,按 gc 处理(通用完成/失败)。 */
|
|
386
|
+
closedReason?: ClosedReason;
|
|
324
387
|
/** 完整执行内容,按 turn 组织。createRecord 初始化为 [空 turn]。 */
|
|
325
388
|
turns: Turn[];
|
|
326
389
|
/** turn 计数(= turns.filter(closed).length,冗余存储供投影直接读)。 */
|
|
@@ -328,6 +391,49 @@ export interface ExecutionRecord {
|
|
|
328
391
|
totalTokens: number;
|
|
329
392
|
/** 运行期最近一次 error 事件的消息(getEventLog 派生 error 条目用)。 */
|
|
330
393
|
lastError: string | undefined;
|
|
394
|
+
/**
|
|
395
|
+
* 对话轮次计数(仅 chatMode 有意义)。首轮运行时 = 0;每完成一轮(finalizeRoundToIdle
|
|
396
|
+
* 进 idle)+1。undefined 时视为 0。非 chatMode 不自增。
|
|
397
|
+
*/
|
|
398
|
+
round?: number;
|
|
399
|
+
/**
|
|
400
|
+
* [增量通知] 当前轮次增量的 turns[] 起始下标(仅 chatMode 有意义;内存态记账,D4 不持久化)。
|
|
401
|
+
*
|
|
402
|
+
* - 生命周期:undefined 视为 0(首轮增量 = 全量,与改造前首轮通知逐字节一致,向后兼容旧
|
|
403
|
+
* record);唯一写点 onRoundSettled 第 5 步(notify 之后推进),唯一读点同回调第 2 步
|
|
404
|
+
* (`getFullTextFrom(record, record.roundBaseTurnIndex ?? 0)`)。非 chatMode 恒
|
|
405
|
+
* undefined(onRoundSettled 是 session-runner chatMode 分支专属回调)。
|
|
406
|
+
* - D1 滞后空 turn 防丢文本(防御性):pi 当前事件序下该形态不可达——带 usage 的
|
|
407
|
+
* message_end 恒先于 turn_end(@earendil-works/pi-agent-core dist/agent-loop.js
|
|
408
|
+
* :240/:253/:547 三处 message_end emit 均在 :131 正常路径 turn_end 之前),settle 时
|
|
409
|
+
* turn 全闭合。防 pi 未来事件序变化:若 settle 时刻末 turn 是滞后 message_end 开出的
|
|
410
|
+
* 空 turn(execution-record.ts message_end 分支经 currentTurn,需同时过两层 usage 守卫:
|
|
411
|
+
* session-runner.ts 转发层 `if (msg?.usage)`(bare message_end 不转发)+ execution-record.ts
|
|
412
|
+
* 累积层 `if (event.usage)`(bare message_end 不开 turn)),推进公式
|
|
413
|
+
* nextRoundBaseTurnIndex 把它留在下一轮增量内(新轮首个 text_delta 经 currentTurn 复用该
|
|
414
|
+
* 空 turn,复用累积被 slice 覆盖);直用 turns.length 推进会把下轮首段文本挤出 slice
|
|
415
|
+
* 范围静默丢失。
|
|
416
|
+
* - D4 不持久化:磁盘重建走 createRecord(turns 仅为初始 [emptyTurn()]),base=0 对空 turn
|
|
417
|
+
* 的增量派生等价为空、天然产出仅新轮增量,持久化是死数据。故不写 manifest、不参与重建。
|
|
418
|
+
* - pi 内部序锚定依据(R1 mitigation):@earendil-works/pi-agent-core 0.84.0
|
|
419
|
+
* dist/agent-loop.js :106-113(error/aborted stopReason 也先 emit turn_end 再 agent_end)
|
|
420
|
+
* 与 :131(正常路径 turn_end 收尾);agent_settled 在 agent_end 之后 emit,故未闭合
|
|
421
|
+
* turn 只可能来自滞后事件。pi 升级若改变 turn_end/agent_end 时序,onRoundSettled 推进前
|
|
422
|
+
* 的观测哨(末 turn 未闭合且 text 非空 → logger.warn)会留痕。
|
|
423
|
+
*/
|
|
424
|
+
roundBaseTurnIndex?: number;
|
|
425
|
+
/**
|
|
426
|
+
* record 进入 idle 态的时间戳(ms)。finalizeRoundToIdle 设值;GC 定时器据此计算
|
|
427
|
+
* 剩余 TTL。undefined = 非 idle 态(running/closed/cancelled)或旧 record 缺失字段。
|
|
428
|
+
*/
|
|
429
|
+
idleSince?: number;
|
|
430
|
+
/**
|
|
431
|
+
* close 优雅关闭标志(M2-B3)。chatMode record 运行中调 `close {force:false}` 时置 true;
|
|
432
|
+
* runAndFinalize 的 done 分流检查此标志——true 则终态化为 done(而非进 idle),并清标志。
|
|
433
|
+
* undefined/false = 正常 idle 分流(对话模式轮次完成进 idle 等续聊)。
|
|
434
|
+
* 仅 chatMode + running 时有意义;force:true(立即终止)不走此标志。
|
|
435
|
+
*/
|
|
436
|
+
closeAfterRound?: boolean;
|
|
331
437
|
|
|
332
438
|
// ── 完成 ──
|
|
333
439
|
endedAt: number | undefined;
|
|
@@ -339,12 +445,30 @@ export interface ExecutionRecord {
|
|
|
339
445
|
/** session jsonl 文件名。session 创建成功后由 session-runner.run() 回填(窗口期内 undefined)。 */
|
|
340
446
|
sessionFile?: string;
|
|
341
447
|
|
|
448
|
+
/**
|
|
449
|
+
* [V2 决策 3] 子进程 pid(spawn 后由 session-runner 回填到内存 record)。
|
|
450
|
+
*
|
|
451
|
+
* 用于 lifecycle-manager 孤儿扫描(V2 §5.2 职责 4:父进程重启时按持久化 pid 扫收
|
|
452
|
+
* 上次崩溃遗留的孤儿)。本字段仅在内存记账,持久化留 Step 5(record
|
|
453
|
+
* 文件写入 pid + 启动时 scanOrphanProcesses 消费)。undefined = 尚未 spawn / 已退出。
|
|
454
|
+
* 向后兼容:旧 record 无此字段,按无 pid 处理(孤儿扫描跳过)。
|
|
455
|
+
*/
|
|
456
|
+
pid?: number;
|
|
457
|
+
|
|
342
458
|
/** [MF#3] worktree 模式下子 agent 改动的 patch 文件路径(worktree 外,供调用方应用)。 */
|
|
343
459
|
patchFile?: string;
|
|
344
460
|
|
|
345
461
|
/** worktree 隔离时的 handle(仅 worktree:true 时存在;fork alone 无此字段)。 */
|
|
346
462
|
worktreeHandle?: WorktreeHandle;
|
|
347
463
|
|
|
464
|
+
/**
|
|
465
|
+
* [review round2] 该 record 创建时启用了 worktree 隔离(跨重启磁盘重建时从 session
|
|
466
|
+
* entry 的 worktree 标志恢复)。handle 本体不可序列化——跨重启后 worktreeHandle 恒
|
|
467
|
+
* undefined,续聊(冷路径 resume)须拒绝(防 cwd 静默回落主 repo 破坏隔离)。仅内存
|
|
468
|
+
* record 使用,与持久化无关;execute() 新建 record 不设(有真 handle 时无意义)。
|
|
469
|
+
*/
|
|
470
|
+
hadWorktree?: boolean;
|
|
471
|
+
|
|
348
472
|
// ── 控制(仅 background 持有)──
|
|
349
473
|
controller: AbortController | undefined;
|
|
350
474
|
}
|
|
@@ -413,8 +537,6 @@ export interface ExecuteOptions {
|
|
|
413
537
|
signal?: AbortSignal;
|
|
414
538
|
/** 主 agent 当前模型(模型解析第三层兼底)。execute 调用方从 ctx.model 传入。 */
|
|
415
539
|
ctxModel?: ModelInfo;
|
|
416
|
-
/** live 状态回流(对话流 block 实时刷新)。 */
|
|
417
|
-
onUpdate?: (details: SubagentToolDetails) => void;
|
|
418
540
|
/** background 完成回调(sync 不调)。 */
|
|
419
541
|
onComplete?: (record: RecordSnapshot) => void;
|
|
420
542
|
/** 是否继承父会话上下文(fork 模式,只继承上下文)。 */
|
|
@@ -423,6 +545,17 @@ export interface ExecuteOptions {
|
|
|
423
545
|
worktree?: boolean | WorktreeHandle;
|
|
424
546
|
/** 覆盖执行 cwd(默认 mainCwd)。 */
|
|
425
547
|
cwd?: string;
|
|
548
|
+
/**
|
|
549
|
+
* 可持续对话模式(决策 8:独立 chatMode 标志,不扩展 ExecutionMode)。
|
|
550
|
+
* true = record 标记 chatMode,轮次完成进 idle 态(保留 record + worktree,等待 message 续聊);
|
|
551
|
+
* undefined/false = 一次性模式(默认,行为完全不变)。service.execute 透传到 createRecordForMode。
|
|
552
|
+
*/
|
|
553
|
+
conversation?: boolean;
|
|
554
|
+
/**
|
|
555
|
+
* 空闲超时毫秒数(仅 conversation 模式有意义)。覆盖默认 5min idle timeout。
|
|
556
|
+
* 优先级:参数 > env XYZ_SUBAGENT_IDLE_TIMEOUT_MS > 默认 300000ms。
|
|
557
|
+
*/
|
|
558
|
+
idleTimeoutMs?: number;
|
|
426
559
|
// 注:fork 深度不从外部传入(曾暴露 parentForkDepth,改用 ALS 后 execute 内部从调用链派生,
|
|
427
560
|
// 公开字段成为死字段误导调用方,已移除)。深度限制检查见 session-runner.ts 内部 RunOptions.parentForkDepth
|
|
428
561
|
// (与历史残留的 types.ts RunOptions 同名不同 interface——后者已删除)。
|
|
@@ -444,12 +577,15 @@ export type ExecutionHandle = {
|
|
|
444
577
|
// tool action 出参(外层分组,adapter 产出)
|
|
445
578
|
// ============================================================
|
|
446
579
|
|
|
447
|
-
/** list 的 item
|
|
580
|
+
/** list 的 item 结构。 */
|
|
448
581
|
export interface SubagentListItem {
|
|
449
582
|
subagentId: string;
|
|
450
583
|
agent: string;
|
|
451
584
|
/** 短标签(≤35 字符),来自 record.slug。旧 record 反序列化时为空串。 */
|
|
452
585
|
slug: string;
|
|
586
|
+
/** 对外四态(决策 10 细则 3,主字段)。由 mapExternalState(status) 派生。 */
|
|
587
|
+
state: ExternalState;
|
|
588
|
+
/** 原始内部状态(调试用,供 details 展示)。 */
|
|
453
589
|
status: ExecutionStatus;
|
|
454
590
|
mode: ExecutionMode;
|
|
455
591
|
/** 运行秒数(running 态实时计算,终态 endedAt-startedAt)。 */
|
|
@@ -458,6 +594,16 @@ export interface SubagentListItem {
|
|
|
458
594
|
totalTokens: number;
|
|
459
595
|
/** session jsonl 文件名(窗口期内可能 undefined)。 */
|
|
460
596
|
sessionFile?: string;
|
|
597
|
+
/** 直接父 subagent record ID(顶层 record 为 undefined)。[v4 A-6] 从
|
|
598
|
+
* record.parentRecordId 派生,配合 A-5 直接父守卫(message/close 仅作用于直接子)。 */
|
|
599
|
+
parent?: string;
|
|
600
|
+
/** 可冷路径 resume(running 且无活进程句柄)。[v4 A-6] B-1「可续聊」对外表达,
|
|
601
|
+
* agent 据 list 判断哪些 running subagent 实际可续聊(vs 正在忙)。 */
|
|
602
|
+
resumable?: boolean;
|
|
603
|
+
/** L2 关闭原因子枚举(仅 status="closed" 时有意义)。[v4 A-6] SP-4 级联关闭告知
|
|
604
|
+
* 替代——砍 before_agent_start 注入通道后,被级联关闭的 record 经 list
|
|
605
|
+
* (includeFinished:true)可查,closedReason 显示 'parent-fork'/'parent-new' 等。 */
|
|
606
|
+
closedReason?: ClosedReason;
|
|
461
607
|
}
|
|
462
608
|
|
|
463
609
|
/** background 启动的内层响应(挂在 SubagentToolResult.bgResponse)。 */
|
|
@@ -480,18 +626,39 @@ export interface CancelResponse {
|
|
|
480
626
|
cancelled: true;
|
|
481
627
|
}
|
|
482
628
|
|
|
629
|
+
/**
|
|
630
|
+
* message 的内层响应(挂在 SubagentToolResult.messageResponse,决策 10 瘦身)。
|
|
631
|
+
*
|
|
632
|
+
* [R1 删除记录] 旧 PendingMessage(在途消息缓存条目,消费确认制,设计决策 6 状态×
|
|
633
|
+
* interrupt 映射)已随 deliverToRunning 一并删除——SP-5 upgrade 后无生产调用方,
|
|
634
|
+
* 配套三段消费链(push / message_start shift / redeliverPending 补投)全部不可达。
|
|
635
|
+
* 详见 subagent-service.ts 的删除记录注释。
|
|
636
|
+
*/
|
|
637
|
+
export interface MessageResponse {
|
|
638
|
+
delivered: true;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/** close 的内层响应(挂在 SubagentToolResult.closeResponse,决策 10 瘦身)。 */
|
|
642
|
+
export interface CloseResponse {
|
|
643
|
+
closed: true;
|
|
644
|
+
}
|
|
645
|
+
|
|
483
646
|
/**
|
|
484
647
|
* Tool 外层出参(renderResult + LLM content JSON 同源)。
|
|
485
|
-
* adapter 唯一产出:领域对象(bg/list/cancel
|
|
648
|
+
* adapter 唯一产出:领域对象(bg/list/cancel/message/close 五选一)+ action/subagentId/sessionFile。
|
|
486
649
|
*
|
|
487
650
|
* - background 启动 → bgResponse(subagentId 有值;sessionFile 窗口期可能 undefined)
|
|
488
651
|
* - list → listResponse(最外层 subagentId/sessionFile 为 null,sessionFile 在各 item 内)
|
|
489
652
|
* - cancel → cancelResponse(subagentId 有值;sessionFile 无意义,可为 null)
|
|
653
|
+
* - message → messageResponse(subagentId 有值;sessionFile 无意义,可为 null)
|
|
654
|
+
* - close → closeResponse(subagentId 有值;sessionFile 无意义,可为 null)
|
|
490
655
|
*/
|
|
491
656
|
export type SubagentToolResult =
|
|
492
657
|
| { action: "start"; subagentId: string; sessionFile: string | null; slug: string; bgResponse: BgResponse; __gui__?: GuiRenderResult }
|
|
493
658
|
| { action: "list"; subagentId: null; sessionFile: null; listResponse: ListResponse; __gui__?: GuiRenderResult }
|
|
494
|
-
| { action: "cancel"; subagentId: string; sessionFile: null; cancelResponse: CancelResponse; __gui__?: GuiRenderResult }
|
|
659
|
+
| { action: "cancel"; subagentId: string; sessionFile: null; cancelResponse: CancelResponse; __gui__?: GuiRenderResult }
|
|
660
|
+
| { action: "message"; subagentId: string; sessionFile: null; messageResponse: MessageResponse; __gui__?: GuiRenderResult }
|
|
661
|
+
| { action: "close"; subagentId: string; sessionFile: null; closeResponse: CloseResponse; __gui__?: GuiRenderResult };
|
|
495
662
|
|
|
496
663
|
// ============================================================
|
|
497
664
|
// TUI list 视图的合并 record(4 源 merge 后的形状)
|
|
@@ -506,6 +673,8 @@ export interface SubagentRecord {
|
|
|
506
673
|
/** 短标签(≤35 字符)。磁盘重建源旧文件可能缺失→兜底空串。 */
|
|
507
674
|
slug: string;
|
|
508
675
|
status: ExecutionStatus;
|
|
676
|
+
/** L2 关闭原因子枚举(仅 status="closed" 时有意义)。SP-1 新增。 */
|
|
677
|
+
closedReason?: ClosedReason;
|
|
509
678
|
mode: ExecutionMode;
|
|
510
679
|
startedAt: number;
|
|
511
680
|
/** 根 Pi session ID(session 隔离过滤用)。递归链上所有层 record 同值。 */
|
|
@@ -529,6 +698,17 @@ export interface SubagentRecord {
|
|
|
529
698
|
sessionFile?: string;
|
|
530
699
|
/** [MF#3] worktree 模式下子 agent 改动的 patch 文件路径(worktree 外,供调用方应用)。 */
|
|
531
700
|
patchFile?: string;
|
|
701
|
+
/**
|
|
702
|
+
* [review round2] 创建时启用 worktree 隔离(磁盘重建源从 session entry 恢复;内存源由
|
|
703
|
+
* recordToSubagent 从 worktreeHandle 投影)。getRecordForAction 跨重启重建时据此拒绝续聊。
|
|
704
|
+
*/
|
|
705
|
+
worktree?: boolean;
|
|
706
|
+
/**
|
|
707
|
+
* 对话轮次计数(仅 chatMode idle record 有意义)。round 仅在内存维护(doFinalizeRoundToIdle
|
|
708
|
+
* 递增),跨重启不恢复(round 无磁盘持久化);非对话模式 / 非 idle record 为 undefined。内存源由 recordToSubagent 从
|
|
709
|
+
* ExecutionRecord.round 投影。
|
|
710
|
+
*/
|
|
711
|
+
round?: number;
|
|
532
712
|
/** 外部 Pi 实例(进程隔离模式下由外部启动的子进程)。 */
|
|
533
713
|
externalInstance?: AliveMarker;
|
|
534
714
|
/** fork 模式下的 worktree handle。 */
|
|
@@ -573,6 +753,8 @@ export interface RecordSnapshot {
|
|
|
573
753
|
/** 短标签(≤35 字符)。来自 record.slug。 */
|
|
574
754
|
readonly slug: string;
|
|
575
755
|
readonly status: ExecutionStatus;
|
|
756
|
+
/** 对话模式标志(与 ExecutionRecord.chatMode 同源)。cancel 别名判定用。 */
|
|
757
|
+
readonly chatMode?: boolean;
|
|
576
758
|
readonly turns: number;
|
|
577
759
|
readonly totalTokens: number;
|
|
578
760
|
readonly startedAt: number;
|