@zhushanwen/subagent-core 0.8.0 → 0.9.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/dist/{chunk-OL5BK4VN.js → chunk-LZJOEDGQ.js} +455 -203
- package/dist/engine-discovery-scan-Da4Dkzsi.d.cts +818 -0
- package/dist/engine-discovery-scan-Da4Dkzsi.d.ts +818 -0
- package/dist/execution/engine/engine-discovery-scan.cjs +216 -155
- package/dist/execution/engine/engine-discovery-scan.d.cts +1 -2
- package/dist/execution/engine/engine-discovery-scan.d.ts +1 -2
- package/dist/execution/engine/engine-discovery-scan.js +1 -1
- package/dist/execution/relay-env.js +5 -4
- package/dist/index.cjs +7686 -5894
- package/dist/index.d.cts +1876 -1360
- package/dist/index.d.ts +1876 -1360
- package/dist/index.js +7048 -5493
- package/dist.bundle/index.cjs +7747 -5957
- package/package.json +4 -4
- package/src/__tests__/manifest-store.test.ts +16 -15
- package/src/__tests__/robustness-medium-batch1.test.ts +10 -14
- package/src/__tests__/robustness-medium-batch2.test.ts +7 -2
- package/src/execution/__tests__/alive-store.test.ts +117 -1
- package/src/execution/__tests__/batch-finalized.test.ts +206 -0
- package/src/execution/__tests__/chat-engine-routing.test.ts +117 -1
- package/src/execution/__tests__/{cold-resurrect.test.ts → cold-lookup.test.ts} +133 -33
- package/src/execution/__tests__/collect-coordinator-service.test.ts +7 -5
- package/src/execution/__tests__/conversation-continuation.test.ts +1452 -0
- package/src/execution/__tests__/delivery-methods.test.ts +90 -176
- package/src/execution/__tests__/dialog-queue.test.ts +70 -3
- package/src/execution/__tests__/dispose-manifest-recovery.test.ts +475 -0
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +3 -3
- package/src/execution/__tests__/execute-nesting.test.ts +8 -5
- package/src/execution/__tests__/execution-record.test.ts +8 -148
- package/src/execution/__tests__/finalize-record.test.ts +295 -129
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +21 -29
- package/src/execution/__tests__/helpers/fake-engine-port.ts +13 -68
- package/src/execution/__tests__/helpers/legacy-sidecar.ts +33 -0
- package/src/execution/__tests__/helpers/subagent-service-mocks.ts +9 -5
- package/src/execution/__tests__/idle-gc.test.ts +60 -0
- package/src/execution/__tests__/lifecycle-manager.test.ts +3 -254
- package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +43 -22
- package/src/execution/__tests__/model-config-service.test.ts +111 -0
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +10 -6
- package/src/execution/__tests__/notify-ledger.test.ts +42 -1
- package/src/execution/__tests__/rebuild-indexes.test.ts +329 -0
- package/src/execution/__tests__/record-binding.test.ts +613 -0
- package/src/execution/__tests__/record-origin.test.ts +318 -0
- package/src/execution/__tests__/record-store-intent-api.test.ts +600 -0
- package/src/execution/__tests__/record-store-orphan-revive.test.ts +71 -3
- package/src/execution/__tests__/record-store.test.ts +72 -54
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +8 -5
- package/src/execution/__tests__/round-supervisor-workflow-origin.test.ts +205 -0
- package/src/execution/__tests__/run-orchestration-write-lease.test.ts +293 -0
- package/src/execution/__tests__/run-orchestration.test.ts +199 -0
- package/src/execution/__tests__/session-file-gc.test.ts +35 -4
- package/src/execution/__tests__/session-reconstructor.test.ts +78 -0
- package/src/execution/__tests__/state-marker.test.ts +288 -0
- package/src/execution/__tests__/stream-sink-retirement.test.ts +8 -5
- package/src/execution/__tests__/subagent-actions-core.test.ts +67 -16
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +0 -1
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -11
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +17 -11
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +130 -53
- package/src/execution/__tests__/subagent-service.test.ts +17 -215
- package/src/execution/__tests__/subprocess-agent-runner-no-progress-killall.test.ts +138 -0
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +105 -660
- package/src/execution/__tests__/sync-collect-recovery.test.ts +23 -16
- package/src/execution/__tests__/terminal-write-latency.test.ts +79 -0
- package/src/execution/__tests__/workflow-agent-dispatch.test.ts +782 -0
- package/src/execution/alive-store.ts +37 -28
- package/src/execution/{cold-resurrect.ts → cold-lookup.ts} +48 -45
- package/src/execution/config.ts +1 -1
- package/src/execution/conversation-continuation.ts +541 -0
- package/src/execution/dialog-queue.ts +60 -12
- package/src/execution/engine/__tests__/common/capability-gate.test.ts +1 -1
- package/src/execution/engine/__tests__/common/journal-wiring.test.ts +16 -1
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +17 -51
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +0 -5
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +1 -1
- package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +5 -9
- package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +0 -3
- package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -3
- package/src/execution/engine/__tests__/model-prompt.test.ts +0 -3
- package/src/execution/engine/__tests__/registry.test.ts +0 -1
- package/src/execution/engine/__tests__/routing.test.ts +0 -1
- package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +0 -3
- package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +0 -3
- package/src/execution/engine/client/__tests__/engine-client-reap.test.ts +212 -0
- package/src/execution/engine/client/__tests__/mirror.test.ts +73 -1
- package/src/execution/engine/client/__tests__/protocol-closure.test.ts +2 -9
- package/src/execution/engine/client/__tests__/remote-engine.test.ts +46 -12
- package/src/execution/engine/client/engine-client.ts +81 -25
- package/src/execution/engine/client/mirror.ts +9 -0
- package/src/execution/engine/client/remote-engine.ts +52 -34
- package/src/execution/engine/client/reverse-router.ts +6 -27
- package/src/execution/engine/common/__tests__/run-signals.test.ts +79 -0
- package/src/execution/engine/common/capability-gate.ts +27 -0
- package/src/execution/engine/common/data-dir.ts +3 -2
- package/src/execution/engine/common/errors.ts +1 -1
- package/src/execution/engine/common/journal-wiring.ts +18 -9
- package/src/execution/engine/common/run-signals.ts +83 -0
- package/src/execution/engine/d8-compat.ts +1 -1
- package/src/execution/engine/host/__tests__/host-bridge.test.ts +3 -18
- package/src/execution/engine/host/host-bridge.ts +19 -41
- package/src/execution/engine/host/pi-host-binding.ts +5 -5
- package/src/execution/engine/port.ts +34 -54
- package/src/execution/engine/types.ts +11 -14
- package/src/execution/execution-record.ts +15 -47
- package/src/execution/finalize-record.ts +94 -197
- package/src/execution/idle-gc.ts +9 -3
- package/src/execution/lifecycle-manager.ts +25 -361
- package/src/execution/lifecycle-predicates.ts +22 -19
- package/src/execution/manifest-store.ts +40 -42
- package/src/execution/model-config-service.ts +1 -1
- package/src/execution/notifier.ts +39 -1
- package/src/execution/notify-host.ts +13 -4
- package/src/execution/record-entry.ts +20 -2
- package/src/execution/record-store.ts +925 -160
- package/src/execution/relay-env.ts +8 -3
- package/src/execution/round-supervisor/domain.ts +17 -5
- package/src/execution/round-supervisor/service-binding.test.ts +89 -53
- package/src/execution/round-supervisor/service-binding.ts +71 -21
- package/src/execution/round-supervisor/supervisor.ts +23 -9
- package/src/execution/service/record-access.ts +547 -0
- package/src/execution/service/record-lifecycle.ts +542 -0
- package/src/execution/service/run-orchestration.ts +1647 -0
- package/src/execution/service/service-bootstrap.ts +111 -0
- package/src/execution/service/service-constants.ts +27 -0
- package/src/execution/service/session-baselines.ts +401 -0
- package/src/execution/service/sync-collect-domain.ts +442 -0
- package/src/execution/service/workflow-dispatch.ts +567 -0
- package/src/execution/session-file-gc.ts +11 -8
- package/src/execution/session-reconstructor.ts +44 -1
- package/src/execution/sessions-index.ts +20 -3
- package/src/execution/settled-watchdog.ts +86 -43
- package/src/execution/state-marker.ts +516 -0
- package/src/execution/stream-sink.ts +1 -1
- package/src/execution/subagent-actions-core.ts +53 -31
- package/src/execution/subagent-service.ts +643 -2980
- package/src/execution/subprocess-agent-runner.ts +46 -323
- package/src/execution/types.ts +60 -43
- package/src/execution/ui-request-handler-factory.ts +5 -0
- package/src/execution/worktree-manager.ts +1 -1
- package/src/execution/worktree-registry.ts +1 -1
- package/src/index.ts +6 -5
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +2 -3
- package/src/orchestration/__tests__/agent-call-stream.test.ts +24 -49
- package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +4 -4
- package/src/orchestration/__tests__/file-run-store.test.ts +5 -7
- package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +2 -3
- package/src/orchestration/__tests__/run-snapshot.test.ts +27 -43
- package/src/orchestration/__tests__/worker-message-pump-workflow-dispatch.test.ts +274 -0
- package/src/orchestration/execute-agent-call.ts +1 -1
- package/src/orchestration/file-run-store.ts +1 -1
- package/src/orchestration/models/ports.ts +20 -13
- package/src/orchestration/models/types.ts +11 -13
- package/src/orchestration/run-snapshot.ts +18 -22
- package/src/orchestration/worker-message-pump.ts +33 -57
- package/src/shared/atomic-write.ts +10 -8
- package/dist/chunk-T2SYBW3I.js +0 -24
- package/dist/engine-discovery-scan-BXLA8y-z.d.cts +0 -1624
- package/dist/engine-discovery-scan-BXLA8y-z.d.ts +0 -1624
- package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +0 -255
- package/src/execution/__tests__/finalized-marker.test.ts +0 -104
- package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -488
- package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +0 -75
- package/src/execution/__tests__/tombstone-store.test.ts +0 -73
- package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +0 -230
- package/src/execution/finalized-marker.ts +0 -70
- package/src/execution/tombstone-store.ts +0 -72
|
@@ -1,372 +1,95 @@
|
|
|
1
1
|
// src/execution/subprocess-agent-runner.ts
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// [H2 W4] SAR 壳归位(设计 subagent-workflow-record-unification.md §5 W4):
|
|
4
|
+
// run() 掏空为纯转调 SubagentService.executeWorkflowAgent——编排权(路由/预检/
|
|
5
|
+
// journal/守护/spawned-children/池)彻底归 service 单点(W2 executeWorkflowAgent
|
|
6
|
+
// 八步迁移承接),本类不再自持任何编排。历史形态(Wave 4 委托重写 → P4 路由 →
|
|
7
|
+
// M3 no-progress 守护落点)随本次掏空退役,行为守护由 workflow-agent-dispatch
|
|
8
|
+
// 测试族(service 落点)承接。
|
|
4
9
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
10
|
+
// 保留壳的原因(设计 v3 定形):唯一装配点 session-lifecycle.ts(D-008 per-session
|
|
11
|
+
// SAR 构造)与 index.ts 的 model_select → updateCtxModel 刷新链零改动——掏空只删
|
|
12
|
+
// run() 内部编排,构造签名与公共面不变。
|
|
7
13
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// PiEngine.agentCallToExecuteOptions。mergeTimeoutSignal(原 execute-options-mapper
|
|
11
|
-
// 的运行期件,D-A9)随 mapper 删除迁入本文件(唯一消费点)。
|
|
12
|
-
//
|
|
13
|
-
// 接线层级:
|
|
14
|
-
// [跨模块 port] implements AgentRunner(orchestration/models/ports.ts)
|
|
15
|
-
// [模块内直调] mergeTimeoutSignal(本文件,D-A9)
|
|
16
|
-
// [P4 路由层] engine/routing.ts routeEngineForHost(D3-② 路由单点:三层优先级 +
|
|
17
|
-
// pi 同步短路 + probe + fallback 三守卫,D9)
|
|
18
|
-
// [公共预检] engine/common/capability-gate(D3-④:capabilities 驱动的调用前拒绝)
|
|
19
|
-
// [引擎层] EnginePort.run(pi = 本地 DI 绑定实例;非 pi = registry.getEngine 动态获取)
|
|
20
|
-
// [公共 journal] engine/common/journal-wiring(D3-③:writer + retarget + 回填单实现)
|
|
21
|
-
// [模块内直调] this.subagentService.executeAndAwait(PiEngine 内部委托目标)
|
|
22
|
-
//
|
|
23
|
-
// 设计基线:
|
|
24
|
-
// D-A8(onEvent 桥接)/ D-A9(timeoutMs 合并 signal)/
|
|
25
|
-
// D-008(model 填底,不调 resolveModel)/ BC-9(timeoutMs 行为)/ BC-10(live-record 进度)
|
|
14
|
+
// ctxModel dep 保留在构造签名(装配点兼容),但 run() 不再消费——model 解析归
|
|
15
|
+
// service resolveIdentity(W2 迁移清单⑧:ctxModel 孪生守卫放弃迁移,不双轨)。
|
|
26
16
|
|
|
27
17
|
import type { AgentRunner } from "../orchestration/models/ports.ts";
|
|
28
18
|
import type { AgentCallOpts, AgentResult } from "../orchestration/models/types.ts";
|
|
29
19
|
import type { AgentEvent } from "../shared/agent-event.ts";
|
|
30
|
-
import { assertTaskShapeSupported } from "./engine/common/capability-gate.ts";
|
|
31
|
-
import { HOST_TIMEOUT_ABORT_REASON } from "./engine/common/kill-chain.ts";
|
|
32
|
-
import { JOURNAL_INITIAL_POOL_KEY, wireEventJournal } from "./engine/common/journal-wiring.ts";
|
|
33
|
-
// [W6 R1 MF-5] pi EnginePort 解析改经 host 公共面(engine/host/pi-host-binding.ts):
|
|
34
|
-
// registry cli 形态经 descriptor 路由(W3 双模 getEngine),inproc/未注册回落 per-session
|
|
35
|
-
// DI 直构(行为与改线前 createPiEngine 逐点一致)。
|
|
36
|
-
import { resolveHostPiEnginePort } from "./engine/host/pi-host-binding.ts";
|
|
37
|
-
import type { EnginePort, RunContext } from "./engine/port.ts";
|
|
38
|
-
import { validateModelForEngine } from "./engine/model-validation.ts";
|
|
39
|
-
import { routeEngineForHost, type EngineRouteResult, type EngineRoutingInput } from "./engine/routing.ts";
|
|
40
|
-
import { getEngine } from "./engine/registry.ts";
|
|
41
|
-
import type { AgentOutcome } from "./engine/types.ts";
|
|
42
|
-
import { getModelConfigService } from "./model-config-service.ts";
|
|
43
20
|
import type { ModelInfo } from "./model-resolver.ts";
|
|
44
|
-
import { modelRefFromVerified } from "../shared/model-ref";
|
|
45
|
-
// [W6 R1 MF-5] 子进程注册改经 spawnedChildren 状态镜像公共面(engine/host/
|
|
46
|
-
// spawned-children.ts——镜像 + inproc 过渡委托,不再深路径 import inproc pi 引擎目录)。
|
|
47
|
-
import { registerSpawnedChildForRecord } from "./engine/host/spawned-children.ts";
|
|
48
21
|
import type { SubagentStream } from "./stream-sink.ts";
|
|
49
22
|
import type { SubagentService } from "./subagent-service.ts";
|
|
50
|
-
import { toErrorMessage } from "../core/error-message.ts";
|
|
51
|
-
|
|
52
|
-
// ── 构造依赖(per-session 注入)──
|
|
53
23
|
|
|
54
24
|
/**
|
|
55
|
-
* SAR
|
|
25
|
+
* SAR 直调(无 workflow run 上下文)时的 parentRunId 占位——record 仍带
|
|
26
|
+
* origin:"workflow" 进 store,但不隶属任何 run(views 按真实 runId 查询
|
|
27
|
+
* collectRecordsByParentRunId 天然不中;治理通道 `subagents action:'list'
|
|
28
|
+
* includeWorkflow:true` 仍可查)。
|
|
56
29
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* - ctxModel: 当前 session 主 agent 模型(D-008 model 填底,opts.model 空时用此)
|
|
60
|
-
*
|
|
61
|
-
* resolveAgentOpts 在 orchestration 层完成(M2 修正后单参数,只处理 schema SO 指令 + skill),
|
|
62
|
-
* 结果填进 AgentCallOpts.skillPath/schemaEnv/appendSystemPrompt,SAR 收已解析的 opts。
|
|
63
|
-
* 不含 agent/session 目录/临时文件集合依赖(agent ref 交 resolveIdentity,无临时文件)。
|
|
30
|
+
* 生产链路 pump 恒经 workflowAgentDispatch 注入(闭包携带真实 run.runId),
|
|
31
|
+
* 本占位仅在 SAR.run 被直接调用的场景出现(生产不可达;测试直调)。
|
|
64
32
|
*/
|
|
33
|
+
export const SAR_UNATTACHED_PARENT_RUN_ID = "sar-unattached";
|
|
34
|
+
|
|
35
|
+
/** SAR 构造参数(签名冻结——session-lifecycle.ts 装配点零改动)。 */
|
|
65
36
|
export interface SubprocessAgentRunnerDeps {
|
|
66
37
|
subagentService: SubagentService;
|
|
38
|
+
/** 兼容保留:run() 不消费(model 解析归 service resolveIdentity)。 */
|
|
67
39
|
ctxModel?: ModelInfo;
|
|
68
40
|
}
|
|
69
41
|
|
|
70
42
|
/**
|
|
71
|
-
* AgentRunner port
|
|
43
|
+
* AgentRunner port 实现——纯转调 SubagentService.executeWorkflowAgent。
|
|
72
44
|
*
|
|
73
|
-
* 层归属:execution
|
|
45
|
+
* 层归属:execution。implements orchestration 层 port。
|
|
74
46
|
*
|
|
75
|
-
*
|
|
47
|
+
* 契约:
|
|
76
48
|
* - opts 形状不变(AgentCallOpts,含 resolveAgentOpts 填的 skillPath/schemaEnv)
|
|
77
|
-
* - result 形状不变(
|
|
78
|
-
*
|
|
79
|
-
* -
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* 非 pi 引擎(P4 路由可达:frontmatter/调用参数/全局默认指定)经 registry.getEngine
|
|
84
|
-
* 动态获取——「引擎身份」的归属边界在注册表,SAR 不感知具体引擎实现。
|
|
85
|
-
*
|
|
86
|
-
* [P4 配置路由] 每次运行经 engine/routing.ts 的 routeEngineForHost(D3-② 路由单点:
|
|
87
|
-
* 唯一实现承载三层优先级(调用参数 opts.engine > agent frontmatter engine > 全局默认
|
|
88
|
-
* 'pi')+ pi 同步短路 + registry 注入 + probe/fallback 三守卫,D9;本类与
|
|
89
|
-
* SubagentService.execute 是其仅有的两调用点)。路由失败(engine_not_found /
|
|
90
|
-
* engine_probe_failed / model_not_available)与预检命中(engine_capability_unsupported,
|
|
91
|
-
* D3-④)不 reject,入 result.error——与 executeAgentCall 契约一致。
|
|
49
|
+
* - result 形状不变(AgentResult——executeWorkflowAgent 返回类型即 orchestration
|
|
50
|
+
* AgentResult,零映射)
|
|
51
|
+
* - 路由失败/预检命中/嵌套超限经 service 同步抛错(§3.4 同步抛错回脚本 + D3
|
|
52
|
+
* 路由先于 record 创建的构造性推论:不产生孤儿 record)——传播形态与
|
|
53
|
+
* workflowAgentDispatch 注入路径一致(dispatch 闭包同样不吞错),pump 侧
|
|
54
|
+
* dispatchCall catch 兜底回发。
|
|
92
55
|
*/
|
|
93
56
|
export class SubprocessAgentRunner implements AgentRunner {
|
|
94
57
|
private readonly subagentService: SubagentService;
|
|
95
58
|
private ctxModel: ModelInfo | undefined;
|
|
96
|
-
/** pi 引擎(per-session DI 绑定,缺省执行路径——见类注释)。 */
|
|
97
|
-
private readonly piEngine: EnginePort;
|
|
98
59
|
|
|
99
60
|
constructor(deps: SubprocessAgentRunnerDeps) {
|
|
100
61
|
this.subagentService = deps.subagentService;
|
|
101
62
|
this.ctxModel = deps.ctxModel;
|
|
102
|
-
// [D4 聚合连带] 经 asEngineService 显式视图适配(原结构化直绑依赖查询面 public)。
|
|
103
|
-
// [W6] 解析经 host 公共面(descriptor 路由 / inproc DI,见 pi-host-binding 注释)。
|
|
104
|
-
this.piEngine = resolveHostPiEnginePort(() => this.subagentService.asEngineService);
|
|
105
63
|
}
|
|
106
64
|
|
|
107
65
|
/**
|
|
108
|
-
* 刷新主 agent model
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
66
|
+
* 刷新主 agent model 缓存(model_select 事件时由 extension index.ts 调用)。
|
|
67
|
+
*
|
|
68
|
+
* [H2 W4] run() 不再消费 ctxModel(model 解析归 service resolveIdentity),
|
|
69
|
+
* 本方法保留仅为装配链兼容(index.ts 调用不炸);字段更新不再影响执行路径。
|
|
112
70
|
*/
|
|
113
71
|
updateCtxModel(model: ModelInfo | undefined): void {
|
|
114
72
|
this.ctxModel = model;
|
|
115
73
|
}
|
|
116
74
|
|
|
117
|
-
/**
|
|
118
|
-
* 执行单次 agent 调用:路由(P4)→ 预检(D3-④)→ EnginePort.run → PiEngine 委托
|
|
119
|
-
* SubagentService.executeAndAwait。
|
|
120
|
-
*
|
|
121
|
-
* 接线链路:
|
|
122
|
-
* routeEngineForHost(D3-② 路由单点:三层 + pi 同步短路 + probe + 守卫)→
|
|
123
|
-
* assertTaskShapeSupported(D3-④ 预检 capabilities 化)→ mergeTimeoutSignal →
|
|
124
|
-
* engine.run(opts 直传——D6 合流:AgentCallOpts 即 EnginePort 任务形状,零映射;
|
|
125
|
-
* PiEngine 内一次直出 ExecuteOptions + engine 留痕) → executeAndAwait →
|
|
126
|
-
* AgentOutcome → AgentResult
|
|
127
|
-
*
|
|
128
|
-
* 错误处理:不 reject。
|
|
129
|
-
* - 路由失败(未注册 id / probe 失败 + 守卫或 strict)→ AgentResult.error(错误码前缀)
|
|
130
|
-
* - 预检命中(capabilities 不支持的任务形状参数)→ AgentResult.error
|
|
131
|
-
* (engine_capability_unsupported——[D3-④] workflow 域 zcode+worktree 由漏拦变
|
|
132
|
-
* 拦截,本单元唯一有意行为变化;拒绝在 journal/run 之前,无进程无 journal 产物)
|
|
133
|
-
* - executeAndAwait 内部失败 → 返回 AgentResult(success:false) → 已映射 error 字段
|
|
134
|
-
* - executeAndAwait throw(嵌套超限 BC-12)→ catch → AgentResult.error
|
|
135
|
-
* - spawn 级失败已由 runSpawn 内部收口为 failed AgentResult(不逃逸)
|
|
136
|
-
*/
|
|
75
|
+
/** 纯转调 service 统一编排入口(形参原样透传;parentRunId 用直调占位)。 */
|
|
137
76
|
async run(
|
|
138
77
|
opts: AgentCallOpts,
|
|
139
78
|
signal: AbortSignal,
|
|
140
79
|
onEvent?: (event: AgentEvent) => void,
|
|
141
80
|
stream?: SubagentStream,
|
|
142
81
|
): Promise<AgentResult> {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// §3.5.3 作废放宽。路由失败(未注册 id / probe 失败 + strict/守卫)与预检命中
|
|
151
|
-
//(capabilities 驱动,含 worktree——workflow 域漏拦缺口修复)一并按「不 reject」
|
|
152
|
-
// 契约转 result.error。
|
|
153
|
-
let route: EngineRouteResult;
|
|
154
|
-
try {
|
|
155
|
-
const routed = routeEngineForHost({
|
|
156
|
-
routing: this.buildRoutingInput(opts),
|
|
157
|
-
taskModel: opts.model,
|
|
158
|
-
strict: getModelConfigService()?.getGlobalConfig().engineRouting?.strict === true,
|
|
159
|
-
probe: (engineId) => this.engineFor(engineId).probe(),
|
|
160
|
-
piEngine: this.piEngine,
|
|
161
|
-
});
|
|
162
|
-
route = routed instanceof Promise ? await routed : routed;
|
|
163
|
-
// [D3-④] SAR 路径预检调用点(run 前同模块调用;唯一实现 = common/capability-gate)。
|
|
164
|
-
// pi 全参数放行(V4⑤ 反向守护);zcode 拦 fork/conversation/maxTurns/worktree。
|
|
165
|
-
// [D6 合流] opts(AgentCallOpts)直传预检——TaskShapeForGate 是结构子集,
|
|
166
|
-
// conversation/fork/worktree/maxTurns 均在合流形状字段表内。
|
|
167
|
-
assertTaskShapeSupported(route.engineId, route.engine.capabilities(), opts);
|
|
168
|
-
// [u-h2 D2-2 调用点②] workflow 域非 pi 引擎的派发同步期 model 校验——与 chat
|
|
169
|
-
// 路径(subagent-service.executeViaEngine)共享同一入口 validateModelForEngine
|
|
170
|
-
// 与同一错误文案(V2-4④:agent({engine:'zcode', model:<pi id>}) 同步期报
|
|
171
|
-
// 「引擎与模型不配套」,不再落 engine.run 的 prepare 期晚炸)。校验对象是显式
|
|
172
|
-
// opts.model(frontmatter model 的解析归 pi 链,workflow 域非 pi 路径现状不消费
|
|
173
|
-
// ——维持现状语义不扩散)。「不 reject」契约:throw 由本 try 的 catch 收口
|
|
174
|
-
// errorResult,不进入 journal 创建与 engine.run(零 record/spawn 副作用)。
|
|
175
|
-
if (route.engineId !== "pi") {
|
|
176
|
-
validateModelForEngine(route.engine, opts.model);
|
|
177
|
-
}
|
|
178
|
-
} catch (err) {
|
|
179
|
-
// buildRoutingInput 的 agent 解析期校验(未注册 frontmatter engine)、路由失败
|
|
180
|
-
//(probe + strict/守卫)与预检拒绝(engine_capability_unsupported)一并在此
|
|
181
|
-
// 收口——「不 reject」契约
|
|
182
|
-
return errorResult(err, startedAt);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// ── P2 event journal 接线(设计 D6 第②级;对齐点③:路径权威 = 引擎池 key)──
|
|
186
|
-
// [D3-③] writer + retarget + 回填收敛 common/journal-wiring(与 chat 域同一实现):
|
|
187
|
-
// 初始 poolKey 占位 'shared'(pi 恒终值);非池化稳定引擎(zcode)在 prepare 期经
|
|
188
|
-
// RunContext.onPoolResolved 声明实际池 key → retarget——保证 journal 落盘路径与
|
|
189
|
-
// handle.poolKey 同源(handle.journalPath 由本方法 run 返回后回填)。
|
|
190
|
-
//
|
|
191
|
-
// taskId 为宿主侧任务标识(journal 文件名与池引用计数 key)——executeAndAwait
|
|
192
|
-
// 不外露内部 record id(取真实 id 需 hook record store 且改 createRecordForMode
|
|
193
|
-
// 签名,影响面大;P4 决策:保留占位,`sa-` 前缀与 record id 同构。影响面:record
|
|
194
|
-
// GC 时无法按 taskId 联动删 journal(journal 依赖 TTL 兜底回收,见 D8 分域裁决),
|
|
195
|
-
// read ②级经 handle.journalPath 自描述定位不受影响)。
|
|
196
|
-
const taskId = `sa-${crypto.randomUUID()}`;
|
|
197
|
-
const journal = wireEventJournal({ engineId: route.engineId, taskId, forwardEvents: onEvent });
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
// ── [U1 D2] RunContext.modelRef 接入:ctxModel 继承路径的孪生守卫 ──
|
|
201
|
-
// ctxModel 是运行时已验证的 ModelInfo(豁免 registry 存在性复查),但继承产出的
|
|
202
|
-
// canonical 串与显式入参走同一个 pi pattern 引擎,孪生守卫同等适用(modelRefFromVerified)。
|
|
203
|
-
// 守卫在 engine.run 之前同步拒绝:含孪生 registry 下不产生任何 record/spawn,
|
|
204
|
-
// 失败走下方 catch → errorResult(错误文案含恢复指引)。
|
|
205
|
-
// RunContext 类型本身定义在 engine/port.ts(跨模块 port,不在本单元领地),
|
|
206
|
-
// 故接入点为构造 runCtx 前的守卫调用;pi 链路下游 resolveModel 的 ctxModel 分支
|
|
207
|
-
// 有同一守卫(model-resolver.ts),两处共用同一入口函数。
|
|
208
|
-
if (this.ctxModel) {
|
|
209
|
-
const modelService = getModelConfigService();
|
|
210
|
-
if (modelService) modelRefFromVerified(this.ctxModel, modelService.getModelRegistry());
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// ── D-A9: timeoutMs 合并 signal(超时 abort 带 HOST_TIMEOUT_ABORT_REASON 标记)──
|
|
214
|
-
const mergedSignal = mergeTimeoutSignal(signal, opts.timeoutMs);
|
|
215
|
-
|
|
216
|
-
// ── P1/P4 引擎接线:EnginePort.run ──
|
|
217
|
-
const runCtx: RunContext = {
|
|
218
|
-
taskId,
|
|
219
|
-
poolKey: JOURNAL_INITIAL_POOL_KEY,
|
|
220
|
-
signal: mergedSignal,
|
|
221
|
-
onEvent: journal.onEvent,
|
|
222
|
-
ctxModel: this.ctxModel,
|
|
223
|
-
...(route.engineFallback !== undefined ? { engineFallback: route.engineFallback } : {}),
|
|
224
|
-
onPoolResolved: journal.onPoolResolved,
|
|
225
|
-
// [U0 D10] 终止链路径①:引擎 spawn 的子进程注册进 session-runner 的
|
|
226
|
-
// spawnedChildren 记账(dispose killAll 收割兜底对 workflow 域引擎任务生效);
|
|
227
|
-
// taskId('sa-' 前缀)即记账 key,与 chat 域 kickOffEngineRun 的 record.id 同构
|
|
228
|
-
onChildSpawned: (child) => registerSpawnedChildForRecord(taskId, child),
|
|
229
|
-
...(stream !== undefined ? { stream } : {}),
|
|
230
|
-
// [D6 合流] 解耦形态(有 schemaEnv 无 schema)不再经 RunContext.schemaEnv
|
|
231
|
-
// 兜底通道——schemaEnv 已在合流形状 AgentCallOpts.schemaEnv 内,pi 直出
|
|
232
|
-
// (agentCallToExecuteOptions)以「schema 派生优先、schemaEnv 兜底」取值,
|
|
233
|
-
// 与原 ctx 兜底链路逐字节等值。
|
|
234
|
-
};
|
|
235
|
-
const { handle, outcome } = await route.engine.run(
|
|
236
|
-
// [D6 合流] opts 直传——AgentCallOpts 即 EnginePort 任务形状(缺省路径零映射;
|
|
237
|
-
// pi 边界一次直出由 PiEngine.agentCallToExecuteOptions 承担,逐字段等值由
|
|
238
|
-
// inproc pi 引擎目录/__tests__/spawn-opts-direct.test.ts 对照表锁定)
|
|
239
|
-
opts,
|
|
240
|
-
runCtx,
|
|
241
|
-
);
|
|
242
|
-
// handle.journalPath 回填(§3.3.6:read ②级的自描述定位符——运行期落盘路径
|
|
243
|
-
// 权威在 writer,handle 记录最终路径供跨重启 read 消费)
|
|
244
|
-
journal.backfillHandle(handle);
|
|
245
|
-
return outcomeToRunnerResult(outcome);
|
|
246
|
-
} catch (err) {
|
|
247
|
-
// executeAndAwait throw(嵌套超限 ForkDepthExceededError,BC-12)或未预期异常 → 不 reject,入 error。
|
|
248
|
-
const message = toErrorMessage(err);
|
|
249
|
-
return {
|
|
250
|
-
content: "",
|
|
251
|
-
durationMs: Date.now() - startedAt,
|
|
252
|
-
error: message,
|
|
253
|
-
toolCalls: [],
|
|
254
|
-
};
|
|
255
|
-
} finally {
|
|
256
|
-
// run 终态后 flush + fsync 一次(§3.3.6 写入纪律);写失败已由 writer 内部
|
|
257
|
-
// warn + failed 收口,close 不抛(journal 是②级尽力而为数据源)
|
|
258
|
-
await journal.close();
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// ── 内部 ──
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* 引擎获取(routeEngineForHost 的 probe 注入体):pi 走 per-session DI 绑定(mock
|
|
266
|
-
* 语义 + 生产同单例,P1 行为零变化);非 pi 经 registry.getEngine 动态获取(P4:
|
|
267
|
-
* 引擎身份归属注册表,未注册 id 抛 EngineNotFoundError——路由期已前置校验,这里
|
|
268
|
-
* 是防御性兜底)。[D3-②] get/has/list 的路由期注入已由 routeEngineForHost 内部
|
|
269
|
-
* 承载(本地 pi 恒可用口径),本方法只剩 probe 一个消费点(pi 请求同步短路恒免探)。
|
|
270
|
-
*/
|
|
271
|
-
private engineFor(engineId: string): EnginePort {
|
|
272
|
-
if (engineId === "pi") return this.piEngine;
|
|
273
|
-
return getEngine(engineId);
|
|
82
|
+
return this.subagentService.executeWorkflowAgent(
|
|
83
|
+
opts,
|
|
84
|
+
SAR_UNATTACHED_PARENT_RUN_ID,
|
|
85
|
+
signal,
|
|
86
|
+
onEvent,
|
|
87
|
+
stream,
|
|
88
|
+
);
|
|
274
89
|
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* 三层路由输入装配(D9):调用参数(opts.engine,workflow step 级透传)> agent
|
|
278
|
-
* frontmatter(ModelConfigService.getAgentConfig——loadByPath mtime 缓存,幂等)>
|
|
279
|
-
* 全局默认(config.json defaultEngine)。单例未就绪(session_start 前/测试 mock)
|
|
280
|
-
* 时各层缺省——落内置 'pi'。
|
|
281
|
-
*/
|
|
282
|
-
private buildRoutingInput(opts: AgentCallOpts): EngineRoutingInput {
|
|
283
|
-
const service = getModelConfigService();
|
|
284
|
-
const agentEngine =
|
|
285
|
-
opts.agent !== undefined && opts.agent !== "" ? service?.getAgentConfig(opts.agent)?.engine : undefined;
|
|
286
|
-
const globalDefault = service?.getGlobalConfig().defaultEngine;
|
|
287
|
-
return {
|
|
288
|
-
...(opts.engine !== undefined && opts.engine !== "" ? { callEngine: opts.engine } : {}),
|
|
289
|
-
...(agentEngine !== undefined && agentEngine !== "" ? { agentEngine } : {}),
|
|
290
|
-
...(globalDefault !== undefined && globalDefault !== "" ? { globalDefaultEngine: globalDefault } : {}),
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/** 路由期/预检错误 → AgentResult.error(错误码前缀格式保留——engine_not_found 等)。 */
|
|
296
|
-
function errorResult(err: unknown, startedAt: number): AgentResult {
|
|
297
|
-
return {
|
|
298
|
-
content: "",
|
|
299
|
-
durationMs: Date.now() - startedAt,
|
|
300
|
-
error: toErrorMessage(err),
|
|
301
|
-
toolCalls: [],
|
|
302
|
-
};
|
|
303
90
|
}
|
|
304
91
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
* 的返回值逐字段映射而来,字段全集完整性由 pi-engine 单测锁定(缺字段会在该处转红,
|
|
310
|
-
* 不会静默丢失)。
|
|
311
|
-
*/
|
|
312
|
-
function outcomeToRunnerResult(outcome: AgentOutcome): AgentResult {
|
|
313
|
-
return {
|
|
314
|
-
content: outcome.content,
|
|
315
|
-
// [D5-③] 失败分诊标签透传(pi 引擎产出;zcode 不产 failureKind,缺省 =
|
|
316
|
-
// unknown = 可重试)。成功路径 undefined 不落键。
|
|
317
|
-
...(outcome.failureKind !== undefined ? { failureKind: outcome.failureKind } : {}),
|
|
318
|
-
parsedOutput: outcome.parsedOutput,
|
|
319
|
-
usage: outcome.usage,
|
|
320
|
-
durationMs: outcome.durationMs,
|
|
321
|
-
error: outcome.error,
|
|
322
|
-
sessionId: outcome.sessionId,
|
|
323
|
-
sessionFile: outcome.sessionFile,
|
|
324
|
-
worktreePath: outcome.worktreePath,
|
|
325
|
-
toolCalls: outcome.toolCalls,
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* D-A9: per-call timeoutMs 合并进 AbortSignal([D6 合流迁入]——原定义在已删除的
|
|
331
|
-
* execution/execute-options-mapper.ts,本类是唯一消费点,运行期件随消费方落位)。
|
|
332
|
-
*
|
|
333
|
-
* 墙钟 timeoutMs(per-call)+ 外部 signal(run 级 abort)都生效。
|
|
334
|
-
* 缺此合并则 agent({timeoutMs:5000}) 静默无效(BC-9)。
|
|
335
|
-
*
|
|
336
|
-
* @param signal 外部 signal(workflow run 级 controller.signal)
|
|
337
|
-
* @param timeoutMs per-call 墙钟超时;undefined/<=0 → 不设超时,原样返回 signal
|
|
338
|
-
* @returns 合并后的 signal(timeoutMs 或外部 signal 任一 abort 都触发)
|
|
339
|
-
*/
|
|
340
|
-
export function mergeTimeoutSignal(
|
|
341
|
-
signal: AbortSignal,
|
|
342
|
-
timeoutMs?: number,
|
|
343
|
-
): AbortSignal {
|
|
344
|
-
if (!timeoutMs || timeoutMs <= 0) {
|
|
345
|
-
return signal;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const controller = new AbortController();
|
|
349
|
-
// 超时 abort 带 reason 标记(对齐点④):引擎合成终态时判别「宿主超时」
|
|
350
|
-
// (engine_timeout 公共合成)vs「外部 cancel」(中止标记)——pi 链路不读 reason,
|
|
351
|
-
// 行为不变。外部 signal abort 不带标记(用户/编排层 cancel 语义)。
|
|
352
|
-
const timer = setTimeout(() => controller.abort(HOST_TIMEOUT_ABORT_REASON), timeoutMs);
|
|
353
|
-
timer.unref();
|
|
354
|
-
|
|
355
|
-
const onExternalAbort = (): void => controller.abort();
|
|
356
|
-
if (signal.aborted) {
|
|
357
|
-
controller.abort();
|
|
358
|
-
} else {
|
|
359
|
-
signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
controller.signal.addEventListener(
|
|
363
|
-
"abort",
|
|
364
|
-
() => {
|
|
365
|
-
clearTimeout(timer);
|
|
366
|
-
if (!signal.aborted) signal.removeEventListener("abort", onExternalAbort);
|
|
367
|
-
},
|
|
368
|
-
{ once: true },
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
return controller.signal;
|
|
372
|
-
}
|
|
92
|
+
// [H2 W2 迁移步⑥] mergeRunSignals/MergedRunSignalHandle 公共 helper 权威落点在
|
|
93
|
+
// engine/common/run-signals.ts;此处 re-export 保持既有 import 路径(no-progress
|
|
94
|
+
// killall 测试等消费面零改动)。
|
|
95
|
+
export { mergeRunSignals, type MergedRunSignalHandle } from "./engine/common/run-signals.ts";
|
package/src/execution/types.ts
CHANGED
|
@@ -47,8 +47,9 @@ export const DEFAULT_AGENT_NAME = "general-purpose";
|
|
|
47
47
|
* 旧 cancelled 折入 closed(closedReason='cancelled' 区分)。
|
|
48
48
|
*
|
|
49
49
|
* running = 活跃态。含两种子态(由派生谓词区分,见 lifecycle-predicates.ts):
|
|
50
|
-
* - 对话模式等待续聊(旧 idle
|
|
51
|
-
*
|
|
50
|
+
* - 对话模式等待续聊(旧 idle):进程已回收,待冷路径 resume
|
|
51
|
+
* (isResumable=running && 无活进程句柄)。旧「进程保活待热路径」形态随
|
|
52
|
+
* H1 U6 长驻退役消亡,isIdle(hasIdleTimer)生产恒 false。
|
|
52
53
|
* - 正在执行(有活进程句柄)。
|
|
53
54
|
*
|
|
54
55
|
* closed = 统一终态(done/failed/crashed/cancelled 合并)。具体关闭原因由
|
|
@@ -57,6 +58,16 @@ export const DEFAULT_AGENT_NAME = "general-purpose";
|
|
|
57
58
|
*/
|
|
58
59
|
export type ExecutionStatus = "running" | "closed";
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* record 来源身份(H2 W1,设计 subagent-workflow-record-unification §3.3 D1 建议新增):
|
|
63
|
+
* "tool" — 主 agent 经 subagent 工具手动派发(现状全部 record);
|
|
64
|
+
* "workflow" — workflow 脚本内 agent() 调用派发(生产写入方 W2 executeWorkflowAgent 接线)。
|
|
65
|
+
* 缺省语义 = "tool":存量 record / 未传字段的 entry 反序列化产物一律视为手动派发,
|
|
66
|
+
* 四个投影消费面(subagents tool list / renderer 侧栏计数 / renderer 后台工作指示 /
|
|
67
|
+
* TUI /subagents)对缺省 record 的可见性与历史行为完全一致(零迁移)。
|
|
68
|
+
*/
|
|
69
|
+
export type RecordOrigin = "tool" | "workflow";
|
|
70
|
+
|
|
60
71
|
/**
|
|
61
72
|
* closed 终态的 L2 关闭原因子枚举。
|
|
62
73
|
*
|
|
@@ -79,7 +90,7 @@ export type ClosedReason = 'parent-shutdown' | 'parent-fork' | 'parent-new' | 'u
|
|
|
79
90
|
* sessionFile(resurrectClosed 回边),不再要求 fork-from 换新 id。
|
|
80
91
|
*
|
|
81
92
|
* 取值以 `.finalized` sidecar 实际写入的 ClosedReason 字面量为准:
|
|
82
|
-
* disconnected — 断联(sidecar
|
|
93
|
+
* disconnected — 断联(sidecar 空/损坏兜底;in-proc 时代写点已随 engine-CLI 化消失)
|
|
83
94
|
* parent-shutdown — 父进程 session_shutdown 回收
|
|
84
95
|
* 其余 reason 刻意排除:user-close/cancelled 是用户主动告别(close 语义不可旁路);
|
|
85
96
|
* gc 是自然完成(追问走 fork-from 或新 start);parent-fork/parent-new 同理是编排性
|
|
@@ -133,19 +144,16 @@ export type ExecutionOutcome = "completed" | "failed" | "cancelled";
|
|
|
133
144
|
export type ProjectedOutcome = ExecutionOutcome | "closed-legacy";
|
|
134
145
|
|
|
135
146
|
/**
|
|
136
|
-
*
|
|
147
|
+
* 对外两态(设计决策 10 细则 3):内部 ExecutionStatus(v4 B-1 两态)收敛为 agent
|
|
137
148
|
* 可理解的状态语义。真实映射只有两条:
|
|
138
149
|
* running → active / closed → ended(closed 统一终态,含 cancelled)。
|
|
139
150
|
* mapExternalState 不消费 ClosedReason——closed 恒映射 ended。
|
|
140
151
|
*
|
|
141
|
-
* waiting / error 是历史多态映射(idle→waiting / failed+crashed→error)的遗留声明:
|
|
142
|
-
* 对外四态联合契约不变,但当前状态机不产生这两个值。
|
|
143
|
-
*
|
|
144
152
|
* 原始 ExecutionStatus 进 list item 的 status 字段供调试;state 是对外主字段。
|
|
145
|
-
* 映射实现见 subagent-actions.ts mapExternalState——未来内部加态必须扩展该处,
|
|
153
|
+
* 映射实现见 subagent-actions-core.ts mapExternalState——未来内部加态必须扩展该处,
|
|
146
154
|
* 漏加会在 default 分支编译报错,不影响对外契约。
|
|
147
155
|
*/
|
|
148
|
-
export type ExternalState = "active" | "
|
|
156
|
+
export type ExternalState = "active" | "ended";
|
|
149
157
|
|
|
150
158
|
/** 执行模式。background = 调用方立即拿 handle 返回,子 agent 在 detached promise 里跑。 */
|
|
151
159
|
export type ExecutionMode = "background";
|
|
@@ -172,6 +180,8 @@ export type ExecutionMode = "background";
|
|
|
172
180
|
// tool_start / tool_end ↔ ACP tool_call / tool_call_update
|
|
173
181
|
// turn_end / message_end ↔ ACP prompt turn 终态(stop_reason + usage)
|
|
174
182
|
// compaction ↔ ACP session/compaction
|
|
183
|
+
// activity ↔ 无 ACP 对应(协议内生活性信号:reducer no-op、
|
|
184
|
+
// 不落 journal,仅供无进展守护刷新判活)
|
|
175
185
|
// 本协议以 pi 为语义锚点(D3)——命名不迁移,对照表仅保证未来 AcpEngine 适配器
|
|
176
186
|
// 与跨引擎 trace 映射的翻译成本最低。
|
|
177
187
|
export type {
|
|
@@ -279,7 +289,8 @@ export interface AgentResult {
|
|
|
279
289
|
// Object.freeze 守卫不可变」的语义注释见消费方 worktree-manager / worktree-git-ops)。
|
|
280
290
|
export type { WorktreeHandle } from "@zhushanwen/subagent-engine-sdk";
|
|
281
291
|
|
|
282
|
-
/** alive marker
|
|
292
|
+
/** alive marker:跨进程写权声明载体(写者 = 宿主进程;acquire/release 见
|
|
293
|
+
* alive-store 模块头;startedAt 仅载体字段,判活不消费——pid 单判据)。 */
|
|
283
294
|
export interface AliveMarker {
|
|
284
295
|
readonly pid: number;
|
|
285
296
|
readonly id: string;
|
|
@@ -366,6 +377,19 @@ export interface ExecutionRecord {
|
|
|
366
377
|
readonly parentRecordId: string | undefined;
|
|
367
378
|
/** subagent 递归深度。顶层(主 session 直接创建)=0,每层嵌套 +1。 */
|
|
368
379
|
readonly depth: number;
|
|
380
|
+
/**
|
|
381
|
+
* 来源身份(H2 W1,D1)。缺省(undefined)语义 = "tool"(存量 record 零迁移);
|
|
382
|
+
* "workflow" = workflow 脚本 agent() 派发(生产写入方 W2 接线)。过滤在投影/查询
|
|
383
|
+
* 消费面(list 默认滤 workflow origin),store 治理面(孤儿恢复/revive)全量可见。
|
|
384
|
+
* 持久化经 subagent-record entry。
|
|
385
|
+
*/
|
|
386
|
+
readonly origin?: RecordOrigin;
|
|
387
|
+
/**
|
|
388
|
+
* origin="workflow" 时所属 workflow run 的 id(W2 写入);tool 来源恒 undefined。
|
|
389
|
+
* W2 run 视图进度 / W3 下钻按本 id 查询本 run 的 record 集(内存 ∪ 磁盘重建口径,
|
|
390
|
+
* collectRecordsByParentRunId)。持久化经 subagent-record entry。
|
|
391
|
+
*/
|
|
392
|
+
readonly parentRunId?: string;
|
|
369
393
|
/**
|
|
370
394
|
* 对话模式标志(可持续对话 subagent)。true = 轮次完成进 idle 态(保留 record +
|
|
371
395
|
* worktree)等待续聊,而非一次性终态化。
|
|
@@ -443,32 +467,9 @@ export interface ExecutionRecord {
|
|
|
443
467
|
* 进 idle)+1。undefined 时视为 0。非 chatMode 不自增。
|
|
444
468
|
*/
|
|
445
469
|
round?: number;
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
* - 生命周期:undefined 视为 0(首轮增量 = 全量,与改造前首轮通知逐字节一致,向后兼容旧
|
|
450
|
-
* record);唯一写点 onRoundSettled 第 5 步(notify 之后推进),唯一读点同回调第 2 步
|
|
451
|
-
* (`getFullTextFrom(record, record.roundBaseTurnIndex ?? 0)`)。非 chatMode 恒
|
|
452
|
-
* undefined(onRoundSettled 是 session-runner chatMode 分支专属回调)。
|
|
453
|
-
* - D1 滞后空 turn 防丢文本(防御性):pi 当前事件序下该形态不可达——带 usage 的
|
|
454
|
-
* message_end 恒先于 turn_end(@earendil-works/pi-agent-core dist/agent-loop.js
|
|
455
|
-
* :240/:253/:547 三处 message_end emit 均在 :131 正常路径 turn_end 之前),settle 时
|
|
456
|
-
* turn 全闭合。防 pi 未来事件序变化:若 settle 时刻末 turn 是滞后 message_end 开出的
|
|
457
|
-
* 空 turn(execution-record.ts message_end 分支经 currentTurn,需同时过两层 usage 守卫:
|
|
458
|
-
* session-runner.ts 转发层 `if (msg?.usage)`(bare message_end 不转发)+ execution-record.ts
|
|
459
|
-
* 累积层 `if (event.usage)`(bare message_end 不开 turn)),推进公式
|
|
460
|
-
* nextRoundBaseTurnIndex 把它留在下一轮增量内(新轮首个 text_delta 经 currentTurn 复用该
|
|
461
|
-
* 空 turn,复用累积被 slice 覆盖);直用 turns.length 推进会把下轮首段文本挤出 slice
|
|
462
|
-
* 范围静默丢失。
|
|
463
|
-
* - D4 不持久化:磁盘重建走 createRecord(turns 仅为初始 [emptyTurn()]),base=0 对空 turn
|
|
464
|
-
* 的增量派生等价为空、天然产出仅新轮增量,持久化是死数据。故不写 manifest、不参与重建。
|
|
465
|
-
* - pi 内部序锚定依据(R1 mitigation):@earendil-works/pi-agent-core 0.84.2
|
|
466
|
-
* dist/agent-loop.js :108-111(error/aborted stopReason 也先 emit turn_end 再 agent_end)
|
|
467
|
-
* 与 :131(正常路径 turn_end 收尾);agent_settled 在 agent_end 之后 emit,故未闭合
|
|
468
|
-
* turn 只可能来自滞后事件。pi 升级若改变 turn_end/agent_end 时序,onRoundSettled 推进前
|
|
469
|
-
* 的观测哨(末 turn 未闭合且 text 非空 → logger.warn)会留痕。
|
|
470
|
-
*/
|
|
471
|
-
roundBaseTurnIndex?: number;
|
|
470
|
+
// [H1 U6 / D7 ③] roundBaseTurnIndex(增量通知 base 记账)已退役删除——消费函数
|
|
471
|
+
// getFullTextFrom/nextRoundBaseTurnIndex 与唯一写点 settleChatRoundFromResponse 随
|
|
472
|
+
// chat 域载体退役,生产零调用(base 推进 = 死记账)。
|
|
472
473
|
/**
|
|
473
474
|
* record 进入 idle 态的时间戳(ms)。finalizeRoundToIdle 设值;GC 定时器据此计算
|
|
474
475
|
* 剩余 TTL。undefined = 非 idle 态(running/closed/cancelled)或旧 record 缺失字段。
|
|
@@ -493,12 +494,11 @@ export interface ExecutionRecord {
|
|
|
493
494
|
sessionFile?: string;
|
|
494
495
|
|
|
495
496
|
/**
|
|
496
|
-
* [V2 决策 3] 子进程 pid(spawn
|
|
497
|
+
* [V2 决策 3] 子进程 pid(spawn 后回填到内存 record,并随 record 持久化落盘)。
|
|
497
498
|
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
* 向后兼容:旧 record 无此字段,按无 pid 处理(孤儿扫描跳过)。
|
|
499
|
+
* 诊断字段:排障时对照 record 文件与进程表核实 spawn 事实。原职责 4 孤儿扫描
|
|
500
|
+
* (按持久化 pid 扫收上次崩溃遗留孤儿)自落地起未接线,已随 L2 死代码清扫删除。
|
|
501
|
+
* undefined = 尚未 spawn / 已退出。向后兼容:旧 record 无此字段,按无 pid 处理。
|
|
502
502
|
*/
|
|
503
503
|
pid?: number;
|
|
504
504
|
|
|
@@ -693,6 +693,14 @@ export interface SubagentListItem {
|
|
|
693
693
|
* 无需翻 error 字段原文(S5)。
|
|
694
694
|
*/
|
|
695
695
|
outcome?: ProjectedOutcome;
|
|
696
|
+
/**
|
|
697
|
+
* 来源身份(H2 W1):undefined(存量 list 形态 / record 无 origin)= "tool" 语义。
|
|
698
|
+
* includeWorkflow 打开后 list 条目与手动派发 record 靠本字段区分(排查 workflow
|
|
699
|
+
* run's subagents 场景的辨识数据)。
|
|
700
|
+
*/
|
|
701
|
+
origin?: RecordOrigin;
|
|
702
|
+
/** origin="workflow" 时所属 workflow run id;tool 来源恒缺省(同 record 侧)。 */
|
|
703
|
+
parentRunId?: string;
|
|
696
704
|
}
|
|
697
705
|
|
|
698
706
|
/** background 启动的内层响应(挂在 SubagentToolResult.bgResponse)。 */
|
|
@@ -805,6 +813,17 @@ export interface SubagentRecord {
|
|
|
805
813
|
parentRecordId: string | undefined;
|
|
806
814
|
/** subagent 递归深度。顶层 =0,每层嵌套 +1。 */
|
|
807
815
|
depth: number;
|
|
816
|
+
/**
|
|
817
|
+
* 来源身份(H2 W1,D1,与 ExecutionRecord.origin 同源投影/entry 重建)。
|
|
818
|
+
* 缺省(undefined / 存量磁盘重建源)语义 = "tool";消费面按 `=== "workflow"`
|
|
819
|
+
* 负向判定,list 查询缺省过滤(includeWorkflow 缺省 false)。
|
|
820
|
+
*/
|
|
821
|
+
origin?: RecordOrigin;
|
|
822
|
+
/**
|
|
823
|
+
* origin="workflow" 时所属 workflow run id(与 ExecutionRecord.parentRunId 同源)。
|
|
824
|
+
* W2/W3 run 视图下钻按 collectRecordsByParentRunId 查询;tool 来源恒 undefined。
|
|
825
|
+
*/
|
|
826
|
+
parentRunId?: string;
|
|
808
827
|
endedAt: number | undefined;
|
|
809
828
|
turns: number;
|
|
810
829
|
totalTokens: number;
|
|
@@ -842,8 +861,6 @@ export interface SubagentRecord {
|
|
|
842
861
|
* (轮终 idle / 重建孤儿兜底),GUI 侧据此排除「真在跑」判定。
|
|
843
862
|
*/
|
|
844
863
|
resumable?: boolean;
|
|
845
|
-
/** 外部 Pi 实例(进程隔离模式下由外部启动的子进程)。 */
|
|
846
|
-
externalInstance?: AliveMarker;
|
|
847
864
|
/** fork 模式下的 worktree handle。 */
|
|
848
865
|
worktreeHandle?: WorktreeHandle;
|
|
849
866
|
/**
|
|
@@ -26,6 +26,7 @@ import { getLogger } from "../core/logger.ts";
|
|
|
26
26
|
import {
|
|
27
27
|
DialogGlobalQueue,
|
|
28
28
|
isValidDialogTimeout,
|
|
29
|
+
registerActiveDialogQueue,
|
|
29
30
|
type UiRequest,
|
|
30
31
|
type UiRequestHandler,
|
|
31
32
|
type UiResponse,
|
|
@@ -94,6 +95,10 @@ export function createUiRequestHandlerForMode(
|
|
|
94
95
|
const hostMode = resolveHostMode(ctx.mode);
|
|
95
96
|
if (hostMode === "headless") return undefined;
|
|
96
97
|
|
|
98
|
+
// [SR-4 接线登记] 队列是跨子进程全局单例(宿主壳创建),而子进程退出信号来自 core
|
|
99
|
+
// 引擎镜像层——本工厂是两者交汇点,在返回 handler 的同一路径上登记,壳侧无需改动。
|
|
100
|
+
registerActiveDialogQueue(dialogQueue);
|
|
101
|
+
|
|
97
102
|
const realHandler = createRealHandler(ctx, hostMode, registry);
|
|
98
103
|
|
|
99
104
|
return async (req: UiRequest): Promise<UiResponse> => {
|