@zhushanwen/subagent-core 0.5.1 → 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-Dv4QhSJ_.d.cts → engine-discovery-scan-ocpM8FmI.d.cts} +835 -668
- package/dist/{types-Dv4QhSJ_.d.ts → engine-discovery-scan-ocpM8FmI.d.ts} +835 -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 +14123 -15467
- package/dist/index.d.cts +1179 -1540
- package/dist/index.d.ts +1179 -1540
- package/dist/index.js +7694 -10986
- package/dist.bundle/index.cjs +33485 -0
- 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__/agent-registry.test.ts +1 -1
- package/src/execution/__tests__/alive-store.test.ts +1 -1
- 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-budget.test.ts +291 -0
- package/src/execution/__tests__/collect-coordinator-service.test.ts +316 -0
- package/src/execution/__tests__/collect-coordinator.test.ts +371 -0
- package/src/execution/__tests__/collect-mixed-dispatch.test.ts +229 -0
- package/src/execution/__tests__/config-collect-sync.test.ts +120 -0
- package/src/execution/__tests__/config.test.ts +1 -1
- 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 +21 -34
- package/src/execution/__tests__/finalized-marker.test.ts +1 -1
- package/src/execution/__tests__/gc-timer.test.ts +8 -23
- 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__/manifest-store-tmp-recovery.test.ts +1 -1
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +5 -2
- package/src/execution/__tests__/notify-batch.test.ts +500 -0
- package/src/execution/__tests__/notify-ledger.test.ts +27 -0
- package/src/execution/__tests__/reconcile-sweep.test.ts +200 -0
- package/src/execution/__tests__/record-entry-collect.test.ts +102 -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__/relay-env.test.ts +12 -1
- package/src/execution/__tests__/round-supervisor.test.ts +293 -0
- package/src/execution/__tests__/session-file-gc.test.ts +1 -1
- package/src/execution/__tests__/session-pending.test.ts +119 -17
- package/src/execution/__tests__/start-collect-guard.test.ts +255 -0
- package/src/execution/__tests__/stream-sink-retirement.test.ts +10 -10
- package/src/execution/__tests__/subagent-actions-core.test.ts +6 -0
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +14 -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 +1102 -0
- package/src/execution/__tests__/tombstone-store.test.ts +1 -1
- package/src/execution/__tests__/workflow-state-root.test.ts +232 -0
- package/src/execution/__tests__/worktree-git-ops.test.ts +1 -1
- package/src/execution/__tests__/worktree-reconcile-aging.test.ts +2 -2
- package/src/execution/__tests__/worktree-reconcile.integration.test.ts +1 -1
- package/src/execution/__tests__/worktree-registry.test.ts +1 -1
- package/src/execution/agent-registry.ts +6 -2
- package/src/execution/collect-coordinator.ts +200 -0
- package/src/execution/config.ts +77 -5
- 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/event-journal.test.ts +1 -1
- 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/pool-manager.test.ts +2 -2
- 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 +82 -55
- 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 +8 -3
- 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/execution-record.ts +7 -0
- package/src/execution/finalize-record.ts +40 -11
- 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/notifier.ts +234 -25
- package/src/execution/notify-host.ts +21 -1
- package/src/execution/record-entry.ts +16 -0
- package/src/execution/record-store.ts +189 -31
- 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-actions-core.ts +62 -6
- package/src/execution/subagent-service.ts +1161 -406
- package/src/execution/subprocess-agent-runner.ts +16 -8
- package/src/execution/sync-rebuild.ts +87 -0
- package/src/execution/types.ts +104 -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__/config-loader.test.ts +1 -1
- package/src/orchestration/__tests__/execute-agent-call.test.ts +1 -1
- package/src/orchestration/__tests__/file-run-store-prune.test.ts +1 -1
- package/src/orchestration/__tests__/file-run-store-throttle.test.ts +1 -1
- package/src/orchestration/__tests__/review-fix-loop-scriptpath-failfast.test.ts +1 -1
- package/src/orchestration/__tests__/script-generate.test.ts +5 -5
- package/src/orchestration/__tests__/skill-discovery.test.ts +2 -2
- package/src/orchestration/__tests__/workflow-files.test.ts +10 -10
- package/src/orchestration/__tests__/workflow-script-registry-impl.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/__tests__/atomic-write.test.ts +1 -1
- package/src/shared/__tests__/resource-discovery-host-roots.test.ts +5 -5
- 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 -134
- 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
|
@@ -8,7 +8,7 @@ import { displayAgentName } from "../shared/agent-ref.ts";
|
|
|
8
8
|
import { snapshot } from "./execution-record.ts";
|
|
9
9
|
import { hasIdleTimer } from "./lifecycle-manager.ts";
|
|
10
10
|
import { hasLiveProcessHandle, isIdle, isResumable } from "./lifecycle-predicates.ts";
|
|
11
|
-
import type { BgNotifier, NotifierHost } from "./notifier.ts";
|
|
11
|
+
import type { BgNotifier, BatchBudgetParams, NotifierHost } from "./notifier.ts";
|
|
12
12
|
import { createNotifier } from "./notifier.ts";
|
|
13
13
|
import type { BgNotifyRecord } from "./notifier.ts";
|
|
14
14
|
import type { ExecutionRecord, RecordSnapshot } from "./types.ts";
|
|
@@ -50,6 +50,14 @@ export interface NotifyHost {
|
|
|
50
50
|
emitPendingRegister(id: string, name?: string): void;
|
|
51
51
|
/** pending-notifications 注销(原模块函数 emitPendingUnregister)。 */
|
|
52
52
|
emitPendingUnregister(id: string, reason: string): void;
|
|
53
|
+
/** [sync-collect U2 合并] record → BgNotifyRecord 映射——collectCoordinator 的
|
|
54
|
+
* toNotifyRecord/notifyAsync 依赖注入消费(守卫放行逻辑单一权威在本文件)。 */
|
|
55
|
+
toNotifyRecord(record: ExecutionRecord): BgNotifyRecord | undefined;
|
|
56
|
+
/** [sync-collect 合并] 单条直发——collectCoordinator notifyAsync 与 E9 dispose
|
|
57
|
+
* 转换路径消费(已越过 toNotifyRecord 守卫的成品通知)。 */
|
|
58
|
+
notify(record: BgNotifyRecord): void;
|
|
59
|
+
/** [sync-collect 合并] sync 批投递——collectCoordinator flushBatch 与 E1 补发消费。 */
|
|
60
|
+
notifyBatch(records: readonly BgNotifyRecord[], budget?: BatchBudgetParams): boolean;
|
|
53
61
|
/** dispose 的逆操作(initSession 复活,原 notifier.revive 委托)。 */
|
|
54
62
|
revive(): void;
|
|
55
63
|
/** dispose 前冲刷待发通知(原 notifier.flushPendingNotifications 委托)。 */
|
|
@@ -197,6 +205,18 @@ export function createNotifyHost(deps: NotifyHostDeps): NotifyHost {
|
|
|
197
205
|
emitPendingUnregister(deps.getPi(), id, reason);
|
|
198
206
|
},
|
|
199
207
|
|
|
208
|
+
toNotifyRecord(record: ExecutionRecord): BgNotifyRecord | undefined {
|
|
209
|
+
return toNotifyRecord(record);
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
notify(record: BgNotifyRecord): void {
|
|
213
|
+
notifier.notify(record);
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
notifyBatch(records: readonly BgNotifyRecord[], budget?: BatchBudgetParams): boolean {
|
|
217
|
+
return notifier.notifyBatch(records, budget);
|
|
218
|
+
},
|
|
219
|
+
|
|
200
220
|
revive(): void {
|
|
201
221
|
notifier.revive();
|
|
202
222
|
},
|
|
@@ -97,6 +97,18 @@ export interface SubagentRecordEntryData {
|
|
|
97
97
|
* 透传不枚举内部键(zcode = { sessionId, dbPath });缺省 = pi(存量 entry 零迁移)。
|
|
98
98
|
*/
|
|
99
99
|
engineHandle?: { sessionRef: Record<string, string>; journalPath?: string; poolKey: string };
|
|
100
|
+
/**
|
|
101
|
+
* 同步收集模式标记(subagent-sync-collect 设计 §3.1.3,U1 foundation)。
|
|
102
|
+
* undefined = async(缺省语义,旧 entry 零迁移——undefined 经 JSON.stringify 自然缺省)。
|
|
103
|
+
* 消费方:U5 rebuildEntryRecord 投影扩展 + E1 重建扫描。
|
|
104
|
+
*/
|
|
105
|
+
collectMode?: "sync";
|
|
106
|
+
/**
|
|
107
|
+
* 离开批终局标记(subagent-sync-collect 设计 §3.1.3,U1 foundation)。两出口统一
|
|
108
|
+
* 落标(批闭合 flush / E9 dispose 转换,均 appendEntry 持久化)。undefined =
|
|
109
|
+
* 未离开批 / 旧 entry 零迁移。消费方:U5 E1 重建扫描只收无标记成员(防双重通知)。
|
|
110
|
+
*/
|
|
111
|
+
batchFinalized?: boolean;
|
|
100
112
|
}
|
|
101
113
|
|
|
102
114
|
/** SubagentRecord → 自描述 entry data(快照投影,不 mutate 源)。
|
|
@@ -134,5 +146,9 @@ export function toSubagentRecordEntry(record: SubagentRecord): SubagentRecordEnt
|
|
|
134
146
|
engine: record.engine,
|
|
135
147
|
engineFallback: record.engineFallback,
|
|
136
148
|
engineHandle: record.engineHandle,
|
|
149
|
+
// 同步收集两字段(U1 foundation):undefined 经 JSON.stringify 自然缺省,
|
|
150
|
+
// 旧记录/旧 entry 序列化产物字节不变(零迁移)。
|
|
151
|
+
collectMode: record.collectMode,
|
|
152
|
+
batchFinalized: record.batchFinalized,
|
|
137
153
|
};
|
|
138
154
|
}
|
|
@@ -259,40 +259,103 @@ function collectLastRecordEntries(content: string): Map<string, Record<string, u
|
|
|
259
259
|
return lastById;
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
/** entry data 字段的安全 string 读取(非 string → undefined)。 */
|
|
263
|
+
function entryStr(d: Record<string, unknown>, k: string): string | undefined {
|
|
264
|
+
return typeof d[k] === "string" ? (d[k] as string) : undefined;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** entry data 字段的安全 number 读取(非 number → undefined)。 */
|
|
268
|
+
function entryNum(d: Record<string, unknown>, k: string): number | undefined {
|
|
269
|
+
return typeof d[k] === "number" ? (d[k] as number) : undefined;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** 终态域投影:status 只认 "closed" 字面量(其余含缺省 → "running",旧调用方行为不变);
|
|
273
|
+
* closedReason 经枚举守卫(非法/缺省 → undefined)。 */
|
|
274
|
+
function readEntryTerminalFields(
|
|
275
|
+
d: Record<string, unknown>,
|
|
276
|
+
): Pick<SubagentRecord, "status" | "closedReason"> {
|
|
277
|
+
const closedReason = entryStr(d, "closedReason");
|
|
278
|
+
return {
|
|
279
|
+
status: d.status === "closed" ? "closed" : "running",
|
|
280
|
+
closedReason: isValidClosedReason(closedReason) ? closedReason : undefined,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** 批收集域投影(U5 E1):仅显式字面量收敛,缺省 undefined(JSON 序列化自然缺省)。 */
|
|
285
|
+
function readEntryBatchFields(
|
|
286
|
+
d: Record<string, unknown>,
|
|
287
|
+
): Pick<SubagentRecord, "collectMode" | "batchFinalized" | "resumable"> {
|
|
288
|
+
return {
|
|
289
|
+
collectMode: d.collectMode === "sync" ? "sync" : undefined,
|
|
290
|
+
batchFinalized: d.batchFinalized === true ? true : undefined,
|
|
291
|
+
resumable: d.resumable === true ? true : undefined,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** engine 域投影:engineFallback/engineHandle 经运行时 guard(未知 JSON 不裸收)。 */
|
|
296
|
+
function readEntryEngineFields(
|
|
297
|
+
d: Record<string, unknown>,
|
|
298
|
+
): Pick<SubagentRecord, "engine" | "engineFallback" | "engineHandle"> {
|
|
299
|
+
return {
|
|
300
|
+
engine: entryStr(d, "engine"),
|
|
301
|
+
engineFallback: isEngineFallbackShape(d.engineFallback) ? d.engineFallback : undefined,
|
|
302
|
+
engineHandle: isEngineHandleShape(d.engineHandle) ? d.engineHandle : undefined,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
262
306
|
/** entry data 即 SubagentRecord v1 快照——带运行时 guard 重建(taste/no-unsafe-cast)。
|
|
263
|
-
* 损坏 entry(agent/task/startedAt 任一缺失)返回 null,由调用方跳过。
|
|
307
|
+
* 损坏 entry(agent/task/startedAt 任一缺失)返回 null,由调用方跳过。
|
|
308
|
+
* [U5 E1] 投影白名单扩展(设计 §3.1.3「标记读取通路」):collectMode/batchFinalized
|
|
309
|
+
* + 终态五字段 status/endedAt/closedReason/result/error——原实现硬编码
|
|
310
|
+
* status:"running" 且不投影终态,E1 重建成员恒被视为 running,「全员终态→补发」
|
|
311
|
+
* 判定永假、补发内容缺失,整条补发路径成死代码。status 守卫只认 "closed" 字面量
|
|
312
|
+
* (其余含缺省 → "running",旧调用方 recoverEntryOnlyOrphans 行为不变——其候选
|
|
313
|
+
* 守卫已滤非 running 末条);closedReason 经 isValidClosedReason 枚举守卫。
|
|
314
|
+
* [v2 D3] 再补 resumable/sessionFile 两投影:成功成员崩溃时末条恒为轮终
|
|
315
|
+
* running+resumable entry(SP-5 有意语义),不投影 resumable 则 E1 无法与协调器
|
|
316
|
+
* hasRunningSync 同构豁免(§2.3 断链 3);sessionFile 原硬编码 undefined,导致
|
|
317
|
+
* E1 落标路径重建快照丢失反查索引锚(断链 1 前置依赖)。recoverEntryOnlyOrphans
|
|
318
|
+
* 的候选判定(isEntryOrphanCandidate)只认 status==="running",两新字段不参与
|
|
319
|
+
* 判定(P-rebuild 探针守卫面)。
|
|
320
|
+
* [E1 恢复批语义修复] 再补 patchFile 投影:entry data 携带该字段
|
|
321
|
+
* (toSubagentRecordEntry 落盘含 patchFile)但原投影丢弃 → E1 补发记录丢失
|
|
322
|
+
* worktree patch 的 git-apply 回收指针(正常 flush 路径经 toNotifyRecord 特意
|
|
323
|
+
* 携带,notify-host.ts patchFile 透传)。undefined 经 JSON.stringify 自然缺省,
|
|
324
|
+
* 无 patchFile 的存量 entry 序列化字节不变(落标出口经 toSubagentRecordEntry
|
|
325
|
+
* 按名重投影,重建对象字段顺序不影响序列化字节形态)。
|
|
326
|
+
* 字段顺序 = 对象字面量原序(终态/批收集/engine 域以 spread 在原位置展开),
|
|
327
|
+
* entry 序列化字节形态不变。 */
|
|
264
328
|
function rebuildEntryRecord(id: string, d: Record<string, unknown>): SubagentRecord | null {
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
const
|
|
268
|
-
const task = str("task");
|
|
269
|
-
const startedAt = num("startedAt");
|
|
329
|
+
const agent = entryStr(d, "agent");
|
|
330
|
+
const task = entryStr(d, "task");
|
|
331
|
+
const startedAt = entryNum(d, "startedAt");
|
|
270
332
|
if (agent === undefined || task === undefined || startedAt === undefined) return null; // 损坏 entry:跳过
|
|
271
333
|
return {
|
|
272
334
|
id,
|
|
273
335
|
agent,
|
|
274
336
|
task,
|
|
275
|
-
slug:
|
|
276
|
-
|
|
337
|
+
slug: entryStr(d, "slug") ?? "",
|
|
338
|
+
...readEntryTerminalFields(d),
|
|
277
339
|
mode: "background",
|
|
278
340
|
startedAt,
|
|
279
|
-
rootSessionId:
|
|
280
|
-
parentRecordId:
|
|
281
|
-
depth:
|
|
282
|
-
endedAt:
|
|
283
|
-
turns:
|
|
284
|
-
totalTokens:
|
|
285
|
-
model:
|
|
286
|
-
thinkingLevel:
|
|
341
|
+
rootSessionId: entryStr(d, "rootSessionId"),
|
|
342
|
+
parentRecordId: entryStr(d, "parentRecordId"),
|
|
343
|
+
depth: entryNum(d, "depth") ?? 0,
|
|
344
|
+
endedAt: entryNum(d, "endedAt"),
|
|
345
|
+
turns: entryNum(d, "turns") ?? 0,
|
|
346
|
+
totalTokens: entryNum(d, "totalTokens") ?? 0,
|
|
347
|
+
model: entryStr(d, "model") ?? "",
|
|
348
|
+
thinkingLevel: entryStr(d, "thinkingLevel"),
|
|
287
349
|
eventLog: [],
|
|
288
350
|
displayItems: [],
|
|
289
|
-
|
|
351
|
+
result: entryStr(d, "result"),
|
|
352
|
+
error: entryStr(d, "error"),
|
|
353
|
+
sessionFile: entryStr(d, "sessionFile"),
|
|
354
|
+
patchFile: entryStr(d, "patchFile"),
|
|
290
355
|
chatMode: d.chatMode === true,
|
|
291
|
-
round:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
isEngineFallbackShape(d.engineFallback) ? d.engineFallback : undefined,
|
|
295
|
-
engineHandle: isEngineHandleShape(d.engineHandle) ? d.engineHandle : undefined,
|
|
356
|
+
round: entryNum(d, "round"),
|
|
357
|
+
...readEntryEngineFields(d),
|
|
358
|
+
...readEntryBatchFields(d),
|
|
296
359
|
};
|
|
297
360
|
}
|
|
298
361
|
|
|
@@ -645,35 +708,59 @@ export class RecordStore {
|
|
|
645
708
|
* - 文件不可读(IO 错误,可能暂时)→ 不判终态,落 resumable entry(防御性路径,
|
|
646
709
|
* IO 恢复后重开可重判)。
|
|
647
710
|
*
|
|
711
|
+
* [v2 D3] mainSessionFile = 覆写 merge 数据源(主 session 每 id 末条 entry,与 E1
|
|
712
|
+
* 的 scanLastRecordEntries 同款通路):崩溃前的批域标记(collectMode/batchFinalized)
|
|
713
|
+
* 与轮终 result/model 只活在主文件 entry——重建矩阵(buildRecord)的数据源
|
|
714
|
+
* (sidecar/子文件 identity)不含它们,覆写前不 merge 就会被抹掉(v2 §2.2 断链 2:
|
|
715
|
+
* E1 候选集恒空的真根因)。缺省(undefined)时 merge 无源,行为与旧版一致。
|
|
716
|
+
* 参数为追加式第二参(rootSessionFilter 保持首参):既有调用面只传过滤参。
|
|
717
|
+
*
|
|
648
718
|
* 防重:orphanJudged 实例级缓存(resumable 形态无 sidecar 锚,同进程重复调用跳过;
|
|
649
719
|
* 终态形态双重防护 = sidecar + 缓存)。调用方:index.ts session_start 恢复段(一次)。
|
|
650
720
|
*/
|
|
651
|
-
recoverOrphanRecords(rootSessionFilter?: string): void {
|
|
721
|
+
recoverOrphanRecords(rootSessionFilter?: string, mainSessionFile?: string): void {
|
|
722
|
+
const lastById = new Map(this.scanLastRecordEntries(mainSessionFile).map((r) => [r.id, r]));
|
|
652
723
|
for (const rec of this.reconstructAll(rootSessionFilter)) {
|
|
653
724
|
// 分支 4 命中集 = running 且无活进程实例(分支 3 带 externalInstance,分支 1/2 已 closed)。
|
|
654
725
|
if (rec.status !== "running" || rec.externalInstance !== undefined) continue;
|
|
655
726
|
if (this.orphanJudged.has(rec.id)) continue;
|
|
656
727
|
this.orphanJudged.add(rec.id);
|
|
657
|
-
this.finalizeOrphanRecord(rec);
|
|
728
|
+
this.finalizeOrphanRecord(rec, lastById.get(rec.id));
|
|
658
729
|
}
|
|
659
730
|
}
|
|
660
731
|
|
|
661
732
|
/**
|
|
662
733
|
* 单孤儿 record 的终态判定与落 entry(residual-fixes §5.2 三判据 + chat 分流)。
|
|
663
734
|
* 防重锚(orphanJudged 标记)已由调用方完成。
|
|
735
|
+
*
|
|
736
|
+
* [v2 D3] 覆写前 merge(lastEntry = 主 session 同 id 末条 entry 重建,调用方构建):
|
|
737
|
+
* 覆写是状态迁移不是信息重建,迁移不应丢末条既有信息。三个落 entry 分支(chatMode
|
|
738
|
+
* 分流 / IO 保守 / 终态覆写)统一基于 merge 后的 rec,同款口径。
|
|
664
739
|
*/
|
|
665
|
-
private finalizeOrphanRecord(rec: SubagentRecord): void {
|
|
666
|
-
|
|
740
|
+
private finalizeOrphanRecord(rec: SubagentRecord, lastEntry?: SubagentRecord): void {
|
|
741
|
+
// 仅补 undefined/空值字段、不覆盖已有值——覆写自带的 status/closedReason/endedAt/
|
|
742
|
+
// error 不在 merge 字段集,天然不受影响。批域字段(collectMode/batchFinalized)对
|
|
743
|
+
// 非 sync 成员恒 no-op(末条 entry collectMode undefined → 无值可补);result/model
|
|
744
|
+
// 的修补对 async/chat 成员同样生效——拉齐 light 重建丢 result/model 与 full 重建的
|
|
745
|
+
// 既有形态不一致(v2 D3 影响面诚实口径),不触碰任何通知文案(golden 不锁 entry 字节)。
|
|
746
|
+
const rec0 = lastEntry === undefined ? rec : RecordStore.mergeOrphanLastEntry(rec, lastEntry);
|
|
747
|
+
// [W4 boot 分区 · 裁决表行 3] 重认领保留分支的判据 = resumable 且**无完成产出**:
|
|
748
|
+
// 非 chatMode 的 resumable=true 且 result 有值是 SP-5 one-shot 完成态(任务已完成,
|
|
749
|
+
// 直断 closed/gc 无损);resumable=true 且 result 缺失是「监督器死亡纳管态」(W4:
|
|
750
|
+
// 引擎死亡接管后宿主重启)——保留 running 交 round-supervisor boot 重认领继续
|
|
751
|
+
// 管辖(注册存续 process 档),误判 closed 会制造「指向已终态 record 的残留注册」
|
|
752
|
+
// 并损失 resume 可能。
|
|
753
|
+
if (rec0.chatMode === true || (rec0.resumable === true && rec0.result === undefined)) {
|
|
667
754
|
// chat 会话跨重启等续聊:保留 running(可续聊),仅落执行态信号。
|
|
668
|
-
this.reportSubagentRecord({ ...
|
|
755
|
+
this.reportSubagentRecord({ ...rec0, resumable: true });
|
|
669
756
|
return;
|
|
670
757
|
}
|
|
671
|
-
const sessionFile =
|
|
758
|
+
const sessionFile = rec0.sessionFile;
|
|
672
759
|
if (sessionFile === undefined) return; // 无子文件锚(目录扫描源不可达,防御)
|
|
673
760
|
const lastLine = readLastJsonlLine(sessionFile);
|
|
674
761
|
if (!lastLine.ok) {
|
|
675
762
|
// IO 错误可能暂时——判终态不可逆,保守落 resumable 等重开重判。
|
|
676
|
-
this.reportSubagentRecord({ ...
|
|
763
|
+
this.reportSubagentRecord({ ...rec0, resumable: true });
|
|
677
764
|
return;
|
|
678
765
|
}
|
|
679
766
|
let parseOk = false;
|
|
@@ -688,15 +775,55 @@ export class RecordStore {
|
|
|
688
775
|
// 真实 reason 同层——否则无 reason sidecar 在磁盘重建时被兜底为 disconnected,
|
|
689
776
|
// 把正常完成的记录误标成断联。
|
|
690
777
|
writeFinalized(sessionFile, "gc");
|
|
778
|
+
// [F3 boot 直断语义,设计表 3 行 2] 走到本分支的 record 分两类:
|
|
779
|
+
// - resumable=true(上方分流保证此时 result 有值)= SP-5 one-shot 完成态——任务
|
|
780
|
+
// 真实完成,直断 closed/gc 无 error,投影 completed 不变;
|
|
781
|
+
// - 其余 = in-flight(重启前在途、无 resumable 信号)——宿主重启中断了在途任务,
|
|
782
|
+
// 投影不得是 completed(事故环 3:异常中断被谎报完成,违反 G3)。error 载体经
|
|
783
|
+
// deriveOutcome("gc", error) = "failed"(execution-record.ts 唯一权威派生)
|
|
784
|
+
// 投影 failed,文案供 GUI/主 agent 明确「任务因宿主重启中断」;ClosedReason
|
|
785
|
+
// 枚举不扩展(sidecar/entry 面最小改动,"gc" 由 error 载体补足失败语义)。
|
|
786
|
+
const inFlightAbortedError =
|
|
787
|
+
rec0.resumable === true
|
|
788
|
+
? undefined
|
|
789
|
+
: "orphan recovery: task aborted by host restart (in-flight at shutdown; session context lost" +
|
|
790
|
+
(parseOk ? "" : "; truncated last line") + ")";
|
|
691
791
|
this.reportSubagentRecord({
|
|
692
|
-
...
|
|
792
|
+
...rec0,
|
|
693
793
|
status: "closed",
|
|
694
794
|
closedReason: "gc",
|
|
695
795
|
endedAt: Date.now(),
|
|
696
|
-
...(
|
|
796
|
+
...(inFlightAbortedError !== undefined
|
|
797
|
+
? { error: inFlightAbortedError }
|
|
798
|
+
: parseOk
|
|
799
|
+
? {}
|
|
800
|
+
: { error: "orphan recovery: subagent session ended abnormally (truncated last line)" }),
|
|
697
801
|
});
|
|
698
802
|
}
|
|
699
803
|
|
|
804
|
+
/** [v2 D3] 孤儿覆写 merge 字段集:末条 entry 的批域标记 + 轮终正文/模型,仅补 rec 侧
|
|
805
|
+
* undefined/空值(model 的空值形态是 ""——light 重建无 model_change entry 时起步
|
|
806
|
+
* 空串),不覆盖已有值。merge 后写 entry 经 reportSubagentRecord →
|
|
807
|
+
* toSubagentRecordEntry 序列化,undefined 字段自然缺省(不引入显式 null)。 */
|
|
808
|
+
private static mergeOrphanLastEntry(rec: SubagentRecord, last: SubagentRecord): SubagentRecord {
|
|
809
|
+
const pickStr = (cur: string | undefined, src: string | undefined): string | undefined =>
|
|
810
|
+
cur !== undefined && cur !== "" ? cur : src;
|
|
811
|
+
return {
|
|
812
|
+
...rec,
|
|
813
|
+
collectMode: rec.collectMode ?? last.collectMode,
|
|
814
|
+
batchFinalized: rec.batchFinalized ?? last.batchFinalized,
|
|
815
|
+
result: pickStr(rec.result, last.result),
|
|
816
|
+
// 类型收尾:两侧实参恒 string(rec.model 类型非可选;last.model 重建投影自带
|
|
817
|
+
// `?? ""`),pickStr 签名宽返回 string|undefined —— `?? ""` 运行时不可达,
|
|
818
|
+
// 仅满足 model 非可选类型,空串回退语义不变(cur 空 → src,src 也空 → "")。
|
|
819
|
+
model: pickStr(rec.model, last.model) ?? "",
|
|
820
|
+
// [W4 boot 分区] 轮终执行态信号(resumable)随末条 entry 保留:子文件侧重建
|
|
821
|
+
// (reconstructAll)不带该信号,boot 分区的「already-resumable-idle 重认领 vs
|
|
822
|
+
// in-flight 直断」分流(finalizeOrphanRecord)只能从主 session 末条 entry 取证。
|
|
823
|
+
resumable: rec.resumable ?? last.resumable,
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
|
|
700
827
|
/**
|
|
701
828
|
* [E2E 实测缺口] entry-born 孤儿恢复:register entry 已落主 session、但子 session 文件
|
|
702
829
|
* 从未创建(父进程死在 spawn 窗口期——register 写点与子进程首笔写入之间的窗口;外部
|
|
@@ -762,6 +889,32 @@ export class RecordStore {
|
|
|
762
889
|
});
|
|
763
890
|
}
|
|
764
891
|
|
|
892
|
+
/**
|
|
893
|
+
* [E1/U5] sync 批崩溃恢复扫描:主 session 文件「每 id 末条 subagent-record entry」
|
|
894
|
+
* (collectLastRecordEntries + rebuildEntryRecord 组合通路,设计 §3.1.3「标记读取
|
|
895
|
+
* 通路」——batchFinalized 落标 entry 写主 session 文件,本扫描同文件域才可见;禁走
|
|
896
|
+
* collectRecords light 路径,它只读子文件 identity 头+sidecar,主 session 落标
|
|
897
|
+
* entry 不可见)。返回每 id 末条重建的完整 record(含 collectMode/batchFinalized /
|
|
898
|
+
* 终态五字段,损坏 entry 跳过);调用方(service.recoverSyncCollectBatch 的 E1 过滤、
|
|
899
|
+
* recoverOrphanRecords 的覆写 merge)自行取舍。主文件不可读(含新 session 未 flush
|
|
900
|
+
* 的 ENOENT)→ 空数组静默。
|
|
901
|
+
*/
|
|
902
|
+
scanLastRecordEntries(mainSessionFile: string | undefined): SubagentRecord[] {
|
|
903
|
+
if (mainSessionFile === undefined) return [];
|
|
904
|
+
let content: string;
|
|
905
|
+
try {
|
|
906
|
+
content = fs.readFileSync(mainSessionFile, "utf-8");
|
|
907
|
+
} catch {
|
|
908
|
+
return []; // 与 recoverEntryOnlyOrphans 同判:best-effort 恢复,不可读静默跳过
|
|
909
|
+
}
|
|
910
|
+
const out: SubagentRecord[] = [];
|
|
911
|
+
for (const [id, d] of collectLastRecordEntries(content)) {
|
|
912
|
+
const rec = rebuildEntryRecord(id, d);
|
|
913
|
+
if (rec !== null) out.push(rec);
|
|
914
|
+
}
|
|
915
|
+
return out;
|
|
916
|
+
}
|
|
917
|
+
|
|
765
918
|
/** 订阅变更。返回取消订阅函数。 */
|
|
766
919
|
onChange(listener: ChangeListener): () => void {
|
|
767
920
|
this.listeners.add(listener);
|
|
@@ -1320,6 +1473,11 @@ export class RecordStore {
|
|
|
1320
1473
|
engineFallback: r.engineFallback,
|
|
1321
1474
|
// U2:engineHandle 经 entry 持久化(register/archive 双写点均经本投影),无则 undefined 自然省略
|
|
1322
1475
|
engineHandle: r.engineHandle,
|
|
1476
|
+
// [U5 修复 U2 披露的投影缺口] 同步收集两字段随本投影持久化(register entry /
|
|
1477
|
+
// archive entry 双写点)——原缺失时闭合判定 flushBatch 重建、E1 重建扫描等消费方
|
|
1478
|
+
// 读不到原始值。undefined 经 JSON.stringify 自然缺省,旧 entry 零迁移。
|
|
1479
|
+
collectMode: r.collectMode,
|
|
1480
|
+
batchFinalized: r.batchFinalized,
|
|
1323
1481
|
};
|
|
1324
1482
|
}
|
|
1325
1483
|
}
|
|
@@ -1,37 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* env 语义:SOCKET/NODE/SCRIPT 三者同时非空 = relay 激活(全有或全无,无中间态);
|
|
10
|
-
* SESSION_ID/RECORD_ID 是 tee 帧归属键(缺失由代理握手前自检拒绝,退出码 13)。
|
|
11
|
-
*/
|
|
1
|
+
// src/execution/relay-env.ts
|
|
2
|
+
//
|
|
3
|
+
// relay 通道 env 名与协议常量的 re-export shim——单源在
|
|
4
|
+
// @zhushanwen/subagent-engine-sdk(round1-reuse R9 跨进程契约副本收编;core → SDK
|
|
5
|
+
// 边界正向合法)。本文件保持路径不变以保住 package.json exports 的 ./relay-env
|
|
6
|
+
// 子入口(semver 面:runtime/extension 消费方 import specifier 不变)。
|
|
7
|
+
// 代理脚本 relay.mjs 仍为内嵌镜像(零依赖脚本不能 import workspace 包),
|
|
8
|
+
// 镜像一致性由 conformance relay 变体断言锁定。
|
|
12
9
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/** 握手被拒:协议版本不匹配(安装损坏,重装应用)。 */
|
|
25
|
-
VERSION_MISMATCH: 10,
|
|
26
|
-
/** relay socket 不可达(runtime 未运行或已重启)。 */
|
|
27
|
-
SOCKET_UNREACHABLE: 11,
|
|
28
|
-
/** socket 中途断开(runtime 崩溃等)——代理生命线断即退。 */
|
|
29
|
-
SOCKET_CLOSED: 12,
|
|
30
|
-
/** 归属 env(SESSION_ID/RECORD_ID)缺失——防无归属帧污染广播。 */
|
|
31
|
-
MISSING_IDENTITY: 13,
|
|
32
|
-
} as const;
|
|
33
|
-
|
|
34
|
-
/** 激活判定:三 env 同时非空才走 relay,任一缺失回落直连 spawn 真实 pi(TUI/独立 pi 零回归)。 */
|
|
35
|
-
export function isRelayActive(env: NodeJS.ProcessEnv | Record<string, string | undefined>): boolean {
|
|
36
|
-
return Boolean(env[RELAY_ENV_SOCKET] && env[RELAY_ENV_NODE] && env[RELAY_ENV_SCRIPT]);
|
|
37
|
-
}
|
|
10
|
+
export {
|
|
11
|
+
RELAY_ENV_SOCKET,
|
|
12
|
+
RELAY_ENV_NODE,
|
|
13
|
+
RELAY_ENV_SCRIPT,
|
|
14
|
+
RELAY_ENV_SESSION_ID,
|
|
15
|
+
RELAY_ENV_RECORD_ID,
|
|
16
|
+
RELAY_PROTOCOL_VERSION,
|
|
17
|
+
RELAY_EXIT_CODES,
|
|
18
|
+
isRelayActive,
|
|
19
|
+
readRelayForwardEnv,
|
|
20
|
+
} from "@zhushanwen/subagent-engine-sdk";
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// src/execution/round-supervisor/domain.ts
|
|
2
|
+
//
|
|
3
|
+
// [W4] 轮次活性监督器——域分类与 record 级判据谓词(单一权威源)。
|
|
4
|
+
//
|
|
5
|
+
// 设计权威源:docs/design/chat-domain-v1x-liveness-governance.md §3.2 D2 前置 1
|
|
6
|
+
// (轮次域分类)+ 前置 2(record 去向单一裁决表)+ 三态判定表。
|
|
7
|
+
//
|
|
8
|
+
// 判定域 = run 域一次性任务(resumable 且无进程驱动)+ workflow 域 resumable run。
|
|
9
|
+
// chat/conversation 形态(record.chatMode)**豁免**出 no-progress 判定域:轮终 idle
|
|
10
|
+
// 现状(doFinalizeRoundToIdle + idle timer / idle-gc)+ settled-watchdog 两段守护
|
|
11
|
+
// 管辖——豁免只意味着「监督器不重复管」,不意味着无界(D2 R2 精确化)。
|
|
12
|
+
//
|
|
13
|
+
// 判据状态源钉死为 record 级(R3 核正):pi 引擎 poolKey 恒 'shared' 单进程、
|
|
14
|
+
// ensureConnected 被动重建会重填「镜像整体置死」——镜像不能作持续判据;run 终态
|
|
15
|
+
// failed 即「驱动死亡」的证据,不随引擎进程重建翻转。镜像置死仅作死亡事件的
|
|
16
|
+
// 触发信号(supervisor 的死亡事件纳管入口),不作持续判据。
|
|
17
|
+
//
|
|
18
|
+
// 纳管模型(R3 显式化):死亡事件纳管(run failed / 引擎 exited 事件把 record 纳入
|
|
19
|
+
// 监督域),**重建不解管**(引擎进程重建不解除已纳管 record 的监督,监督器按
|
|
20
|
+
// record 级状态持续判定直至终态或放弃)。本文件的谓词全部只读 record 级状态,
|
|
21
|
+
// 不读引擎镜像——结构性保证「重建不解管」(模拟引擎重建后监督器仍按 record 级判)。
|
|
22
|
+
|
|
23
|
+
import type { ExecutionRecord } from "../types.ts";
|
|
24
|
+
|
|
25
|
+
/** 监督器域分类(判定域先收窄,再谈三态)。 */
|
|
26
|
+
export type SupervisorDomain =
|
|
27
|
+
/** run 域一次性任务(非 chatMode record)——监督域主体。 */
|
|
28
|
+
| "run"
|
|
29
|
+
/** conversation/chat 形态(record.chatMode)——豁免,现状机制管辖。 */
|
|
30
|
+
| "conversation";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 域分类(裁决表 conversation 行「任何触发不入监督域」的判定锚)。
|
|
34
|
+
* record.chatMode === true → conversation(豁免);否则 → run 域。
|
|
35
|
+
* (workflow 域 resumable run 的活性收口 = kill-9 恢复链 + idle-gc startedAt 锚
|
|
36
|
+
* 归档 + sweep 对账——workflow run 不在 RecordStore,其注册对账按 type=workflow
|
|
37
|
+
* 保守跳过,见 reconcile-sweep.ts。)
|
|
38
|
+
*/
|
|
39
|
+
export function classifySupervisorDomain(record: Pick<ExecutionRecord, "chatMode">): SupervisorDomain {
|
|
40
|
+
return record.chatMode === true ? "conversation" : "run";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 三态判定「该唤醒」的 record 级判据(设计三态表逐字实现):
|
|
45
|
+
* **resumable 未终态 且 无在途 run / 无进程驱动**。
|
|
46
|
+
*
|
|
47
|
+
* 入参解耦说明:谓词只消费 record 级状态与两个布尔(在途 run / 活进程句柄),
|
|
48
|
+
* 由调用方(supervisor)供给——「有在途 run」来自 supervisor 的在途记账
|
|
49
|
+
* (subagent-service 报告),「有进程驱动」来自生命周期镜像谓词。本函数不读
|
|
50
|
+
* 镜像/引擎状态,结构性满足「镜像置死只作触发信号不作持续判据」。
|
|
51
|
+
*
|
|
52
|
+
* 「已有完成产出」(SP-5 upgrade 等待态)不在本谓词域——由调用方以 hasResult
|
|
53
|
+
* 单独判定(视图投影面分离,supervisor.evaluate 消费)。
|
|
54
|
+
*/
|
|
55
|
+
export function isAwakeWarrantedShape(
|
|
56
|
+
record: { status: string; resumable: boolean; chatMode: boolean },
|
|
57
|
+
hasInFlightRun: boolean,
|
|
58
|
+
hasLiveProcess: boolean,
|
|
59
|
+
): boolean {
|
|
60
|
+
if (record.chatMode === true) return false; // conversation 豁免
|
|
61
|
+
if (record.status !== "running") return false; // 终态 = 已收口
|
|
62
|
+
if (hasInFlightRun || hasLiveProcess) return false; // 该等(有驱动)→ 不干预
|
|
63
|
+
return record.resumable === true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* boot 分区「already-resumable-idle」重认领谓词(与裁决表同源——设计 D4 连带面 2
|
|
68
|
+
* ②「启动扫描 resumable 且无进程驱动且非 conversation 形态」的单一权威实现;
|
|
69
|
+
* cold-resurrect.ts 的 message 冷查链不承载启动扫描,本谓词即其「cold-resurrect
|
|
70
|
+
* 扩展」落点,record-store 孤儿恢复的保留分支与 supervisor.bootPartition 共同消费
|
|
71
|
+
* 同一判据形态)。
|
|
72
|
+
*
|
|
73
|
+
* 判据:非 conversation 形态 + status=running + resumable 信号(轮终写点 set true;
|
|
74
|
+
* 冷路径续轮清除——重启前已在途的 record resumable=undefined,走 boot 直断分支
|
|
75
|
+
* 而非重认领)+ **无完成产出**(resumable=true 且 result 有值是 SP-5 one-shot
|
|
76
|
+
* 完成态——任务已完成,直断 closed/gc 无损,不属重认领域;result 缺失才是 W4
|
|
77
|
+
* 死亡纳管态跨重启的形态)。
|
|
78
|
+
*/
|
|
79
|
+
export function isBootReadoptable(record: {
|
|
80
|
+
status: string;
|
|
81
|
+
resumable: boolean;
|
|
82
|
+
chatMode: boolean;
|
|
83
|
+
hasResult: boolean;
|
|
84
|
+
}): boolean {
|
|
85
|
+
if (record.chatMode) return false;
|
|
86
|
+
if (record.status !== "running") return false;
|
|
87
|
+
if (!record.resumable) return false;
|
|
88
|
+
return !record.hasResult;
|
|
89
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/execution/round-supervisor/index.ts
|
|
2
|
+
//
|
|
3
|
+
// [W4] 轮次活性监督器公共出口(SubagentService 与测试的消费面)。
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
classifySupervisorDomain,
|
|
7
|
+
isAwakeWarrantedShape,
|
|
8
|
+
isBootReadoptable,
|
|
9
|
+
type SupervisorDomain,
|
|
10
|
+
} from "./domain.ts";
|
|
11
|
+
export {
|
|
12
|
+
classifyReplacement,
|
|
13
|
+
type ReplacementCandidate,
|
|
14
|
+
type ReplacementProbeSubject,
|
|
15
|
+
type ReplacementVerdict,
|
|
16
|
+
} from "./notify-accounting.ts";
|
|
17
|
+
export {
|
|
18
|
+
runReconcileSweep,
|
|
19
|
+
type ReconcileSweepDeps,
|
|
20
|
+
type ReconcileSweepResult,
|
|
21
|
+
type SupervisedRecordState,
|
|
22
|
+
} from "./reconcile-sweep.ts";
|
|
23
|
+
export {
|
|
24
|
+
ROUND_SUPERVISOR_WATCHDOG_DEFAULT_MS,
|
|
25
|
+
ROUND_SUPERVISOR_WATCHDOG_ENV,
|
|
26
|
+
RoundSupervisor,
|
|
27
|
+
getSupervisorWatchdogMs,
|
|
28
|
+
isSupervisorGiveUpDisabled,
|
|
29
|
+
type GiveUpKind,
|
|
30
|
+
type RoundSupervisorDeps,
|
|
31
|
+
type SupervisorCandidateRecord,
|
|
32
|
+
type SupervisorRecordView,
|
|
33
|
+
} from "./supervisor.ts";
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/execution/round-supervisor/notify-accounting.ts
|
|
2
|
+
//
|
|
3
|
+
// [W4] 通知对账——送决策指引前查替代的两级启发式(纯函数)。
|
|
4
|
+
//
|
|
5
|
+
// 设计权威源:docs/design/chat-domain-v1x-liveness-governance.md §3.2 D2「通知对账」
|
|
6
|
+
// (R3 增补、R4 钉死判定语义)。
|
|
7
|
+
//
|
|
8
|
+
// 背景:主 agent 是唯一决策者,重派不被禁止——即使合并单条通知,它仍可能在收到
|
|
9
|
+
// 指引前合法地重派了新任务。record 数据模型不存在重派关联字段(parentRecordId 是
|
|
10
|
+
// 层级语义、rootSessionId 是 session 隔离语义、task 是完整 prompt 非关联键),
|
|
11
|
+
// 对账判定为显式定义的两级启发式:
|
|
12
|
+
// - 高置信替代:同 rootSessionId + 同 agent 名 + 同 slug(≤35 字符短标签,重派
|
|
13
|
+
// 同任务大概率同 slug)+ 决策指引看门狗窗内新建 → 撤销指引,改送「原任务已被
|
|
14
|
+
// 新任务替代」终止通知 + 对原 record 走该放弃路径(终态化 + 注销);
|
|
15
|
+
// - 低置信(仅 agent 同名):不撤销指引,但指引内容自带豁免声明(「若你已重新
|
|
16
|
+
// 派发或不再需要此任务,忽略本指引;原任务将在看门狗到期后自动终止」)。
|
|
17
|
+
//
|
|
18
|
+
// 两失败方向登记(设计四要素):
|
|
19
|
+
// - 漏判(重派改写 slug/task 致高置信不命中)→ 残余双执行;重审触发 = 实测双执行
|
|
20
|
+
// 反馈 ≥1 例 → 升级「supersedes 显式引用」方案;
|
|
21
|
+
// - 误判(无关任务撞 slug)→ 原任务被错误终态化——危害轻(原任务本已无进程驱动,
|
|
22
|
+
// 仅损失 resume 可能)。
|
|
23
|
+
|
|
24
|
+
/** 对账候选(重派承接任务的 record 投影面)。 */
|
|
25
|
+
export interface ReplacementCandidate {
|
|
26
|
+
id: string;
|
|
27
|
+
rootSessionId: string | undefined;
|
|
28
|
+
/** agent 类型名(record.agent)。 */
|
|
29
|
+
agentName: string;
|
|
30
|
+
/** 人类短标签(record.slug,≤35 字符)。 */
|
|
31
|
+
slug: string;
|
|
32
|
+
/** 创建时刻(record.startedAt,ms)。 */
|
|
33
|
+
startedAt: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** 被接管 record 的对账基准面。 */
|
|
37
|
+
export interface ReplacementProbeSubject {
|
|
38
|
+
id: string;
|
|
39
|
+
rootSessionId: string | undefined;
|
|
40
|
+
agentName: string;
|
|
41
|
+
slug: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** 对账结论(两级 + 无命中)。 */
|
|
45
|
+
export type ReplacementVerdict =
|
|
46
|
+
| { kind: "high-confidence"; replacementId: string }
|
|
47
|
+
| { kind: "low-confidence" }
|
|
48
|
+
| { kind: "none" };
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 高置信判定窗口:候选的 startedAt 必须落在「决策指引看门狗窗」内(接管时刻起
|
|
52
|
+
* 算——窗内新建才有「承接了同一任务」的置信;窗外的同名任务与本接管无时序关联)。
|
|
53
|
+
* 窗值由调用方传(= 监督器决策看门狗窗,同源常量)。
|
|
54
|
+
*/
|
|
55
|
+
export function classifyReplacement(
|
|
56
|
+
subject: ReplacementProbeSubject,
|
|
57
|
+
candidates: readonly ReplacementCandidate[],
|
|
58
|
+
windowMs: number,
|
|
59
|
+
now: number,
|
|
60
|
+
): ReplacementVerdict {
|
|
61
|
+
let sameAgentOnly = false;
|
|
62
|
+
for (const candidate of candidates) {
|
|
63
|
+
if (candidate.id === subject.id) continue;
|
|
64
|
+
if (candidate.agentName !== subject.agentName) continue;
|
|
65
|
+
// 时序窗(高/低置信共同的门):窗内新建才参与对账——窗外的同名任务与本接管
|
|
66
|
+
// 无时序关联(预先存在的同名任务不是替代者)。
|
|
67
|
+
if (now - candidate.startedAt > windowMs) continue;
|
|
68
|
+
// [契约锚] sameRoot 在生产装配下恒真——此检查是对供给侧不变量的防御性复认,
|
|
69
|
+
// 不是独立生效的第四要素。生产候选源 = supervisor.deps.listCandidateRecords
|
|
70
|
+
// (service-binding.ts supervisorCandidates 已按 getSessionRootId() 预过滤,
|
|
71
|
+
// 循环内候选恒同 root)。约束力悄悄依赖该供给不变量:若换候选源为未按 root
|
|
72
|
+
// 预过滤的全量集,sameRoot 从恒真退化为真实约束——跨 root 命中会从
|
|
73
|
+
// high-confidence 降为 low-confidence(替代收口弱化:原任务改由看门狗到期才
|
|
74
|
+
// 放弃),行为静默漂移。换候选源必须保「root 预过滤」或显式重审本判定语义。
|
|
75
|
+
const sameRoot =
|
|
76
|
+
candidate.rootSessionId !== undefined &&
|
|
77
|
+
candidate.rootSessionId === subject.rootSessionId;
|
|
78
|
+
const sameSlug =
|
|
79
|
+
subject.slug !== "" &&
|
|
80
|
+
candidate.slug === subject.slug;
|
|
81
|
+
if (sameRoot && sameSlug) {
|
|
82
|
+
return { kind: "high-confidence", replacementId: candidate.id };
|
|
83
|
+
}
|
|
84
|
+
sameAgentOnly = true;
|
|
85
|
+
}
|
|
86
|
+
return sameAgentOnly ? { kind: "low-confidence" } : { kind: "none" };
|
|
87
|
+
}
|