@zhushanwen/pi-subagent-workflow 8.6.0 → 8.8.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 +5 -11
- package/package.json +13 -20
- package/relay/relay.mjs +1 -1
- package/skills/workflow-script-format/SKILL.md +32 -13
- package/src/host/__tests__/pi-host.test.ts +235 -0
- package/src/host/pi-host.ts +163 -0
- package/src/index.ts +141 -138
- package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
- package/src/injectors/__tests__/engine-section-stability.test.ts +343 -0
- package/src/injectors/__tests__/model-list-injector.test.ts +18 -21
- package/src/injectors/__tests__/subagent-list-injector.test.ts +59 -19
- package/src/injectors/__tests__/workflow-list-injector.test.ts +31 -17
- package/src/injectors/engine-awareness.ts +119 -0
- package/src/injectors/model-list-injector.ts +15 -58
- package/src/injectors/subagent-list-injector.ts +56 -114
- package/src/injectors/workflow-list-injector.ts +37 -70
- package/src/interface/__tests__/detectors.test.ts +48 -37
- package/src/interface/__tests__/subagent-tool-path-guard.test.ts +2 -2
- package/src/interface/__tests__/subagent-tool-prompt.test.ts +6 -3
- package/src/interface/__tests__/tool-workflow-run-builtin-name.test.ts +216 -0
- package/src/interface/__tests__/tool-workflow-script-generate.test.ts +17 -6
- package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +38 -2
- package/src/interface/bg-notify-render.ts +7 -17
- package/src/interface/command-actions.ts +5 -15
- package/src/interface/commands.ts +4 -4
- package/src/interface/format.ts +17 -6
- package/src/interface/gui-mappers.ts +18 -22
- package/src/interface/helpers.ts +9 -130
- package/src/interface/list-component.ts +5 -5
- package/src/interface/list-shared.ts +3 -3
- package/src/interface/list-view.ts +3 -3
- package/src/interface/subagent-actions.ts +66 -439
- package/src/interface/subagent-tool-schema.ts +21 -17
- package/src/interface/subagent-tool.ts +12 -7
- package/src/interface/subagents.ts +4 -4
- package/src/interface/tool-render.ts +37 -15
- package/src/interface/tool-workflow-script.ts +34 -76
- package/src/interface/tool-workflow.ts +57 -94
- package/src/interface/views/WorkflowsView.ts +8 -16
- package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
- package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
- package/src/interface/views/detail-content.ts +4 -4
- package/src/interface/views/format.ts +23 -62
- package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +137 -225
- package/agents/analyst.md +0 -61
- package/agents/coder.md +0 -70
- package/agents/debugger.md +0 -67
- package/agents/doc-reviewer.md +0 -50
- package/agents/explorer.md +0 -64
- package/agents/general-purpose.md +0 -32
- package/agents/orchestrator.md +0 -63
- package/agents/planner.md +0 -54
- package/agents/researcher.md +0 -65
- package/agents/reviewer.md +0 -74
- package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
- package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
- package/src/execution/__tests__/agent-registry.test.ts +0 -363
- package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
- package/src/execution/__tests__/alive-store.test.ts +0 -147
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
- package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
- package/src/execution/__tests__/bg-notify-render.test.ts +0 -329
- package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
- package/src/execution/__tests__/chat-engine-routing.test.ts +0 -601
- package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
- package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
- package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
- package/src/execution/__tests__/config.test.ts +0 -110
- package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
- package/src/execution/__tests__/crash-recovery.test.ts +0 -320
- package/src/execution/__tests__/delivery-methods.test.ts +0 -422
- package/src/execution/__tests__/dialog-queue.test.ts +0 -299
- package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
- package/src/execution/__tests__/execute-nesting.test.ts +0 -323
- package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
- package/src/execution/__tests__/execution-record.test.ts +0 -1394
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +0 -171
- package/src/execution/__tests__/finalize-record.test.ts +0 -368
- package/src/execution/__tests__/finalized-marker.test.ts +0 -82
- package/src/execution/__tests__/format-schema-instruction.test.ts +0 -169
- package/src/execution/__tests__/format.test.ts +0 -458
- package/src/execution/__tests__/gc-timer.test.ts +0 -184
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
- package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
- package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
- package/src/execution/__tests__/helpers/spawn-mock.ts +0 -242
- package/src/execution/__tests__/host-mode.test.ts +0 -87
- package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
- package/src/execution/__tests__/index-session-start.test.ts +0 -672
- package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
- package/src/execution/__tests__/lifecycle-manager.test.ts +0 -383
- package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
- package/src/execution/__tests__/list-component.test.ts +0 -401
- package/src/execution/__tests__/list-fields.test.ts +0 -140
- package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
- package/src/execution/__tests__/model-resolver.test.ts +0 -465
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
- package/src/execution/__tests__/nested-visibility.test.ts +0 -325
- package/src/execution/__tests__/notifier-flush.test.ts +0 -612
- package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
- package/src/execution/__tests__/notify-ledger.test.ts +0 -826
- package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
- package/src/execution/__tests__/output-collector.test.ts +0 -358
- package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
- package/src/execution/__tests__/path-encoding.test.ts +0 -104
- package/src/execution/__tests__/pi-invocation.test.ts +0 -134
- package/src/execution/__tests__/record-store.test.ts +0 -1057
- package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
- package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
- package/src/execution/__tests__/relay-agent.test.ts +0 -448
- package/src/execution/__tests__/relay-env.test.ts +0 -42
- package/src/execution/__tests__/resource-policy.test.ts +0 -109
- package/src/execution/__tests__/rpc-mode.test.ts +0 -89
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
- package/src/execution/__tests__/run-spawn-edges.test.ts +0 -687
- 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 -199
- package/src/execution/__tests__/sdk-contract.test.ts +0 -273
- package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
- package/src/execution/__tests__/session-file-gc.test.ts +0 -293
- package/src/execution/__tests__/session-pending.test.ts +0 -197
- package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
- package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
- package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -350
- package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
- package/src/execution/__tests__/spawn-args.test.ts +0 -445
- package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
- package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
- package/src/execution/__tests__/spawned-children.test.ts +0 -92
- package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
- package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
- package/src/execution/__tests__/status-refactor.test.ts +0 -345
- package/src/execution/__tests__/stdin-writer.test.ts +0 -463
- package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
- package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
- package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
- package/src/execution/__tests__/subagent-service.test.ts +0 -788
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -599
- package/src/execution/__tests__/temp-prompt.test.ts +0 -53
- package/src/execution/__tests__/timeout-integration.test.ts +0 -615
- package/src/execution/__tests__/tombstone-store.test.ts +0 -73
- package/src/execution/__tests__/tool-action.test.ts +0 -476
- package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
- 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-channels.test.ts +0 -187
- package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
- package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
- package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
- package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
- package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
- package/src/execution/__tests__/worktree-manager.test.ts +0 -633
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
- package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
- package/src/execution/__tests__/worktree-registry.test.ts +0 -199
- package/src/execution/agent-registry.ts +0 -199
- package/src/execution/agent-result-mapper.ts +0 -90
- package/src/execution/alive-store.ts +0 -92
- package/src/execution/argv-mirror.ts +0 -113
- package/src/execution/best-effort.ts +0 -38
- package/src/execution/channel-registry-access.ts +0 -144
- package/src/execution/concurrency-pool.ts +0 -116
- package/src/execution/config.ts +0 -96
- package/src/execution/dialog-queue.ts +0 -330
- package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
- package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
- package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
- package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
- package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
- package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
- package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
- package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
- package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
- package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
- package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
- package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
- package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
- package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
- package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
- package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
- package/src/execution/engine/__tests__/paths.test.ts +0 -39
- package/src/execution/engine/__tests__/registry.test.ts +0 -120
- package/src/execution/engine/__tests__/routing.test.ts +0 -231
- package/src/execution/engine/common/data-dir.ts +0 -62
- package/src/execution/engine/common/errors.ts +0 -183
- package/src/execution/engine/common/event-journal.ts +0 -254
- package/src/execution/engine/common/journal-replay.ts +0 -62
- package/src/execution/engine/common/kill-chain.ts +0 -221
- package/src/execution/engine/common/nesting-guard.ts +0 -50
- package/src/execution/engine/common/persona-router.ts +0 -108
- package/src/execution/engine/common/pool-manager.ts +0 -226
- 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/engine-discovery.ts +0 -65
- package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
- package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
- package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
- package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
- package/src/execution/engine/engines/pi/reader.ts +0 -48
- package/src/execution/engine/engines/pi/registration.ts +0 -35
- package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
- package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
- package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
- package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
- package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
- package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -580
- package/src/execution/engine/engines/zcode/constants.ts +0 -43
- package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
- package/src/execution/engine/engines/zcode/launcher.ts +0 -161
- package/src/execution/engine/engines/zcode/parser.ts +0 -436
- package/src/execution/engine/engines/zcode/preparer.ts +0 -363
- 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/zcode-engine.ts +0 -658
- package/src/execution/engine/host-task-spec.ts +0 -47
- package/src/execution/engine/model-prompt.ts +0 -59
- package/src/execution/engine/paths.ts +0 -42
- package/src/execution/engine/port.ts +0 -153
- package/src/execution/engine/registry.ts +0 -123
- package/src/execution/engine/routing.ts +0 -218
- package/src/execution/engine/types.ts +0 -309
- package/src/execution/execute-options-mapper.ts +0 -112
- package/src/execution/execution-record.ts +0 -965
- package/src/execution/finalize-record.ts +0 -251
- package/src/execution/finalized-marker.ts +0 -51
- package/src/execution/get-state-handshake.ts +0 -104
- package/src/execution/host-mode.ts +0 -56
- package/src/execution/idle-gc.ts +0 -47
- package/src/execution/lifecycle-manager.ts +0 -513
- package/src/execution/lifecycle-predicates.ts +0 -65
- package/src/execution/manifest-store.ts +0 -256
- package/src/execution/model-config-service.ts +0 -219
- package/src/execution/model-resolver.ts +0 -248
- package/src/execution/notifier.ts +0 -330
- package/src/execution/notify-ledger.ts +0 -580
- package/src/execution/output-collector.ts +0 -228
- package/src/execution/path-encoding.ts +0 -60
- package/src/execution/pi-invocation.ts +0 -120
- package/src/execution/record-entry.ts +0 -132
- package/src/execution/record-store.ts +0 -1234
- package/src/execution/relay-env.ts +0 -37
- package/src/execution/session-context-resolver.ts +0 -64
- package/src/execution/session-file-gc.ts +0 -120
- package/src/execution/session-pending.ts +0 -164
- package/src/execution/session-reconstructor.ts +0 -678
- package/src/execution/session-runner.ts +0 -1781
- package/src/execution/sessions-index.ts +0 -304
- package/src/execution/spawn-event-adapter.ts +0 -363
- package/src/execution/stdin-writer.ts +0 -198
- package/src/execution/stream-sink.ts +0 -126
- package/src/execution/subagent-service.ts +0 -2141
- package/src/execution/subprocess-agent-runner.ts +0 -317
- package/src/execution/temp-prompt.ts +0 -62
- package/src/execution/tombstone-store.ts +0 -72
- package/src/execution/turn-limiter.ts +0 -102
- package/src/execution/types.ts +0 -973
- package/src/execution/ui-channels.ts +0 -216
- package/src/execution/ui-interaction-model.ts +0 -48
- package/src/execution/ui-request-handler-factory.ts +0 -212
- package/src/execution/ui-request-observability.ts +0 -81
- package/src/execution/ui-request-queue.ts +0 -184
- package/src/execution/worktree-manager.ts +0 -688
- package/src/execution/worktree-registry.ts +0 -222
- package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -349
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -202
- package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -152
- package/src/orchestration/__tests__/args-validator.test.ts +0 -143
- package/src/orchestration/__tests__/config-loader.test.ts +0 -503
- package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -809
- package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
- package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
- package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
- package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -451
- package/src/orchestration/__tests__/jsonl-run-store-corrupt-entry.test.ts +0 -150
- package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
- package/src/orchestration/__tests__/jsonl-run-store-retention.test.ts +0 -202
- package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -600
- package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
- package/src/orchestration/__tests__/lifecycle.test.ts +0 -659
- package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +0 -95
- package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -2025
- package/src/orchestration/__tests__/script-lint.test.ts +0 -831
- package/src/orchestration/__tests__/skill-discovery.test.ts +0 -201
- package/src/orchestration/__tests__/test-mocks.ts +0 -197
- package/src/orchestration/__tests__/worker-exit-without-result.test.ts +0 -368
- package/src/orchestration/__tests__/worker-host.test.ts +0 -120
- package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
- package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -563
- package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
- package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -129
- package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
- package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
- package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
- package/src/orchestration/agent-opts-resolver.ts +0 -174
- package/src/orchestration/args-validator.ts +0 -127
- package/src/orchestration/config-loader.ts +0 -315
- package/src/orchestration/error-recovery.ts +0 -1018
- package/src/orchestration/execute-agent-call.ts +0 -256
- package/src/orchestration/launcher.ts +0 -455
- package/src/orchestration/lifecycle.ts +0 -399
- package/src/orchestration/models/__tests__/budget.test.ts +0 -307
- package/src/orchestration/models/__tests__/trace.test.ts +0 -408
- package/src/orchestration/models/agent-call.ts +0 -83
- package/src/orchestration/models/budget.ts +0 -118
- package/src/orchestration/models/ports.ts +0 -164
- package/src/orchestration/models/run-runtime.ts +0 -104
- package/src/orchestration/models/run-spec.ts +0 -83
- package/src/orchestration/models/run-state.ts +0 -44
- package/src/orchestration/models/trace.ts +0 -183
- package/src/orchestration/models/types.ts +0 -301
- package/src/orchestration/models/workflow-run.ts +0 -254
- package/src/orchestration/models/workflow-script-registry.ts +0 -35
- package/src/orchestration/models/workflow-script.ts +0 -117
- package/src/orchestration/script-lint.ts +0 -766
- package/src/orchestration/skill-discovery.ts +0 -115
- package/src/orchestration/worker-handle.ts +0 -115
- package/src/orchestration/worker-host.ts +0 -98
- package/src/orchestration/worker-script-builder.ts +0 -421
- package/src/orchestration/workflow-files.ts +0 -85
- package/src/orchestration/workflow-script-registry-impl.ts +0 -133
- package/src/shared/__tests__/agent-ref.test.ts +0 -34
- package/src/shared/__tests__/meta-parser.test.ts +0 -304
- package/src/shared/__tests__/model-ref.test.ts +0 -306
- package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
- package/src/shared/__tests__/resource-discovery.test.ts +0 -736
- package/src/shared/__tests__/resource-meta.test.ts +0 -51
- package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
- package/src/shared/__tests__/timer-delay.test.ts +0 -61
- package/src/shared/agent-event.ts +0 -13
- package/src/shared/agent-ref.ts +0 -57
- package/src/shared/meta-parser.ts +0 -261
- package/src/shared/model-ref.ts +0 -286
- package/src/shared/resource-discovery.ts +0 -811
- package/src/shared/resource-meta.ts +0 -65
- package/src/shared/schema-env.ts +0 -44
- package/src/shared/schema-jsonify.ts +0 -58
- package/src/shared/timer-delay.ts +0 -54
- package/src/shared/xml-injection.ts +0 -35
- package/workflows/README.md +0 -81
- package/workflows/_shared/agent-refs.cjs +0 -40
- package/workflows/chain.js +0 -131
- package/workflows/map-reduce.js +0 -174
- package/workflows/parallel.js +0 -148
- package/workflows/review-fix-loop-utils.cjs +0 -1309
- package/workflows/review-fix-loop.js +0 -1404
- package/workflows/scatter-gather.js +0 -178
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
// src/interface/subagent-actions.ts
|
|
2
2
|
//
|
|
3
|
-
// subagent tool
|
|
3
|
+
// subagent tool 六 action 的 pi adapter 壳(sink 设计 D6② 消费收缩)。
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// 领域内核(入参校验 / message 拒绝文案分流 / fork-from 拒绝链 / 终态映射 /
|
|
6
|
+
// list 投影)已下沉 core @zhushanwen/subagent-core/execution/subagent-actions-core——
|
|
7
|
+
// ⛔4 行为快照等值锚定见 core __tests__/subagent-actions-core.test.ts(期望值硬编码自
|
|
8
|
+
// 本文件迁移前实测输出,含错误文案逐字锚)。本壳按设计仅保留三类职责:
|
|
9
|
+
// 1. core 调用面 re-export:六 handler + 领域类型(签名不变,消费方零改动)
|
|
10
|
+
// 2. 参数提取:位于 subagent-tool.ts executeSubagent(action 路由 / listParam /
|
|
11
|
+
// cancelParam 解包 / skillPath-cwd 路径检查),本次收缩零改动
|
|
12
|
+
// 3. TUI/GUI 渲染:adapter / buildGuiComponent(pi TUI 渲染族按设计留壳)
|
|
8
13
|
//
|
|
9
14
|
// content(JSON 字符串)给 LLM,details(SubagentToolResult)给 renderResult,同源同处生成。
|
|
10
15
|
|
|
@@ -16,456 +21,60 @@ import {
|
|
|
16
21
|
isGuiCapable,
|
|
17
22
|
} from "@xyz-agent/extension-protocol";
|
|
18
23
|
|
|
19
|
-
import {
|
|
20
|
-
import { computeElapsedSeconds, projectOutcome } from "../execution/execution-record.ts";
|
|
21
|
-
import { isResumable } from "../execution/lifecycle-predicates.ts";
|
|
22
|
-
import type { ExecutionRecord } from "../execution/types.ts";
|
|
23
|
-
import type { ModelInfo } from "../execution/model-resolver.ts";
|
|
24
|
-
import type { SubagentService } from "../execution/subagent-service.ts";
|
|
25
|
-
import { displayAgentName } from "../shared/agent-ref.ts";
|
|
24
|
+
import type { SubagentToolResult } from "@zhushanwen/subagent-core/execution/types.ts";
|
|
26
25
|
import type {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
SubagentListItem,
|
|
35
|
-
SubagentRecord,
|
|
36
|
-
SubagentToolResult,
|
|
37
|
-
} from "../execution/types.ts";
|
|
26
|
+
CancelHandlerResult,
|
|
27
|
+
CloseHandlerResult,
|
|
28
|
+
ForkFromHandlerResult,
|
|
29
|
+
ListHandlerResult,
|
|
30
|
+
MessageHandlerResult,
|
|
31
|
+
StartHandlerResult,
|
|
32
|
+
} from "@zhushanwen/subagent-core/execution/subagent-actions-core.ts";
|
|
38
33
|
import { mapRunIcon, mapRunStatus } from "./gui-mappers.ts";
|
|
39
34
|
|
|
40
35
|
// ============================================================
|
|
41
|
-
//
|
|
36
|
+
// core 领域内核 re-export(pi 消费面符号与收缩前一致,deep path 直连 core 源码)
|
|
42
37
|
// ============================================================
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
export {
|
|
40
|
+
cancelHandler,
|
|
41
|
+
closeHandler,
|
|
42
|
+
endedMessageGuard,
|
|
43
|
+
forkFromHandler,
|
|
44
|
+
listHandler,
|
|
45
|
+
mapExternalState,
|
|
46
|
+
messageHandler,
|
|
47
|
+
recordToListItem,
|
|
48
|
+
startHandler,
|
|
49
|
+
} from "@zhushanwen/subagent-core/execution/subagent-actions-core.ts";
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
export type {
|
|
52
|
+
CancelHandlerInput,
|
|
53
|
+
CancelHandlerResult,
|
|
54
|
+
CloseHandlerInput,
|
|
55
|
+
CloseHandlerResult,
|
|
56
|
+
ForkFromHandlerInput,
|
|
57
|
+
ForkFromHandlerResult,
|
|
58
|
+
ListHandlerInput,
|
|
59
|
+
ListHandlerResult,
|
|
60
|
+
MessageHandlerInput,
|
|
61
|
+
MessageHandlerResult,
|
|
62
|
+
StartHandlerInput,
|
|
63
|
+
StartHandlerResult,
|
|
64
|
+
} from "@zhushanwen/subagent-core/execution/subagent-actions-core.ts";
|
|
57
65
|
|
|
58
66
|
// ============================================================
|
|
59
|
-
//
|
|
67
|
+
// 渲染层常量 / 类型(pi TUI 渲染族,按设计留壳)
|
|
60
68
|
// ============================================================
|
|
61
69
|
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
* 调用方传整个 params(含 action/listParam/cancelParam),多余字段被忽略。 */
|
|
65
|
-
export interface StartHandlerInput {
|
|
66
|
-
task?: string;
|
|
67
|
-
/** 短标签(≤35 字符,kebab-case),必填。 */
|
|
68
|
-
slug?: string;
|
|
69
|
-
agent?: string;
|
|
70
|
-
model?: string;
|
|
71
|
-
thinkingLevel?: string;
|
|
72
|
-
skillPath?: string;
|
|
73
|
-
appendSystemPrompt?: string[];
|
|
74
|
-
schema?: Record<string, unknown>;
|
|
75
|
-
maxTurns?: number;
|
|
76
|
-
graceTurns?: number;
|
|
77
|
-
/** fork 模式:继承主 session 上下文(D-018 两级降级)。 */
|
|
78
|
-
fork?: boolean;
|
|
79
|
-
/** worktree 模式:文件系统隔离运行(D-008 tmpdir)。 */
|
|
80
|
-
worktree?: boolean;
|
|
81
|
-
/** 覆盖子 agent 工作目录(默认 mainCwd)。 */
|
|
82
|
-
cwd?: string;
|
|
83
|
-
/** 可持续对话模式(true = chatMode,轮次完成进 idle 等续聊)。 */
|
|
84
|
-
conversation?: boolean;
|
|
85
|
-
/**
|
|
86
|
-
* 空闲超时毫秒数(仅 conversation 模式有意义,覆盖默认 5min)。
|
|
87
|
-
* 显式传 0/负数 = 禁用 idle GC(不挂 timer);不传走 env/默认优先级。
|
|
88
|
-
*/
|
|
89
|
-
idleTimeoutMs?: number;
|
|
90
|
-
/** 执行引擎(D4 三层路由第一层:本参数 > agent frontmatter engine > config defaultEngine)。 */
|
|
91
|
-
engine?: string;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** start 领域对象(adapter 包成 bgResponse)。 */
|
|
95
|
-
export type StartHandlerResult = {
|
|
96
|
-
kind: "bg";
|
|
97
|
-
subagentId: string;
|
|
98
|
-
sessionFile: string | undefined;
|
|
99
|
-
/** 短标签,来自 record(handle.details.slug)。用于 result 行展示。 */
|
|
100
|
-
slug: string;
|
|
101
|
-
/**
|
|
102
|
-
* registry 全等回显(U1):handle.details.model = record.model = `${provider}/${id}`,
|
|
103
|
-
* 源头是 resolveModel 裁决放行的条目——通过校验 = 子进程必然按此名执行。
|
|
104
|
-
*/
|
|
105
|
-
model: string;
|
|
106
|
-
response: BgResponse;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
export interface ListHandlerInput {
|
|
110
|
-
includeFinished?: boolean;
|
|
111
|
-
limit?: number;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** list 领域对象(adapter 包成 listResponse,最外层 subagentId/sessionFile 为 null)。 */
|
|
115
|
-
export interface ListHandlerResult {
|
|
116
|
-
response: ListResponse;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export interface CancelHandlerInput {
|
|
120
|
-
subagentId?: string;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** cancel 领域对象(adapter 包成 cancelResponse)。 */
|
|
124
|
-
export interface CancelHandlerResult {
|
|
125
|
-
subagentId: string;
|
|
126
|
-
response: CancelResponse;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// ============================================================
|
|
130
|
-
// helpers(模块内)
|
|
131
|
-
// ============================================================
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* list 数据源(诚实声明 G3-003):
|
|
135
|
-
* collectRecords(limit, statusFilter) 合并内存(running) + 磁盘(sessions/*.jsonl 重建)。
|
|
136
|
-
* 磁盘源天然跨 session 可见——/new /resume /fork 后前 session 的终态 record 仍在
|
|
137
|
-
* sessions 目录里(直到 30 天 GC)。内存源仅当前 session 的 running record。
|
|
138
|
-
* 不新增 sessionId 到 ExecutionRecord(YAGNI,修跨 session 清理是独立问题)。
|
|
139
|
-
*/
|
|
70
|
+
/** subagentId(UUID)在 GUI header 的截断显示长度。 */
|
|
71
|
+
const SUBAGENT_ID_PREVIEW = 8;
|
|
140
72
|
|
|
141
|
-
/** exhaustiveness 兜底:default 分支把
|
|
73
|
+
/** exhaustiveness 兜底:default 分支把 action 收敛为 never,新增 action 时 tsc 报错。 */
|
|
142
74
|
function assertNever(value: never): string {
|
|
143
75
|
return String(value);
|
|
144
76
|
}
|
|
145
77
|
|
|
146
|
-
/**
|
|
147
|
-
* 内部 ExecutionStatus → 对外 state 映射(设计决策 10 细则 3)。
|
|
148
|
-
* v4 B-1 两态收敛后的真实映射只有两条:
|
|
149
|
-
* running → active / closed → ended(closed 统一终态,含 cancelled)
|
|
150
|
-
* ExternalState 仍声明 waiting/error 四态联合(对外契约不变),但当前状态机不产生
|
|
151
|
-
* 这两个值——它们是历史多态映射(idle→waiting / failed+crashed→error)的遗留声明。
|
|
152
|
-
* 未来内部加态必须扩展此处,漏加会在 default 分支编译报错(而非静默返回 undefined
|
|
153
|
-
* 让 state 字段以无主值进入 listResponse JSON)。
|
|
154
|
-
*/
|
|
155
|
-
export function mapExternalState(status: ExecutionStatus): ExternalState {
|
|
156
|
-
switch (status) {
|
|
157
|
-
case "running":
|
|
158
|
-
return "active";
|
|
159
|
-
case "closed":
|
|
160
|
-
// v4 B-1: closed 统一终态(含 cancelled)。对外映射为 ended。
|
|
161
|
-
return "ended";
|
|
162
|
-
default:
|
|
163
|
-
throw new Error(`mapExternalState: unhandled ExecutionStatus ${assertNever(status)}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** SubagentRecord → SubagentListItem(state 四态主字段 + status 调试字段,duration 实时计算)。
|
|
168
|
-
* [v4 A-6] 新增 parent/resumable:parent 从 record.parentRecordId 派生(配合 A-5 直接父
|
|
169
|
-
* 守卫),resumable 从 isResumable 派生(B-1「可续聊」对外表达)。
|
|
170
|
-
* [U3 C-outcome] 新增 outcome 一等终态语义(projectOutcome 唯一出口);closedReason
|
|
171
|
-
* 退出对外 JSON(保留为 record 内部诊断字段),对外成败判读收口到 outcome,消费方
|
|
172
|
-
* 零手写推导(三处同构 switch 已收敛删除)。
|
|
173
|
-
* agent 是 GUI/TUI list 共用的显示名——取 basename 短名(displayAgentName),
|
|
174
|
-
* 完整路径保留在 record.agent(数据层)。 */
|
|
175
|
-
export function recordToListItem(r: SubagentRecord): SubagentListItem {
|
|
176
|
-
return {
|
|
177
|
-
subagentId: r.id,
|
|
178
|
-
agent: displayAgentName(r.agent),
|
|
179
|
-
slug: r.slug,
|
|
180
|
-
state: mapExternalState(r.status),
|
|
181
|
-
status: r.status,
|
|
182
|
-
mode: r.mode,
|
|
183
|
-
duration: computeElapsedSeconds(r),
|
|
184
|
-
model: r.model,
|
|
185
|
-
totalTokens: r.totalTokens,
|
|
186
|
-
sessionFile: r.sessionFile,
|
|
187
|
-
parent: r.parentRecordId,
|
|
188
|
-
resumable: isResumable(r),
|
|
189
|
-
outcome: projectOutcome(r),
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// ============================================================
|
|
194
|
-
// start handler
|
|
195
|
-
// ============================================================
|
|
196
|
-
|
|
197
|
-
export async function startHandler(
|
|
198
|
-
service: SubagentService,
|
|
199
|
-
input: StartHandlerInput | undefined,
|
|
200
|
-
signal: AbortSignal | undefined,
|
|
201
|
-
ctxModel?: ModelInfo,
|
|
202
|
-
): Promise<StartHandlerResult> {
|
|
203
|
-
if (!input) throw new Error(
|
|
204
|
-
"action:'start' requires task and slug (top-level fields). " +
|
|
205
|
-
'Correct: {"action":"start","task":"<your task>","slug":"<kebab-case>"}',
|
|
206
|
-
);
|
|
207
|
-
// task 必填 + 空白校验(G-008)
|
|
208
|
-
const task = input.task?.trim();
|
|
209
|
-
if (!task) throw new Error(
|
|
210
|
-
"task is required for action:'start' (top-level field, must not be whitespace-only). " +
|
|
211
|
-
'Correct: {"action":"start","task":"...","slug":"..."}',
|
|
212
|
-
);
|
|
213
|
-
// slug 必填 + 空白校验 + 长度校验(≤ SLUG_MAX_LENGTH 字符)
|
|
214
|
-
const slug = input.slug?.trim();
|
|
215
|
-
if (!slug) throw new Error(
|
|
216
|
-
"slug is required for action:'start' (top-level field, must not be whitespace-only). " +
|
|
217
|
-
'Correct: {"action":"start","task":"...","slug":"<kebab-case>"}',
|
|
218
|
-
);
|
|
219
|
-
if (slug.length > SLUG_MAX_LENGTH) throw new Error(`slug must be ≤${SLUG_MAX_LENGTH} chars (got ${slug.length}). Shorten to a kebab-case label, e.g. "fix-login", "extract-urls".`);
|
|
220
|
-
|
|
221
|
-
const handle = await service.execute({
|
|
222
|
-
task,
|
|
223
|
-
slug,
|
|
224
|
-
agent: input.agent,
|
|
225
|
-
model: input.model,
|
|
226
|
-
thinkingLevel: input.thinkingLevel,
|
|
227
|
-
skillPath: input.skillPath,
|
|
228
|
-
appendSystemPrompt: input.appendSystemPrompt,
|
|
229
|
-
schema: input.schema,
|
|
230
|
-
maxTurns: input.maxTurns,
|
|
231
|
-
graceTurns: input.graceTurns,
|
|
232
|
-
fork: input.fork,
|
|
233
|
-
worktree: input.worktree,
|
|
234
|
-
cwd: input.cwd,
|
|
235
|
-
conversation: input.conversation,
|
|
236
|
-
idleTimeoutMs: input.idleTimeoutMs,
|
|
237
|
-
engine: input.engine,
|
|
238
|
-
ctxModel,
|
|
239
|
-
signal,
|
|
240
|
-
// background detached 运行,完成由 notify 驱动新 turn。
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
kind: "bg",
|
|
245
|
-
subagentId: handle.subagentId,
|
|
246
|
-
sessionFile: handle.sessionFile,
|
|
247
|
-
slug: handle.details.slug,
|
|
248
|
-
// [U1] registry 全等回显:record.model 由 resolved(裁决放行条目)拼接,原样透出。
|
|
249
|
-
model: handle.details.model,
|
|
250
|
-
response: {
|
|
251
|
-
status: "running",
|
|
252
|
-
mode: "background",
|
|
253
|
-
message: BG_MESSAGE,
|
|
254
|
-
notifyContract: NOTIFY_CONTRACT,
|
|
255
|
-
},
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// ============================================================
|
|
260
|
-
// list handler
|
|
261
|
-
// ============================================================
|
|
262
|
-
|
|
263
|
-
export function listHandler(
|
|
264
|
-
service: SubagentService,
|
|
265
|
-
input: ListHandlerInput | undefined,
|
|
266
|
-
): ListHandlerResult {
|
|
267
|
-
const includeFinished = input?.includeFinished === true;
|
|
268
|
-
// limit 夹紧:默认 20,范围 [1, 100]
|
|
269
|
-
const rawLimit = input?.limit ?? DEFAULT_LIST_LIMIT;
|
|
270
|
-
const limit = Math.max(1, Math.min(rawLimit, MAX_LIST_LIMIT));
|
|
271
|
-
|
|
272
|
-
// collectRecords 是 service 核心能力:statusFilter 决定 running-only 还是全部。
|
|
273
|
-
// 防截断(先多取再过滤)已下沉到 store 层——这里直接传 limit + filter。
|
|
274
|
-
const filter = includeFinished ? "all" : "running";
|
|
275
|
-
const all = service.collectRecords(limit, filter);
|
|
276
|
-
// [perf] collectRecords 磁盘源是 light(无 totalTokens/model 等):SubagentListItem 对
|
|
277
|
-
// LLM 消费方暴露 totalTokens/model,逐项 getFullRecord 补全(per-file 缓存,仅首次
|
|
278
|
-
// 全量解析;显式 tool 调用非渲染热路径,成本可接受)。
|
|
279
|
-
const items: SubagentListItem[] = all.map((r) =>
|
|
280
|
-
recordToListItem(service.getFullRecord(r.id) ?? r),
|
|
281
|
-
);
|
|
282
|
-
const running = items.filter((i) => i.status === "running").length;
|
|
283
|
-
|
|
284
|
-
return { response: { running, items } };
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// ============================================================
|
|
288
|
-
// cancel handler
|
|
289
|
-
// ============================================================
|
|
290
|
-
|
|
291
|
-
export async function cancelHandler(
|
|
292
|
-
service: SubagentService,
|
|
293
|
-
input: CancelHandlerInput | undefined,
|
|
294
|
-
): Promise<CancelHandlerResult> {
|
|
295
|
-
const id = input?.subagentId?.trim();
|
|
296
|
-
if (!id) throw new Error("cancelParam.subagentId is required for action:'cancel'");
|
|
297
|
-
|
|
298
|
-
// step 1: id 不存在(findRecord 只查内存 running record,不从 session.jsonl 重建)
|
|
299
|
-
const rec = service.findRecord(id);
|
|
300
|
-
if (!rec) {
|
|
301
|
-
// [S-19] MF-1 全树可见后,list/completion 可能列出其他进程(父/兄弟)的 running record
|
|
302
|
-
//(collectRecords 扫共享 sessionsDir 按 rootSessionId 过滤,跨进程互相可见),而 cancel
|
|
303
|
-
// 只作用于本进程内存 record。区分两种失败,避免「may have finished」误导(该 record 正
|
|
304
|
-
// 被列出且未 finished,只是不属于本进程内存)。仅文案区分,不改 cancel 作用域。
|
|
305
|
-
const treeRec = service.collectRecords(DEFAULT_LIST_LIMIT, "all").find((r) => r.id === id);
|
|
306
|
-
if (treeRec && treeRec.status === "running") {
|
|
307
|
-
throw new Error(
|
|
308
|
-
`Subagent record "${id}" is running but owned by another process in the tree ` +
|
|
309
|
-
`(it was spawned by a different subagent process) — this process cannot cancel it; ` +
|
|
310
|
-
`cancel only works for subagents spawned by the current process.`,
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
throw new Error(`No subagent record with id "${id}". It may have finished — use action:'list' with includeFinished:true to verify.`);
|
|
314
|
-
}
|
|
315
|
-
// step 2: controller 检查(controller 为 undefined 表示 record 已终态或未启动)
|
|
316
|
-
if (rec.mode !== "background") {
|
|
317
|
-
throw new Error(`Cannot cancel subagent ${id} (unsupported mode: ${rec.mode})`);
|
|
318
|
-
}
|
|
319
|
-
// 对话模式 cancel = close(force:true) 别名(设计决策 5):chatMode record(running/idle)
|
|
320
|
-
// 走 close 行为路径(idle 终态化 done;running 立即 SIGTERM cancelled),
|
|
321
|
-
// 返回 cancel 响应(向后兼容 cancel action 的返回类型)。非 chatMode 保持现有 cancel 行为。
|
|
322
|
-
if (rec.chatMode) {
|
|
323
|
-
const chatRecord = service.getRecordForAction(id);
|
|
324
|
-
await service.closeSubagent(chatRecord, true);
|
|
325
|
-
return { subagentId: id, response: { cancelled: true } };
|
|
326
|
-
}
|
|
327
|
-
// step 3: service.cancel boolean(list-view 契约不变);false = 已终态(CAS 抢锁失败)。
|
|
328
|
-
// 注意:不嵌入 rec.status——findRecord 快照可能已过期(TOCTOU:cancel 期间 detached
|
|
329
|
-
// 路径 CAS 到 done/failed)。重新查当前状态,避免「status: running」与「already finished」矛盾。
|
|
330
|
-
if (!service.cancel(id)) {
|
|
331
|
-
// CAS 失败 = record 在 cancel 期间被 detached 路径 finalize(done/failed)。
|
|
332
|
-
// re-query 查当前真实状态。终态 record 被 archive 立即移出内存,
|
|
333
|
-
// 诚实报告 "unknown (evicted from memory)" 而非回落到可能过期的 rec.status(BL-3)。
|
|
334
|
-
const now = service.findRecord(id);
|
|
335
|
-
const statusDesc = now ? now.status : "unknown (evicted from memory)";
|
|
336
|
-
throw new Error(`Subagent ${id} could not be cancelled (it likely just finished; status: ${statusDesc})`);
|
|
337
|
-
}
|
|
338
|
-
return { subagentId: id, response: { cancelled: true } };
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// ============================================================
|
|
342
|
-
// message handler(M2-B3 对话模式续聊/插入)
|
|
343
|
-
// ============================================================
|
|
344
|
-
|
|
345
|
-
export interface MessageHandlerInput {
|
|
346
|
-
subagentId?: string;
|
|
347
|
-
text?: string;
|
|
348
|
-
interrupt?: boolean;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/** message 领域对象(adapter 包成 messageResponse)。
|
|
352
|
-
* slug 来自 record(GUI /subagents message 通道的留痕 details 需要,设计 §3.3.3),
|
|
353
|
-
* 避免调用方二次 getRecordForAction 查询。 */
|
|
354
|
-
export type MessageHandlerResult = {
|
|
355
|
-
kind: "message";
|
|
356
|
-
subagentId: string;
|
|
357
|
-
slug: string;
|
|
358
|
-
response: MessageResponse;
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* message action handler:向对话模式 subagent 续聊/插入消息。
|
|
363
|
-
*
|
|
364
|
-
* 状态 × interrupt 自动映射(agent 只表达意图):
|
|
365
|
-
* running → deliverMessage 热路径(进程活:prompt + streamingBehavior,interrupt=true
|
|
366
|
-
* 抢占 / false 排队,pi 权威裁决 busy/idle)
|
|
367
|
-
* 进程死 → deliverMessage 冷路径(resumeRound 重开 session + prompt,interrupt 自动
|
|
368
|
-
* 退化,agent 无感)
|
|
369
|
-
* 终态 → throw ended(正常路径不命中——终态 record 已 archive,getRecordForAction 先 throw not found)
|
|
370
|
-
* (旧 deliverToRunning busy 投递已删除——SP-5 upgrade 后 running 恒走 deliverMessage)
|
|
371
|
-
*
|
|
372
|
-
* 归属守卫(决策 3):getRecordForAction 内部校验 rootSessionId。
|
|
373
|
-
*
|
|
374
|
-
* @throws Error subagentId/text 缺失 / 不存在或非本 session 所有 / 已结束
|
|
375
|
-
*/
|
|
376
|
-
export async function messageHandler(
|
|
377
|
-
service: SubagentService,
|
|
378
|
-
input: MessageHandlerInput | undefined,
|
|
379
|
-
): Promise<MessageHandlerResult> {
|
|
380
|
-
const id = input?.subagentId?.trim();
|
|
381
|
-
if (!id) throw new Error("messageParam.subagentId is required for action:'message'");
|
|
382
|
-
const text = input?.text?.trim();
|
|
383
|
-
if (!text) throw new Error(
|
|
384
|
-
"messageParam.text is required for action:'message' (must not be whitespace-only). " +
|
|
385
|
-
'Correct: {"action":"message","messageParam":{"subagentId":"sa-...","text":"your follow-up"}}',
|
|
386
|
-
);
|
|
387
|
-
const interrupt = input?.interrupt === true;
|
|
388
|
-
|
|
389
|
-
// 归属守卫(决策 3):getRecordForAction 内部校验 rootSessionId
|
|
390
|
-
const record = service.getRecordForAction(id);
|
|
391
|
-
|
|
392
|
-
// SP-5 one-shot upgrade:非 chatMode 的 active record(running/idle)收到 message 时
|
|
393
|
-
// 自动升级为 chatMode,后续走 deliverMessage 统一投递路径(热路径或冷路径 resume)。
|
|
394
|
-
// closed/cancelled 终态 record 不可 upgrade(getRecordForAction 已抛 not found)。
|
|
395
|
-
// chatMode 是 ExecutionRecord 的 readonly 字段,用 Mutable<T> 显式断言绕过 readonly 约束(upgrade 语义)。
|
|
396
|
-
// Object.assign 隐式绕过 readonly 不可追踪,改为单字段显式赋值。
|
|
397
|
-
// [v4 A-3] 进程内 upgrade 入口(SP-5)——one-shot 首条 message 触发 upgrade 置位
|
|
398
|
-
// chatMode=true。与 subagent-service.ts getRecordForAction 磁盘重建(跨重启恢复入口)
|
|
399
|
-
// 分工:本入口服务进程内 one-shot,跨重启路径恒被 getRecordForAction 磁盘重建绕过
|
|
400
|
-
// (该处无条件 chatMode=true)。改动这两处必须协同,带 S3 回归。
|
|
401
|
-
if (!record.chatMode && record.status === "running") {
|
|
402
|
-
type Mutable<T> = { -readonly [K in keyof T]: T[K] };
|
|
403
|
-
(record as Mutable<ExecutionRecord>).chatMode = true;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// [V2 决策 3] chatMode 统一投递:按进程死活分流(热路径 prompt+streamingBehavior / 冷路径 resume),
|
|
407
|
-
// 不按 record.status(V2 进程长驻,idle 态进程仍活,续聊走热路径 prompt 而非重开 session)。
|
|
408
|
-
// SP-5:upgrade 后 record.chatMode 已为 true,统一进此分支。
|
|
409
|
-
if (record.chatMode) {
|
|
410
|
-
await service.deliverMessage(record, text, interrupt);
|
|
411
|
-
} else {
|
|
412
|
-
// 终态(closed/cancelled):防御性兜底(终态 record 已 archive,正常走 not found)
|
|
413
|
-
throw new Error(
|
|
414
|
-
`subagent ${id} has ended (status: ${record.status}), cannot message. ` +
|
|
415
|
-
`Recovery: use action:'close' to clean up, then action:'start' a new subagent.`,
|
|
416
|
-
);
|
|
417
|
-
}
|
|
418
|
-
return { kind: "message", subagentId: id, slug: record.slug, response: { delivered: true } };
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// ============================================================
|
|
422
|
-
// close handler(M2-B3 对话模式结束)
|
|
423
|
-
// ============================================================
|
|
424
|
-
|
|
425
|
-
export interface CloseHandlerInput {
|
|
426
|
-
subagentId?: string;
|
|
427
|
-
force?: boolean;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/** close 领域对象(adapter 包成 closeResponse)。 */
|
|
431
|
-
export type CloseHandlerResult = {
|
|
432
|
-
kind: "close";
|
|
433
|
-
subagentId: string;
|
|
434
|
-
response: CloseResponse;
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* close action handler:结束 subagent(对话模式为主,one-shot 同样支持)。
|
|
439
|
-
*
|
|
440
|
-
* force 语义(设计决策 5/10,v4 B-1 两态收敛 + M5 修正):
|
|
441
|
-
* force:false(默认)= 优雅关闭——
|
|
442
|
-
* 无在跑轮(等待续聊 timer armed / 无活进程)→ 立即终态化(closed + user-close,回收保活进程)
|
|
443
|
-
* 有活进程在跑轮 → 置 closeAfterRound,轮完成时终态化(chatMode 消费点 onRoundSettled,
|
|
444
|
-
* one-shot 在 runAndFinalize 轮完成分支)——返回 {closed:true} 即承诺轮结束后资源已释放
|
|
445
|
-
* force:true = 立即终止——running 立即 SIGTERM(cancelBackground 显式 kill)+ closed+cancelled
|
|
446
|
-
*
|
|
447
|
-
* 行为分流委托 service.closeSubagent(归属守卫由 getRecordForAction 把关)。
|
|
448
|
-
* 已终态 record 由 getRecordForAction throw not found(「已结束的不能再操作」语义)。
|
|
449
|
-
*/
|
|
450
|
-
export async function closeHandler(
|
|
451
|
-
service: SubagentService,
|
|
452
|
-
input: CloseHandlerInput | undefined,
|
|
453
|
-
): Promise<CloseHandlerResult> {
|
|
454
|
-
const id = input?.subagentId?.trim();
|
|
455
|
-
if (!id) throw new Error("closeParam.subagentId is required for action:'close'");
|
|
456
|
-
const force = input?.force === true;
|
|
457
|
-
|
|
458
|
-
// 归属守卫(决策 3)+ 行为分流(service.closeSubagent)
|
|
459
|
-
const record = service.getRecordForAction(id);
|
|
460
|
-
await service.closeSubagent(record, force);
|
|
461
|
-
|
|
462
|
-
return { kind: "close", subagentId: id, response: { closed: true } };
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// ============================================================
|
|
466
|
-
// adapter(领域对象 → SubagentToolResult + {content, details})
|
|
467
|
-
// ============================================================
|
|
468
|
-
|
|
469
78
|
/**
|
|
470
79
|
* action ↔ domain 配对的承重类型(替代三处松散 `as`)。
|
|
471
80
|
* 调用方必须传匹配的 {action, domain}——TS 在调用点校验,错配编译报错。
|
|
@@ -475,7 +84,12 @@ type AdapterInput =
|
|
|
475
84
|
| { action: "list"; domain: ListHandlerResult }
|
|
476
85
|
| { action: "cancel"; domain: CancelHandlerResult }
|
|
477
86
|
| { action: "message"; domain: MessageHandlerResult }
|
|
478
|
-
| { action: "close"; domain: CloseHandlerResult }
|
|
87
|
+
| { action: "close"; domain: CloseHandlerResult }
|
|
88
|
+
| { action: "fork-from"; domain: ForkFromHandlerResult };
|
|
89
|
+
|
|
90
|
+
// ============================================================
|
|
91
|
+
// adapter(领域对象 → SubagentToolResult + {content, details})
|
|
92
|
+
// ============================================================
|
|
479
93
|
|
|
480
94
|
export function adapter(
|
|
481
95
|
input: AdapterInput,
|
|
@@ -495,6 +109,11 @@ export function adapter(
|
|
|
495
109
|
result = { action, subagentId: input.domain.subagentId, sessionFile: null, cancelResponse: input.domain.response };
|
|
496
110
|
} else if (action === "message") {
|
|
497
111
|
result = { action, subagentId: input.domain.subagentId, sessionFile: null, messageResponse: input.domain.response };
|
|
112
|
+
} else if (action === "fork-from") {
|
|
113
|
+
// MF-3 同款瘦身:sourceSessionFile 真实路径只在 forkFromResponse 内层(LLM 接续
|
|
114
|
+
// 不需要拼路径,需要时 list/details 可取);顶层 sessionFile 保持 null 一致性。
|
|
115
|
+
const d = input.domain;
|
|
116
|
+
result = { action, subagentId: d.subagentId, sessionFile: null, forkFromResponse: d.response };
|
|
498
117
|
} else {
|
|
499
118
|
// action === "close"
|
|
500
119
|
result = { action, subagentId: input.domain.subagentId, sessionFile: null, closeResponse: input.domain.response };
|
|
@@ -565,6 +184,14 @@ export function buildGuiComponent(
|
|
|
565
184
|
items: [{ label: "messaged", value: input.domain.subagentId, severity: "ok" }],
|
|
566
185
|
});
|
|
567
186
|
}
|
|
187
|
+
if (action === "fork-from") {
|
|
188
|
+
return guiComponent("stats-line", {
|
|
189
|
+
items: [
|
|
190
|
+
{ label: "forked-from", value: input.domain.sourceSessionFile },
|
|
191
|
+
{ label: "new subagent", value: input.domain.subagentId, severity: "ok" },
|
|
192
|
+
],
|
|
193
|
+
});
|
|
194
|
+
}
|
|
568
195
|
if (action === "close") {
|
|
569
196
|
return guiComponent("stats-line", {
|
|
570
197
|
items: [{ label: "closed", value: input.domain.subagentId, severity: "warn" }],
|
|
@@ -12,22 +12,18 @@
|
|
|
12
12
|
// 编译本 schema 并断言 required/description/enum/pattern 存活——SW 自身测试环境
|
|
13
13
|
// 把 typebox alias 到 mock(丢 options),SO 侧测试以真实构造为对照基准。
|
|
14
14
|
//
|
|
15
|
-
// 层归属:Interface(工具 schema 的家)。SLUG_MAX_LENGTH
|
|
16
|
-
//
|
|
17
|
-
//
|
|
15
|
+
// 层归属:Interface(工具 schema 的家)。SLUG_MAX_LENGTH 权威定义回归 core 侧
|
|
16
|
+
// execution/execute-options-mapper.ts(subagent-core 包抽离 u1-move:core 切面不得
|
|
17
|
+
// 反向 import 壳侧 interface,常量随之内化)——此处 re-export 保持既有 import 路径。
|
|
18
18
|
|
|
19
19
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
20
|
-
import {
|
|
20
|
+
import { Type } from "typebox";
|
|
21
21
|
|
|
22
|
-
import { THINKING_ORDER } from "
|
|
22
|
+
import { THINKING_ORDER } from "@zhushanwen/subagent-core/shared/model-ref.ts";
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* 历史值 20 偏紧——描述性 slug 如 "audit-structured-output"(23)/"fix-subagent-wf-tools"(21)
|
|
28
|
-
* 会撞上限,放宽到 35 兼顾「短到能塞进 TUI 标题行」与「容纳合理描述性 kebab-case 名」。
|
|
29
|
-
*/
|
|
30
|
-
export const SLUG_MAX_LENGTH = 35;
|
|
24
|
+
import { SLUG_MAX_LENGTH } from "@zhushanwen/subagent-core/execution/execute-options-mapper.ts";
|
|
25
|
+
|
|
26
|
+
export { SLUG_MAX_LENGTH };
|
|
31
27
|
|
|
32
28
|
// Params schema(跨包契约测试的真实 typebox 校验入口)。
|
|
33
29
|
//
|
|
@@ -42,8 +38,8 @@ export const SLUG_MAX_LENGTH = 35;
|
|
|
42
38
|
// (subagent_start / subagent_list / subagent_cancel),让每个 tool 的 schema 真实
|
|
43
39
|
// 反映必填性。勿在此基础上继续堆 action 条件逻辑——要加就拆 tool。
|
|
44
40
|
export const SubagentParams = Type.Object({
|
|
45
|
-
action: StringEnum(["start", "list", "cancel", "message", "close"], {
|
|
46
|
-
description: "Operation: 'start' runs a subagent, 'list' shows subagents, 'cancel' stops a background subagent, 'message' sends a follow-up to a running subagent (one-shot subagents are auto-upgraded to conversation mode on first message), 'close' ends a running subagent (conversation-mode or one-shot).",
|
|
41
|
+
action: StringEnum(["start", "list", "cancel", "message", "close", "fork-from"], {
|
|
42
|
+
description: "Operation: 'start' runs a subagent, 'list' shows subagents, 'cancel' stops a background subagent, 'message' sends a follow-up to a running subagent (one-shot subagents are auto-upgraded to conversation mode on first message), 'close' ends a running subagent (conversation-mode or one-shot), 'fork-from' spawns a NEW subagent inheriting an older one's history (recovery for restart-disconnected subagents; the old record is untouched).",
|
|
47
43
|
}),
|
|
48
44
|
// ── action:"start" fields (flattened to top level). task/slug REQUIRED for start. ──
|
|
49
45
|
// Missing/empty task or slug throws at runtime (startHandler).
|
|
@@ -150,7 +146,15 @@ export const SubagentParams = Type.Object({
|
|
|
150
146
|
description: "If true, terminate immediately even if mid-round (in-progress work is lost). If false (default), let the current round finish, then close. When idle, the subagent closes immediately regardless.",
|
|
151
147
|
})),
|
|
152
148
|
})),
|
|
149
|
+
// action:"fork-from" → forkFromParam.sourceSubagentId REQUIRED ([v8.5 B] 断联恢复通道).
|
|
150
|
+
// 从旧 subagent 的会话历史 spawn 新 id:新进程 --fork 指向旧 session 文件(copy-on-write,
|
|
151
|
+
// 源文件只读不续写);旧记录/状态机不动。pi 引擎限定(非 pi 在 execute 层拒绝)。
|
|
152
|
+
forkFromParam: Type.Optional(Type.Object({
|
|
153
|
+
sourceSubagentId: Type.String({
|
|
154
|
+
description: "REQUIRED for action:'fork-from'. The OLD subagentId whose conversation history becomes the inherited context of the new subagent. Works for records disconnected by a session restart or already finished; cancelled/worktree-bound/still-running ones are rejected with guidance.",
|
|
155
|
+
}),
|
|
156
|
+
prompt: Type.Optional(Type.String({
|
|
157
|
+
description: "Continuation instruction for the new subagent (what to do next on top of the inherited history). When omitted, a standard handover frame is injected: reconstruct done/decided/remaining from the inherited history, then continue to completion. Whitespace-only treated as omitted.",
|
|
158
|
+
})),
|
|
159
|
+
})),
|
|
153
160
|
});
|
|
154
|
-
|
|
155
|
-
/** Params schema 的 Static 投影(消费方经 `Static<typeof SubagentParams>` 使用,见 subagent-tool.ts)。 */
|
|
156
|
-
export type SubagentParamsStatic = Static<typeof SubagentParams>;
|