@zhushanwen/subagent-core 0.6.0 → 0.7.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 +1 -1
- package/dist/chunk-KXVBIVOU.js +16 -0
- package/dist/chunk-T2SYBW3I.js +24 -0
- package/dist/chunk-VURUAGMM.js +2305 -0
- package/dist/{types-C3fE3R9x.d.cts → engine-discovery-scan-ocpM8FmI.d.cts} +770 -668
- package/dist/{types-C3fE3R9x.d.ts → engine-discovery-scan-ocpM8FmI.d.ts} +770 -668
- package/dist/execution/engine/engine-discovery-scan.cjs +2210 -0
- package/dist/execution/engine/engine-discovery-scan.d.cts +4 -0
- package/dist/execution/engine/engine-discovery-scan.d.ts +4 -0
- package/dist/execution/engine/engine-discovery-scan.js +20 -0
- package/dist/execution/engine/paths.cjs +6 -23
- package/dist/execution/engine/paths.d.cts +1 -8
- package/dist/execution/engine/paths.d.ts +1 -8
- package/dist/execution/engine/paths.js +1 -1
- package/dist/execution/relay-env.cjs +12 -28
- package/dist/execution/relay-env.d.cts +1 -33
- package/dist/execution/relay-env.d.ts +1 -33
- package/dist/execution/relay-env.js +5 -3
- package/dist/index.cjs +14045 -16059
- package/dist/index.d.cts +1035 -1579
- package/dist/index.d.ts +1035 -1579
- package/dist/index.js +9838 -13800
- package/dist.bundle/index.cjs +28875 -30323
- package/package.json +20 -26
- package/src/__tests__/record-store-last-line.test.ts +16 -7
- package/src/core/error-message.ts +7 -6
- package/src/core/host-services.ts +8 -2
- package/src/core/notify-ports.ts +17 -2
- package/src/execution/__tests__/chat-engine-routing.test.ts +62 -28
- package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +255 -0
- package/src/execution/__tests__/collect-coordinator-service.test.ts +36 -47
- package/src/execution/__tests__/collect-mixed-dispatch.test.ts +20 -53
- package/src/execution/__tests__/delivery-methods.test.ts +179 -237
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -2
- package/src/execution/__tests__/execute-nesting.test.ts +20 -13
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +20 -33
- package/src/execution/__tests__/gc-timer.test.ts +7 -22
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +20 -10
- package/src/execution/__tests__/helpers/fake-engine-port.ts +187 -0
- package/src/execution/__tests__/helpers/spawn-mock.ts +36 -9
- package/src/execution/__tests__/helpers/subagent-service-mocks.ts +1 -1
- package/src/execution/__tests__/idle-gc.test.ts +200 -0
- package/src/execution/__tests__/lifecycle-predicates.test.ts +26 -21
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +5 -2
- package/src/execution/__tests__/reconcile-sweep.test.ts +200 -0
- package/src/execution/__tests__/record-store.test.ts +60 -6
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +20 -13
- package/src/execution/__tests__/round-supervisor.test.ts +293 -0
- package/src/execution/__tests__/session-pending.test.ts +119 -17
- package/src/execution/__tests__/stream-sink-retirement.test.ts +10 -10
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +1 -11
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +33 -30
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +2 -9
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +59 -129
- package/src/execution/__tests__/subagent-service.test.ts +2 -2
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +109 -7
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +108 -36
- package/src/execution/__tests__/sync-collect-recovery.test.ts +21 -36
- package/src/execution/__tests__/workflow-state-root.test.ts +232 -0
- package/src/execution/agent-registry.ts +6 -2
- package/src/execution/dialog-queue.ts +6 -73
- package/src/execution/engine/__tests__/common/capability-gate.test.ts +115 -15
- package/src/execution/engine/__tests__/common/errors.test.ts +11 -18
- package/src/execution/engine/__tests__/common/kill-chain.test.ts +7 -0
- package/src/execution/engine/__tests__/common/nesting-guard.test.ts +9 -3
- package/src/execution/engine/__tests__/common/session-view-service.test.ts +90 -3
- package/src/execution/engine/__tests__/conformance/H9-test-disposition.md +116 -0
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +377 -0
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/recorded.fixture.json +331 -0
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +213 -0
- package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +230 -0
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +69 -42
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +4 -81
- package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +67 -44
- package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +81 -54
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +133 -70
- package/src/execution/engine/__tests__/conformance/engine-crash.test.ts +143 -0
- package/src/execution/engine/__tests__/conformance/fake-engine-capabilities.ts +19 -0
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +7 -2
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +6 -5
- package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +398 -0
- package/src/execution/engine/__tests__/conformance/registry-fork-filter.test.ts +221 -0
- package/src/execution/engine/__tests__/conformance/round-liveness-supervisor.test.ts +302 -0
- package/src/execution/engine/__tests__/conformance/static-spawn-guard.test.ts +58 -0
- package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +558 -0
- package/src/execution/engine/__tests__/host-task-spec.test.ts +45 -0
- package/src/execution/engine/__tests__/model-ref-split.test.ts +74 -0
- package/src/execution/engine/__tests__/registry.test.ts +206 -1
- package/src/execution/engine/__tests__/routing.test.ts +97 -0
- package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +97 -0
- package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +294 -0
- package/src/execution/engine/client/__tests__/engine-client.test.ts +516 -0
- package/src/execution/engine/client/__tests__/mirror.test.ts +67 -0
- package/src/execution/engine/client/__tests__/pid-file.test.ts +257 -0
- package/src/execution/engine/client/__tests__/protocol-closure.test.ts +95 -0
- package/src/execution/engine/client/__tests__/remote-engine.test.ts +457 -0
- package/src/execution/engine/client/client-options.ts +103 -0
- package/src/execution/engine/client/engine-client.ts +687 -0
- package/src/execution/engine/client/mirror.ts +167 -0
- package/src/execution/engine/client/pid-file.ts +392 -0
- package/src/execution/engine/client/reaper.ts +95 -0
- package/src/execution/engine/client/remote-engine.ts +441 -0
- package/src/execution/engine/client/reverse-router.ts +255 -0
- package/src/execution/engine/common/capability-gate.ts +109 -22
- package/src/execution/engine/common/errors.ts +9 -25
- package/src/execution/engine/common/event-journal.ts +4 -50
- package/src/execution/engine/common/journal-replay.ts +3 -1
- package/src/execution/engine/common/kill-chain.ts +18 -251
- package/src/execution/engine/common/nesting-guard.ts +18 -114
- package/src/execution/engine/common/pool-manager.ts +4 -0
- package/src/execution/engine/common/session-view-service.ts +56 -84
- package/src/execution/engine/config.ts +151 -0
- package/src/execution/engine/d8-compat.ts +346 -0
- package/src/execution/engine/engine-discovery-roots.ts +107 -0
- package/src/execution/engine/engine-discovery-scan.ts +269 -0
- package/src/execution/engine/engine-discovery.ts +30 -7
- package/src/execution/engine/engine-inspect-package.ts +282 -0
- package/src/execution/engine/engine-manifest.ts +244 -0
- package/src/execution/engine/host/__tests__/host-askuser-endpoint.test.ts +123 -0
- package/src/execution/engine/host/__tests__/host-bridge.test.ts +135 -0
- package/src/execution/engine/host/__tests__/spawned-children.test.ts +73 -0
- package/src/execution/engine/host/host-bridge.ts +150 -0
- package/src/execution/engine/host/host-ui-endpoint.ts +47 -0
- package/src/execution/engine/host/pi-host-binding.ts +91 -0
- package/src/execution/engine/host/spawned-children.ts +139 -0
- package/src/execution/engine/host-task-spec.ts +29 -2
- package/src/execution/engine/model-validation.ts +55 -2
- package/src/execution/engine/paths.ts +16 -41
- package/src/execution/engine/port.ts +48 -2
- package/src/execution/engine/registry.ts +153 -34
- package/src/execution/engine/routing.ts +225 -52
- package/src/execution/engine/types.ts +25 -200
- package/src/execution/finalize-record.ts +25 -0
- package/src/execution/idle-gc.ts +89 -14
- package/src/execution/lifecycle-manager.ts +10 -7
- package/src/execution/lifecycle-predicates.ts +10 -8
- package/src/execution/record-store.ts +29 -2
- package/src/execution/relay-env.ts +19 -36
- package/src/execution/round-supervisor/domain.ts +89 -0
- package/src/execution/round-supervisor/index.ts +33 -0
- package/src/execution/round-supervisor/notify-accounting.ts +87 -0
- package/src/execution/round-supervisor/reconcile-sweep.ts +235 -0
- package/src/execution/round-supervisor/service-binding.test.ts +661 -0
- package/src/execution/round-supervisor/service-binding.ts +273 -0
- package/src/execution/round-supervisor/supervisor.ts +426 -0
- package/src/execution/session-pending.ts +68 -74
- package/src/execution/settled-watchdog.ts +39 -0
- package/src/execution/subagent-service.ts +746 -400
- package/src/execution/subprocess-agent-runner.ts +16 -8
- package/src/execution/types.ts +41 -117
- package/src/execution/ui-channels.ts +13 -214
- package/src/execution/ui-request-handler-factory.ts +7 -4
- package/src/execution/ui-request-observability.ts +2 -2
- package/src/execution/workflow-state-root.ts +67 -0
- package/src/execution/worktree-git-ops.ts +5 -0
- package/src/execution/worktree-manager.ts +11 -1
- package/src/index.ts +55 -26
- package/src/orchestration/__tests__/execute-agent-call.test.ts +1 -1
- package/src/orchestration/execute-agent-call.ts +1 -1
- package/src/orchestration/file-run-store.ts +144 -59
- package/src/orchestration/models/types.ts +43 -42
- package/src/shared/zcode-model-ref.ts +31 -0
- package/dist/chunk-43ONBFZX.js +0 -240
- package/dist/chunk-A4IVZWVX.js +0 -31
- package/dist/chunk-APZY4IME.js +0 -27
- package/dist/chunk-V3VHZ2VX.js +0 -59
- package/dist/execution/engine/engines/zcode/constants.cjs +0 -107
- package/dist/execution/engine/engines/zcode/constants.d.cts +0 -135
- package/dist/execution/engine/engines/zcode/constants.d.ts +0 -135
- package/dist/execution/engine/engines/zcode/constants.js +0 -54
- package/dist/execution/engine/engines/zcode/reader.cjs +0 -276
- package/dist/execution/engine/engines/zcode/reader.d.cts +0 -21
- package/dist/execution/engine/engines/zcode/reader.d.ts +0 -21
- package/dist/execution/engine/engines/zcode/reader.js +0 -9
- package/src/__tests__/append-system-prompt-assembly.test.ts +0 -243
- package/src/__tests__/fr4-get-state-handshake.test.ts +0 -125
- package/src/__tests__/session-runner.test.ts +0 -69
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -191
- package/src/execution/__tests__/descendant-sweep-guards.test.ts +0 -220
- package/src/execution/__tests__/descendant-sweep.test.ts +0 -269
- package/src/execution/__tests__/engine-model-validation.test.ts +0 -741
- package/src/execution/__tests__/epipe-fallback.test.ts +0 -248
- package/src/execution/__tests__/execution-runtime-face.test.ts +0 -272
- package/src/execution/__tests__/get-state-handshake.test.ts +0 -127
- package/src/execution/__tests__/helpers/session-runner-mocks.ts +0 -113
- package/src/execution/__tests__/keep-alive-no-progress.test.ts +0 -280
- package/src/execution/__tests__/kill-all-escalation.test.ts +0 -196
- package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +0 -113
- package/src/execution/__tests__/output-collector.test.ts +0 -469
- package/src/execution/__tests__/pi-invocation.test.ts +0 -166
- package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -149
- package/src/execution/__tests__/rpc-mode.test.ts +0 -89
- package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +0 -387
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -277
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -254
- package/src/execution/__tests__/run-spawn-edges.test.ts +0 -1079
- package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
- package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
- package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
- package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -207
- package/src/execution/__tests__/service-kill-escalation.test.ts +0 -91
- package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +0 -110
- package/src/execution/__tests__/session-runner-close-prune.test.ts +0 -181
- package/src/execution/__tests__/session-runner-dispatch.test.ts +0 -489
- package/src/execution/__tests__/session-runner-epipe.test.ts +0 -179
- package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +0 -227
- package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +0 -290
- package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -352
- package/src/execution/__tests__/settled-watchdog.test.ts +0 -524
- package/src/execution/__tests__/spawn-args.test.ts +0 -446
- package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -192
- package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -208
- package/src/execution/__tests__/spawned-children.test.ts +0 -236
- package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
- package/src/execution/__tests__/stdin-writer.test.ts +0 -464
- package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -693
- package/src/execution/__tests__/temp-prompt.test.ts +0 -53
- package/src/execution/__tests__/timeout-integration.test.ts +0 -616
- package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
- package/src/execution/__tests__/turn-limiter.test.ts +0 -65
- package/src/execution/__tests__/ui-request-handler.test.ts +0 -205
- package/src/execution/__tests__/ui-request-queue.test.ts +0 -298
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -230
- package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
- package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +0 -149
- package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
- package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +0 -128
- package/src/execution/engine/__tests__/paths.test.ts +0 -39
- package/src/execution/engine/common/schema-emulation.ts +0 -189
- package/src/execution/engine/common/session-view-projection.ts +0 -51
- package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -615
- package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
- package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +0 -257
- package/src/execution/engine/engines/pi/argv-mirror.ts +0 -135
- package/src/execution/engine/engines/pi/get-state-handshake.ts +0 -179
- package/src/execution/engine/engines/pi/output-collector.ts +0 -317
- package/src/execution/engine/engines/pi/pi-engine.ts +0 -811
- package/src/execution/engine/engines/pi/pi-invocation.ts +0 -120
- package/src/execution/engine/engines/pi/reader.ts +0 -59
- package/src/execution/engine/engines/pi/registration.ts +0 -37
- package/src/execution/engine/engines/pi/session-runner.ts +0 -2840
- package/src/execution/engine/engines/pi/spawn-event-adapter.ts +0 -404
- package/src/execution/engine/engines/pi/stdin-writer.ts +0 -199
- package/src/execution/engine/engines/pi/temp-prompt.ts +0 -62
- package/src/execution/engine/engines/pi/turn-limiter.ts +0 -102
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +0 -301
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +0 -36
- package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +0 -321
- package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +0 -473
- package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -43
- package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -124
- package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
- package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -71
- package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +0 -247
- package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +0 -451
- package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +0 -792
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +0 -782
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +0 -168
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +0 -210
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +0 -353
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +0 -282
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +0 -372
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -145
- package/src/execution/engine/engines/zcode/appserver-launcher.ts +0 -167
- package/src/execution/engine/engines/zcode/connection.ts +0 -598
- package/src/execution/engine/engines/zcode/constants.ts +0 -176
- package/src/execution/engine/engines/zcode/golden-sample.ts +0 -47
- package/src/execution/engine/engines/zcode/parser.ts +0 -102
- package/src/execution/engine/engines/zcode/preparer.ts +0 -235
- package/src/execution/engine/engines/zcode/reader.ts +0 -381
- package/src/execution/engine/engines/zcode/registration.ts +0 -37
- package/src/execution/engine/engines/zcode/session-channel.ts +0 -968
- package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -1431
- package/src/execution/round-settlement.ts +0 -93
- package/src/execution/ui-request-queue.ts +0 -215
- package/src/shared/schema-env.ts +0 -44
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// src/execution/round-supervisor/reconcile-sweep.ts
|
|
2
|
+
//
|
|
3
|
+
// [W4] 注册对账 sweep——死亡窗口投递缺口的补发通道(发射点枚举第 5 处)。
|
|
4
|
+
//
|
|
5
|
+
// 设计权威源:docs/design/chat-domain-v1x-liveness-governance.md §3.2 D2「注册对账
|
|
6
|
+
// sweep」(R2 增补、R3 钉死判据与写法)。
|
|
7
|
+
//
|
|
8
|
+
// 问题:注销经进程内 pi.events appendEntry 落盘,进程死亡时发射源消失
|
|
9
|
+
// (notify-host getPi() 为 null),注销 entry 可能永久缺位 → goal 守卫幻 defer、
|
|
10
|
+
// pending_notifications 工具虚报活跃。
|
|
11
|
+
//
|
|
12
|
+
// 补发机制:对「本 session 的 register entry × 对应 record 状态 ∈ 终态集 ∪ record
|
|
13
|
+
// 已归档/不存在」的差集补发 unregister。**已归档**(archive 从内存移除、磁盘有
|
|
14
|
+
// finalized sidecar → 读侧重建 closed)与**不存在**(畸形条目对不上任何 record)
|
|
15
|
+
// 同视同终态——「查不到即补注销」判据兜底链才闭合。
|
|
16
|
+
//
|
|
17
|
+
// 写法钉死(照 base-tool-enhance/src/background/pending-reconcile.ts 先例):
|
|
18
|
+
// **直接 appendEntry 权威落盘 + 尽力 emit 同步内存视图**——不经 bus emit 作权威:
|
|
19
|
+
// pending-notifications 的 unregister listener 落盘条件是其内存 registry 该 id
|
|
20
|
+
// active,而两个 extension 的加载/派发顺序无保障,顺序反转时 emit 被静默吞。
|
|
21
|
+
// 差集消费方(goal 守卫)从持久化 entries 算差集,appendEntry 对守卫直接生效;
|
|
22
|
+
// emit 之外尽力同步 listener 内存视图(失败无害)。
|
|
23
|
+
//
|
|
24
|
+
// 触发时机:session reattach / session_start / 监督器启动(由 subagent-service 在
|
|
25
|
+
// initSession 链内调用)。与 session_start 的 registry rebuild 先后时序不作保证,
|
|
26
|
+
// 残余窗口由下次 session_start 收口(设计明示容忍)。
|
|
27
|
+
//
|
|
28
|
+
// 判据保守性([F2] 按类型分流收口):
|
|
29
|
+
// - type=subagent → record 差集对账(lookupRecordState);
|
|
30
|
+
// - type=workflow 及缺失/未知的畸形条目(normalizePendingType 归 workflow 的偏好)
|
|
31
|
+
// → workflow run 判据(lookupWorkflowRunState,生产装配查 WorkflowRun store 的
|
|
32
|
+
// run state 文件):终态 ∪ 文件不存在 → 补注销;running → 跳过;全部行损坏
|
|
33
|
+
// (读不出 ≠ 不存在)由判据侧保守按 running 处理(宁挂账不失明——误注销活跃
|
|
34
|
+
// workflow run 是事故方向)。deps 未注入该判据时维持旧保守跳过(向后兼容)。
|
|
35
|
+
// - type=bash → 无 record/store 可查(bash 注册随进程退出注销,进程死亡窗口的
|
|
36
|
+
// 丢失无补发通道)→ 保守跳过,显式偏差登记(impl-plan §5 #5):挂账方向代价 =
|
|
37
|
+
// 每孤儿 bash 注册 1 条静态虚报,无空转驱动源(goal 守卫读侧过滤已使子 session
|
|
38
|
+
// 不受污染,本 session 虚报 defer 由熔断限损)。
|
|
39
|
+
|
|
40
|
+
import * as fs from "node:fs";
|
|
41
|
+
|
|
42
|
+
import { getLogger } from "../../core/logger.ts";
|
|
43
|
+
|
|
44
|
+
const logger = getLogger("subagents");
|
|
45
|
+
|
|
46
|
+
/** sweep 的 record 状态判据(subagent-service 供 store 读侧:内存 getMutable ∪
|
|
47
|
+
* 磁盘 findLightById 两级)。 */
|
|
48
|
+
export type SupervisedRecordState =
|
|
49
|
+
/** 活跃(running-resumable,监督域或等待 upgrade)——不动。 */
|
|
50
|
+
| "active"
|
|
51
|
+
/** 终态(closed,含 closedReason——映射 pending reason 用)。 */
|
|
52
|
+
| { terminal: true; closedReason: string | undefined }
|
|
53
|
+
/** 已归档/不存在(视同终态,补注销)。 */
|
|
54
|
+
| "missing";
|
|
55
|
+
|
|
56
|
+
/** sweep 依赖注入(全部单测可替身)。 */
|
|
57
|
+
export interface ReconcileSweepDeps {
|
|
58
|
+
/** 主 session 文件(差集输入源)。undefined = 无法读取,本轮空跑。 */
|
|
59
|
+
sessionFile: string | undefined;
|
|
60
|
+
/** record 状态判据(见 SupervisedRecordState)。 */
|
|
61
|
+
lookupRecordState: (id: string) => SupervisedRecordState;
|
|
62
|
+
/**
|
|
63
|
+
* [F2] workflow run 状态判据(type=workflow 及畸形条目的收口依据)。生产装配查
|
|
64
|
+
* WorkflowRun store(service-binding → FileRunStore.findStateByIdSync)。
|
|
65
|
+
* 缺省(未注入)= workflow/畸形条目无收口通道,保守跳过(skippedNonSubagent)。
|
|
66
|
+
*/
|
|
67
|
+
lookupWorkflowRunState?: (runId: string) => SupervisedRecordState;
|
|
68
|
+
/** 权威写(pi.appendEntry)。缺失(dispose 后)= 本轮只判不写。 */
|
|
69
|
+
appendEntry?: (customType: string, data: unknown) => void;
|
|
70
|
+
/** 尽力 emit(pi.events.emit;listener 缺失/抛错无害)。 */
|
|
71
|
+
emit?: (channel: string, data: unknown) => void;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** sweep 结果(日志 + 测试断言面)。 */
|
|
75
|
+
export interface ReconcileSweepResult {
|
|
76
|
+
/** 补发 unregister 的注册 id。 */
|
|
77
|
+
reconciled: string[];
|
|
78
|
+
/** 差集内但判据为活跃(record/run running)而保守跳过的注册 id。 */
|
|
79
|
+
skippedActive: string[];
|
|
80
|
+
/** 差集内无收口通道而保守跳过的注册 id(bash;或 deps 未注入 workflow 判据时
|
|
81
|
+
* 的 workflow/未知类型——显式偏差面,见文件头注 bash 段)。 */
|
|
82
|
+
skippedNonSubagent: string[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 执行一次对账 sweep。同步(fs 读 + appendEntry 均同步,session_start 链内毫秒级)。
|
|
87
|
+
* 幂等:重复执行时已补发的 id 有 unregister entry 抵消,差集不再出现。
|
|
88
|
+
*/
|
|
89
|
+
export function runReconcileSweep(deps: ReconcileSweepDeps): ReconcileSweepResult {
|
|
90
|
+
const result: ReconcileSweepResult = {
|
|
91
|
+
reconciled: [],
|
|
92
|
+
skippedActive: [],
|
|
93
|
+
skippedNonSubagent: [],
|
|
94
|
+
};
|
|
95
|
+
if (!deps.sessionFile) return result;
|
|
96
|
+
|
|
97
|
+
const activeRegisters = collectActiveRegisterEntries(deps.sessionFile);
|
|
98
|
+
for (const entry of activeRegisters) {
|
|
99
|
+
sweepSingleRegister(deps, entry, result);
|
|
100
|
+
}
|
|
101
|
+
if (result.reconciled.length > 0) {
|
|
102
|
+
logger.warn(
|
|
103
|
+
`[subagents] reconcile sweep re-emitted ${result.reconciled.length} unregister(s) for terminal/missing records: ${result.reconciled.join(",")}`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 差集单条对账(保守性分流 [F2]):按注册类型选收口判据——subagent 走 record 差集;
|
|
111
|
+
* workflow/畸形(normalizePendingType 归 workflow 偏好)走 workflow run 判据;bash 无
|
|
112
|
+
* record/store 可查,保守跳过(显式偏差,头注 bash 段)。
|
|
113
|
+
*/
|
|
114
|
+
function sweepSingleRegister(
|
|
115
|
+
deps: ReconcileSweepDeps,
|
|
116
|
+
entry: ActiveRegisterEntry,
|
|
117
|
+
result: ReconcileSweepResult,
|
|
118
|
+
): void {
|
|
119
|
+
const id = entry.id;
|
|
120
|
+
if (entry.type === "bash") {
|
|
121
|
+
result.skippedNonSubagent.push(id);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const state = entry.type === "subagent"
|
|
125
|
+
? deps.lookupRecordState(id)
|
|
126
|
+
: deps.lookupWorkflowRunState?.(id);
|
|
127
|
+
if (state === undefined) {
|
|
128
|
+
// deps 未注入 workflow 判据:无收口通道,保守跳过(向后兼容——判据注入面
|
|
129
|
+
// 缺席 ≠ 条目可注销)。
|
|
130
|
+
result.skippedNonSubagent.push(id);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (state === "active") {
|
|
134
|
+
result.skippedActive.push(id);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
reemitUnregister(deps, id, state, result);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** 补发单条 unregister:appendEntry 权威落盘 + 尽力 emit 同步内存视图(均失败保守处理)。 */
|
|
141
|
+
function reemitUnregister(
|
|
142
|
+
deps: ReconcileSweepDeps,
|
|
143
|
+
id: string,
|
|
144
|
+
state: Exclude<SupervisedRecordState, "active">,
|
|
145
|
+
result: ReconcileSweepResult,
|
|
146
|
+
): void {
|
|
147
|
+
const reason =
|
|
148
|
+
state === "missing" ? "expired" : closedReasonToPendingReason(state.closedReason);
|
|
149
|
+
// 权威路径:直接 appendEntry 落盘(不经 bus emit 作权威——先例论证见文件头注)。
|
|
150
|
+
try {
|
|
151
|
+
deps.appendEntry?.("pending:unregister", { id, reason, status: reason });
|
|
152
|
+
} catch (err) {
|
|
153
|
+
// 落盘失败:差集残留交下次 sweep(session_start / 监督器启动)重试。
|
|
154
|
+
logger.warn(
|
|
155
|
+
`[subagents] reconcile sweep appendEntry failed for ${id} (retry on next sweep): ${
|
|
156
|
+
err instanceof Error ? err.message : String(err)
|
|
157
|
+
}`,
|
|
158
|
+
);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// 尽力补 emit(listener 就绪时同步 pending 内存视图,缩短工具投影不一致窗口)。
|
|
162
|
+
try {
|
|
163
|
+
deps.emit?.("pending:unregister", { id, reason });
|
|
164
|
+
} catch (err) {
|
|
165
|
+
// 尽力语义:emit 失败无害(appendEntry 已是权威路径),debug 留痕供排查。
|
|
166
|
+
logger.debug(
|
|
167
|
+
`[subagents] reconcile sweep best-effort emit failed (harmless) for ${id}: ${
|
|
168
|
+
err instanceof Error ? err.message : String(err)
|
|
169
|
+
}`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
result.reconciled.push(id);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** closedReason → pending reason(未知值交 pending-notifications mapReasonToStatus
|
|
176
|
+
* 的 default=completed 兜底——诚实且对差集消费方无行为影响,reason 不参与计数)。 */
|
|
177
|
+
function closedReasonToPendingReason(closedReason: string | undefined): string {
|
|
178
|
+
return closedReason ?? "completed";
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ── 差集读取(独立轻量实现,不复用 session-pending 的 per-file 增量游标——sweep
|
|
182
|
+
// 是低频全量操作,与后代判定的游标记账解耦,避免交错消费 offset)──
|
|
183
|
+
|
|
184
|
+
interface ActiveRegisterEntry {
|
|
185
|
+
id: string;
|
|
186
|
+
type: string | undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** entry.data 的最小形状(对齐 pending-notifications RegisterEntryData)。 */
|
|
190
|
+
interface RegisterDataLike {
|
|
191
|
+
id?: unknown;
|
|
192
|
+
type?: unknown;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function isRegisterDataLike(v: unknown): v is RegisterDataLike {
|
|
196
|
+
return typeof v === "object" && v !== null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 读主 session 文件的 pending:register − pending:unregister 差集(register 顺序
|
|
201
|
+
* 保留;同 id 重 register 去重)。文件不可读(首条 assistant 前未 flush / 被删)
|
|
202
|
+
* 返回空集——sweep 空跑,下次触发点重试。坏行跳过(append 中途崩溃的截断行)。
|
|
203
|
+
*/
|
|
204
|
+
function collectActiveRegisterEntries(sessionFile: string): ActiveRegisterEntry[] {
|
|
205
|
+
let content: string;
|
|
206
|
+
try {
|
|
207
|
+
content = fs.readFileSync(sessionFile, "utf-8");
|
|
208
|
+
} catch {
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
const unregistered = new Set<string>();
|
|
212
|
+
const registers = new Map<string, string | undefined>();
|
|
213
|
+
for (const line of content.split("\n")) {
|
|
214
|
+
// 快速路径(对齐 session-pending S-4 按值匹配):只解析含 pending 值的行。
|
|
215
|
+
if (!line.includes('"pending:register"') && !line.includes('"pending:unregister"')) continue;
|
|
216
|
+
let parsed: unknown;
|
|
217
|
+
try {
|
|
218
|
+
parsed = JSON.parse(line);
|
|
219
|
+
} catch {
|
|
220
|
+
continue; // 坏行跳过
|
|
221
|
+
}
|
|
222
|
+
if (typeof parsed !== "object" || parsed === null) continue;
|
|
223
|
+
const entry = parsed as { customType?: unknown; data?: unknown };
|
|
224
|
+
if (!isRegisterDataLike(entry.data)) continue;
|
|
225
|
+
const id = entry.data.id;
|
|
226
|
+
if (typeof id !== "string") continue;
|
|
227
|
+
if (entry.customType === "pending:register") {
|
|
228
|
+
registers.set(id, typeof entry.data.type === "string" ? entry.data.type : undefined);
|
|
229
|
+
} else if (entry.customType === "pending:unregister") {
|
|
230
|
+
unregistered.add(id);
|
|
231
|
+
registers.delete(id);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return [...registers.entries()].map(([id, type]) => ({ id, type }));
|
|
235
|
+
}
|