@zhushanwen/pi-subagent-workflow 8.5.0 → 8.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/package.json +13 -16
- package/relay/relay.mjs +1 -1
- package/src/host/__tests__/pi-host.test.ts +214 -0
- package/src/host/pi-host.ts +109 -0
- package/src/index.ts +142 -32
- package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
- package/src/injectors/__tests__/engine-section-stability.test.ts +341 -0
- package/src/injectors/__tests__/subagent-list-injector.test.ts +5 -5
- package/src/injectors/__tests__/workflow-list-injector.test.ts +5 -5
- package/src/injectors/engine-awareness.ts +123 -0
- package/src/injectors/model-list-injector.ts +1 -1
- package/src/injectors/subagent-list-injector.ts +8 -8
- package/src/injectors/workflow-list-injector.ts +8 -8
- package/src/interface/__tests__/detectors.test.ts +3 -3
- package/src/interface/__tests__/subagent-tool-path-guard.test.ts +157 -0
- package/src/interface/__tests__/subagent-tool-prompt.test.ts +12 -0
- package/src/interface/__tests__/tool-workflow-script-generate.test.ts +2 -2
- package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +1 -1
- package/src/interface/bg-notify-render.ts +34 -13
- package/src/interface/commands.ts +3 -3
- package/src/interface/format.ts +2 -2
- package/src/interface/helpers.ts +3 -3
- package/src/interface/list-component.ts +4 -4
- package/src/interface/list-shared.ts +2 -2
- package/src/interface/list-view.ts +2 -2
- package/src/interface/subagent-actions.ts +288 -19
- package/src/interface/subagent-tool-schema.ts +163 -0
- package/src/interface/subagent-tool.ts +65 -129
- package/src/interface/subagents.ts +5 -5
- package/src/interface/tool-render.ts +34 -2
- package/src/interface/tool-workflow-script.ts +4 -4
- package/src/interface/tool-workflow.ts +6 -6
- package/src/interface/views/WorkflowsView.ts +5 -5
- 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 +4 -4
- package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +132 -18
- 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 -256
- package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
- package/src/execution/__tests__/chat-engine-routing.test.ts +0 -597
- 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 -385
- 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 -189
- package/src/execution/__tests__/execution-record.test.ts +0 -1284
- 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 -138
- 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 -238
- 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 -593
- package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
- package/src/execution/__tests__/lifecycle-manager.test.ts +0 -337
- 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 -109
- package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
- package/src/execution/__tests__/model-resolver.test.ts +0 -413
- 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 -574
- package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
- package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
- package/src/execution/__tests__/output-collector.test.ts +0 -61
- 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 -644
- 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__/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 -311
- package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
- package/src/execution/__tests__/spawn-args.test.ts +0 -434
- 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__/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 -506
- package/src/execution/__tests__/temp-prompt.test.ts +0 -53
- package/src/execution/__tests__/timeout-integration.test.ts +0 -397
- package/src/execution/__tests__/tombstone-store.test.ts +0 -73
- package/src/execution/__tests__/tool-action.test.ts +0 -385
- 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 -193
- package/src/execution/agent-result-mapper.ts +0 -90
- package/src/execution/alive-store.ts +0 -92
- package/src/execution/argv-mirror.ts +0 -109
- 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 -567
- 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 -648
- 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 -304
- package/src/execution/execute-options-mapper.ts +0 -111
- package/src/execution/execution-record.ts +0 -906
- 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 -491
- package/src/execution/lifecycle-predicates.ts +0 -65
- package/src/execution/manifest-store.ts +0 -256
- package/src/execution/model-config-service.ts +0 -204
- package/src/execution/model-resolver.ts +0 -276
- package/src/execution/notifier.ts +0 -260
- package/src/execution/output-collector.ts +0 -88
- 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 -1548
- 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 -2119
- package/src/execution/subprocess-agent-runner.ts +0 -303
- 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 -910
- 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 -174
- 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 -336
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -208
- package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -157
- package/src/orchestration/__tests__/args-validator.test.ts +0 -143
- package/src/orchestration/__tests__/concurrency-gate.test.ts +0 -125
- package/src/orchestration/__tests__/config-loader.test.ts +0 -503
- package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -724
- 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 -314
- package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
- package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -277
- package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
- package/src/orchestration/__tests__/lifecycle.test.ts +0 -625
- package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -1971
- package/src/orchestration/__tests__/script-lint.test.ts +0 -831
- package/src/orchestration/__tests__/skill-discovery.test.ts +0 -157
- package/src/orchestration/__tests__/test-mocks.ts +0 -197
- 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 -520
- package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
- package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -110
- 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 -93
- package/src/orchestration/args-validator.ts +0 -127
- package/src/orchestration/concurrency-gate.ts +0 -69
- package/src/orchestration/config-loader.ts +0 -315
- package/src/orchestration/error-recovery.ts +0 -862
- package/src/orchestration/execute-agent-call.ts +0 -217
- package/src/orchestration/launcher.ts +0 -410
- package/src/orchestration/lifecycle.ts +0 -396
- package/src/orchestration/models/__tests__/budget.test.ts +0 -367
- 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 -148
- package/src/orchestration/models/ports.ts +0 -164
- package/src/orchestration/models/run-runtime.ts +0 -89
- 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 -292
- 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 -92
- package/src/orchestration/worker-handle.ts +0 -115
- package/src/orchestration/worker-host.ts +0 -98
- package/src/orchestration/worker-script-builder.ts +0 -408
- 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__/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/agent-event.ts +0 -13
- package/src/shared/agent-ref.ts +0 -57
- package/src/shared/meta-parser.ts +0 -261
- package/src/shared/resource-discovery.ts +0 -811
- package/src/shared/resource-meta.ts +0 -65
- package/src/shared/schema-jsonify.ts +0 -56
- 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 -1307
- package/workflows/review-fix-loop.js +0 -1396
- package/workflows/scatter-gather.js +0 -178
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/pi-subagent-workflow",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"description": "Unified subagent execution and multi-agent workflow orchestration for Pi — spawned-process agent runtime with sync/background modes, stateful workflow management with persistence, state machine, and execution tracing.",
|
|
@@ -21,15 +21,13 @@
|
|
|
21
21
|
"index.ts",
|
|
22
22
|
"agents/",
|
|
23
23
|
"skills/",
|
|
24
|
-
"workflows/",
|
|
25
24
|
"scripts/",
|
|
26
25
|
"relay/",
|
|
27
26
|
"src/index.ts",
|
|
28
|
-
"src/
|
|
27
|
+
"src/jsonl-run-store.ts",
|
|
28
|
+
"src/host/",
|
|
29
29
|
"src/injectors/",
|
|
30
|
-
"src/
|
|
31
|
-
"src/interface/",
|
|
32
|
-
"src/shared/"
|
|
30
|
+
"src/interface/"
|
|
33
31
|
],
|
|
34
32
|
"xyz-agent": {
|
|
35
33
|
"role": "universal",
|
|
@@ -59,20 +57,18 @@
|
|
|
59
57
|
]
|
|
60
58
|
},
|
|
61
59
|
"dependencies": {
|
|
62
|
-
"
|
|
63
|
-
"yaml": "^2.9.0",
|
|
64
|
-
"@xyz-agent/session-delivery": "0.2.0",
|
|
60
|
+
"@xyz-agent/session-delivery": "0.3.0",
|
|
65
61
|
"@zhushanwen/pi-extension-logger": "0.3.0",
|
|
66
62
|
"@xyz-agent/extension-protocol": "0.7.0",
|
|
67
|
-
"@zhushanwen/
|
|
63
|
+
"@zhushanwen/subagent-core": "0.2.0"
|
|
68
64
|
},
|
|
69
65
|
"peerDependencies": {
|
|
70
|
-
"@earendil-works/pi-ai": "^0.84.
|
|
71
|
-
"@earendil-works/pi-coding-agent": "^0.84.
|
|
72
|
-
"@earendil-works/pi-tui": "^0.84.
|
|
66
|
+
"@earendil-works/pi-ai": "^0.84.4",
|
|
67
|
+
"@earendil-works/pi-coding-agent": "^0.84.4",
|
|
68
|
+
"@earendil-works/pi-tui": "^0.84.4",
|
|
73
69
|
"typebox": "*",
|
|
74
|
-
"@zhushanwen/pi-pending-notifications": "0.
|
|
75
|
-
"@zhushanwen/pi-structured-output": "5.0
|
|
70
|
+
"@zhushanwen/pi-pending-notifications": "0.5.0",
|
|
71
|
+
"@zhushanwen/pi-structured-output": "5.1.0"
|
|
76
72
|
},
|
|
77
73
|
"peerDependenciesMeta": {
|
|
78
74
|
"@earendil-works/pi-coding-agent": {
|
|
@@ -89,6 +85,7 @@
|
|
|
89
85
|
},
|
|
90
86
|
"scripts": {
|
|
91
87
|
"typecheck": "npx tsc --noEmit",
|
|
92
|
-
"test": "vitest run"
|
|
88
|
+
"test": "vitest run",
|
|
89
|
+
"test:isolated": "env $(env | grep -o '^PI_SUBAGENT_[A-Z_]*' | sed 's/^/-u /' | tr '\n' ' ') vitest run"
|
|
93
90
|
}
|
|
94
91
|
}
|
package/relay/relay.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* 通道,payload 一律 base64 封装保字节精确。
|
|
9
9
|
*
|
|
10
10
|
* ============================ 镜像常量表 ============================
|
|
11
|
-
* SSOT = src/execution/relay-env.ts(零依赖脚本不能 import workspace 包,只能内嵌镜像;
|
|
11
|
+
* SSOT = packages/subagent-core/src/execution/relay-env.ts(零依赖脚本不能 import workspace 包,只能内嵌镜像;
|
|
12
12
|
* 改名/改值必须双侧同步,一致性由 E-3 conformance relay 变体断言锁定——设计 §10-5):
|
|
13
13
|
*
|
|
14
14
|
* | relay-env.ts 常量 | 本文件常量 | 值 |
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// pi-host.test.ts —— pi 壳宿主实现与现行为等价(u0-wire 验收①)。
|
|
2
|
+
//
|
|
3
|
+
// 三视角:①使用者——discoveryRoots 各 kind 的根清单/顺序/source 标签与
|
|
4
|
+
// resource-discovery.ts buildScanTargets(user-pi/npm/npm-dev 段)、
|
|
5
|
+
// skill-discovery.ts resolveSkillPath(skills 两根)现推导逐项一致;
|
|
6
|
+
// ②构建者——dataRoot/log/countActiveFromEntries/createDelivery 四端口桥接形态;
|
|
7
|
+
// ③观察者——getAgentDir 每次现取(PI_CODING_AGENT_DIR 实例隔离切换后重取生效,
|
|
8
|
+
// 无模块级缓存)。
|
|
9
|
+
//
|
|
10
|
+
// mock 策略:pi SDK / pi 宿主协作件全部 vi.mock 工厂覆盖(vitest alias 的
|
|
11
|
+
// mocks/ 桩只供其他测试族用,本文件需要可控返回值)。pending-notifications
|
|
12
|
+
// mock 返回 {count: n} 形状直接验证「适配读 .count」;session-delivery mock
|
|
13
|
+
// 验证 createDelivery 透传(参数 + 返回句柄)。
|
|
14
|
+
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
|
|
17
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
18
|
+
|
|
19
|
+
// ── hoisted mocks(vi.mock 工厂 hoisting 不能引用外部 let/const) ──
|
|
20
|
+
|
|
21
|
+
const piCodingAgentMock = vi.hoisted(() => ({
|
|
22
|
+
// 与实装版 getAgentDir 的 env 契约一致(PI_CODING_AGENT_DIR 实例隔离优先),
|
|
23
|
+
// 使「env 切换后重取生效」可直接断言;缺省值仅作 fallback。
|
|
24
|
+
getAgentDir: vi.fn(() => process.env.PI_CODING_AGENT_DIR ?? "/mock/default/agent-dir"),
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
const extensionLoggerMock = vi.hoisted(() => ({
|
|
28
|
+
getLogger: vi.fn(),
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
const pendingNotificationsMock = vi.hoisted(() => ({
|
|
32
|
+
countActiveFromEntries: vi.fn(),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
const sessionDeliveryMock = vi.hoisted(() => ({
|
|
36
|
+
createDelivery: vi.fn(),
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
vi.mock("@earendil-works/pi-coding-agent", () => piCodingAgentMock);
|
|
40
|
+
vi.mock("@zhushanwen/pi-extension-logger", () => extensionLoggerMock);
|
|
41
|
+
vi.mock("@zhushanwen/pi-pending-notifications", () => pendingNotificationsMock);
|
|
42
|
+
vi.mock("@xyz-agent/session-delivery", () => sessionDeliveryMock);
|
|
43
|
+
|
|
44
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
45
|
+
import { getLogger } from "@zhushanwen/pi-extension-logger";
|
|
46
|
+
import { countActiveFromEntries } from "@zhushanwen/pi-pending-notifications";
|
|
47
|
+
import { createDelivery } from "@xyz-agent/session-delivery";
|
|
48
|
+
|
|
49
|
+
import { createPiHostServices, createPiNotifyDomainPorts } from "../pi-host.ts";
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
vi.mocked(getAgentDir).mockClear();
|
|
53
|
+
vi.mocked(getLogger).mockReset();
|
|
54
|
+
vi.mocked(countActiveFromEntries).mockReset();
|
|
55
|
+
vi.mocked(createDelivery).mockReset();
|
|
56
|
+
delete process.env.PI_CODING_AGENT_DIR;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
vi.restoreAllMocks();
|
|
61
|
+
delete process.env.PI_CODING_AGENT_DIR;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("createPiHostServices.discoveryRoots(与现推导逐项一致)", () => {
|
|
65
|
+
// 基线锚点:resource-discovery.ts buildScanTargets(join(agentDir, kind) /
|
|
66
|
+
// join(agentDir, "npm", "node_modules") / join(agentDir, "extensions"))与
|
|
67
|
+
// skill-discovery.ts resolveSkillPath(join(getAgentDir(), "skills") +
|
|
68
|
+
// join(getAgentDir(), "npm/node_modules"))。根列表按优先级低→高排列(D2)。
|
|
69
|
+
const AGENT_DIR = "/fake/agent-dir";
|
|
70
|
+
|
|
71
|
+
function stubAgentDir(): void {
|
|
72
|
+
vi.mocked(getAgentDir).mockReturnValue(AGENT_DIR);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
it("agents 三根:顺序与 source 标签 = user-pi → npm → npm-dev", () => {
|
|
76
|
+
stubAgentDir();
|
|
77
|
+
const roots = createPiHostServices().discoveryRoots?.().agents;
|
|
78
|
+
|
|
79
|
+
expect(roots).toEqual([
|
|
80
|
+
{ dir: join(AGENT_DIR, "agents"), source: "user-pi" },
|
|
81
|
+
{ dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
|
|
82
|
+
{ dir: join(AGENT_DIR, "extensions"), source: "npm-dev" },
|
|
83
|
+
]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("workflows 三根:与 agents 同构,末级目录名切换为 workflows", () => {
|
|
87
|
+
stubAgentDir();
|
|
88
|
+
const roots = createPiHostServices().discoveryRoots?.().workflows;
|
|
89
|
+
|
|
90
|
+
expect(roots).toEqual([
|
|
91
|
+
{ dir: join(AGENT_DIR, "workflows"), source: "user-pi" },
|
|
92
|
+
{ dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
|
|
93
|
+
{ dir: join(AGENT_DIR, "extensions"), source: "npm-dev" },
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("skills 两根:user-pi + npm,无 npm-dev(对齐 skill-discovery 现状)", () => {
|
|
98
|
+
stubAgentDir();
|
|
99
|
+
const roots = createPiHostServices().discoveryRoots?.().skills;
|
|
100
|
+
|
|
101
|
+
expect(roots).toEqual([
|
|
102
|
+
{ dir: join(AGENT_DIR, "skills"), source: "user-pi" },
|
|
103
|
+
{ dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
|
|
104
|
+
]);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("每次调用现取 getAgentDir(agentDir 变更后根列表跟随,不缓存)", () => {
|
|
108
|
+
stubAgentDir();
|
|
109
|
+
const first = createPiHostServices().discoveryRoots?.().agents;
|
|
110
|
+
const secondCallDir = "/another/agent-dir";
|
|
111
|
+
vi.mocked(getAgentDir).mockReturnValue(secondCallDir);
|
|
112
|
+
const second = createPiHostServices().discoveryRoots?.().agents;
|
|
113
|
+
|
|
114
|
+
expect(second?.[0].dir).toBe(join(secondCallDir, "agents"));
|
|
115
|
+
expect(first?.[0].dir).not.toBe(second?.[0].dir);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("createPiHostServices.dataRoot(每次现取 getAgentDir)", () => {
|
|
120
|
+
it("返回 getAgentDir() 本身(env 覆盖段与 warn-once 留 core data-dir)", () => {
|
|
121
|
+
vi.mocked(getAgentDir).mockReturnValue("/data/root");
|
|
122
|
+
expect(createPiHostServices().dataRoot()).toBe("/data/root");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("PI_CODING_AGENT_DIR 切换后重取生效(实例隔离,无模块级缓存)", () => {
|
|
126
|
+
// 恢复 mock 工厂的 env 语义实现(其他用例的 mockReturnValue 会覆盖它)
|
|
127
|
+
vi.mocked(getAgentDir).mockImplementation(
|
|
128
|
+
() => process.env.PI_CODING_AGENT_DIR ?? "/mock/default/agent-dir",
|
|
129
|
+
);
|
|
130
|
+
process.env.PI_CODING_AGENT_DIR = "/instance-a";
|
|
131
|
+
const host = createPiHostServices();
|
|
132
|
+
expect(host.dataRoot()).toBe("/instance-a");
|
|
133
|
+
|
|
134
|
+
process.env.PI_CODING_AGENT_DIR = "/instance-b";
|
|
135
|
+
expect(host.dataRoot()).toBe("/instance-b");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("透传 getAgentDir 调用(不缓存结果、不吞调用)", () => {
|
|
139
|
+
vi.mocked(getAgentDir).mockReturnValue("/d1");
|
|
140
|
+
const host = createPiHostServices();
|
|
141
|
+
host.dataRoot();
|
|
142
|
+
host.dataRoot();
|
|
143
|
+
expect(vi.mocked(getAgentDir)).toHaveBeenCalledTimes(2);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("createPiHostServices.log(桥接 pi-extension-logger)", () => {
|
|
148
|
+
function stubLogger(): { debug: ReturnType<typeof vi.fn>; warn: ReturnType<typeof vi.fn>; error: ReturnType<typeof vi.fn> } {
|
|
149
|
+
const fake = { debug: vi.fn(), warn: vi.fn(), error: vi.fn() };
|
|
150
|
+
vi.mocked(getLogger).mockReturnValue(fake);
|
|
151
|
+
return fake;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
it("debug level → logger.debug,(message, data) 透传", () => {
|
|
155
|
+
const fake = stubLogger();
|
|
156
|
+
createPiHostServices().log("debug", "subagents", "d-msg", { k: 1 });
|
|
157
|
+
|
|
158
|
+
expect(vi.mocked(getLogger)).toHaveBeenCalledWith("subagents");
|
|
159
|
+
expect(fake.debug).toHaveBeenCalledWith("d-msg", { k: 1 });
|
|
160
|
+
expect(fake.warn).not.toHaveBeenCalled();
|
|
161
|
+
expect(fake.error).not.toHaveBeenCalled();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("warn level → logger.warn;error level → logger.error", () => {
|
|
165
|
+
const fake = stubLogger();
|
|
166
|
+
const host = createPiHostServices();
|
|
167
|
+
|
|
168
|
+
host.log("warn", "comp-a", "w-msg");
|
|
169
|
+
host.log("error", "comp-b", "e-msg", { reason: "x" });
|
|
170
|
+
|
|
171
|
+
expect(fake.warn).toHaveBeenCalledWith("w-msg", undefined);
|
|
172
|
+
expect(fake.error).toHaveBeenCalledWith("e-msg", { reason: "x" });
|
|
173
|
+
expect(vi.mocked(getLogger)).toHaveBeenNthCalledWith(1, "comp-a");
|
|
174
|
+
expect(vi.mocked(getLogger)).toHaveBeenNthCalledWith(2, "comp-b");
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe("createPiNotifyDomainPorts.countActiveFromEntries(适配读 .count)", () => {
|
|
179
|
+
it("拆 CountActiveResult.count 为 number(core 端口契约),entries 透传", () => {
|
|
180
|
+
const entries: unknown[] = [{ customType: "pending:register" }];
|
|
181
|
+
vi.mocked(countActiveFromEntries).mockReturnValue({ count: 3, ids: ["a", "b", "c"], entries: [] });
|
|
182
|
+
|
|
183
|
+
const result = createPiNotifyDomainPorts().countActiveFromEntries?.(entries);
|
|
184
|
+
|
|
185
|
+
expect(result).toBe(3);
|
|
186
|
+
expect(vi.mocked(countActiveFromEntries)).toHaveBeenCalledWith(entries);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("零活跃返回 0({count: 0} 形状)", () => {
|
|
190
|
+
vi.mocked(countActiveFromEntries).mockReturnValue({ count: 0, ids: [], entries: [] });
|
|
191
|
+
expect(createPiNotifyDomainPorts().countActiveFromEntries?.([])).toBe(0);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe("createPiNotifyDomainPorts.createDelivery(透传 session-delivery)", () => {
|
|
196
|
+
it("参数透传 + 返回句柄透传(不经包装)", () => {
|
|
197
|
+
const fakePort = {
|
|
198
|
+
supportedPayloads: ["text"] as const,
|
|
199
|
+
isIdle: () => true,
|
|
200
|
+
hasPendingMessages: () => false,
|
|
201
|
+
send: () => undefined,
|
|
202
|
+
};
|
|
203
|
+
const fakeConfig = { intent: "after-run" as const };
|
|
204
|
+
const fakeHandle = { send: () => {}, flush: () => {}, dispose: () => {} };
|
|
205
|
+
vi.mocked(createDelivery).mockReturnValue(fakeHandle);
|
|
206
|
+
|
|
207
|
+
const result = createPiNotifyDomainPorts().createDelivery?.(fakePort, fakeConfig);
|
|
208
|
+
|
|
209
|
+
expect(vi.mocked(createDelivery)).toHaveBeenCalledTimes(1);
|
|
210
|
+
expect(vi.mocked(createDelivery).mock.calls[0][0]).toBe(fakePort);
|
|
211
|
+
expect(vi.mocked(createDelivery).mock.calls[0][1]).toBe(fakeConfig);
|
|
212
|
+
expect(result).toBe(fakeHandle);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// src/host/pi-host.ts
|
|
2
|
+
//
|
|
3
|
+
// pi 壳宿主实现(subagent-core 包抽离 u0-wire)。设计权威源:
|
|
4
|
+
// docs/design/subagent-core-package-extraction.md §3.3 D2(含计划期契约细化 3 条)。
|
|
5
|
+
//
|
|
6
|
+
// 本文件属壳侧(shell),不进 core 切面——对 pi SDK 与 pi 宿主协作件
|
|
7
|
+
// (@earendil-works/pi-coding-agent / @zhushanwen/pi-extension-logger /
|
|
8
|
+
// @zhushanwen/pi-pending-notifications / @xyz-agent/session-delivery)的运行时
|
|
9
|
+
// import 收敛在此层,core 闭包(D9 守卫对象)不得出现这些包。
|
|
10
|
+
//
|
|
11
|
+
// 端口语义:
|
|
12
|
+
// - dataRoot / discoveryRoots 每次调用现取 getAgentDir(),禁止模块级缓存:
|
|
13
|
+
// getAgentDir 尊重 PI_CODING_AGENT_DIR 实例隔离(xyz-agent 按 session dir
|
|
14
|
+
// 隔离 pi 实例),缓存会把后续切换实例的进程钉死在首个 agentDir。
|
|
15
|
+
// - discoveryRoots 的根清单/顺序/source 标签与 shared/resource-discovery.ts
|
|
16
|
+
// buildScanTargets、orchestration/skill-discovery.ts resolveSkillPath 的现推导
|
|
17
|
+
// 逐项一致(user-pi / npm / npm-dev 字面即现 ResourceSource 标签)。
|
|
18
|
+
// project/workspace 根不在壳侧提供——core 消费方按 workspaceRoot 自行推导
|
|
19
|
+
// (u0-data-discovery 波次接注入消费)。
|
|
20
|
+
// - countActiveFromEntries 适配:pi 侧真函数返回 CountActiveResult 对象,core
|
|
21
|
+
// 端口契约是 number(core 消费面只读 .count,notify-ports.ts 契约注释)——
|
|
22
|
+
// foundation 单元登记给本单元的适配责任。
|
|
23
|
+
// - createDelivery 透传:@xyz-agent/session-delivery 的 createDelivery 与 core
|
|
24
|
+
// 的 Delivery* 结构化类型逐字段结构兼容(DeliveryHandle 的 sendChecked/depth
|
|
25
|
+
// 是结构超集成员,多不碍兼容)——结构兼容由本注入点 typecheck 守护,上游签名
|
|
26
|
+
// 漂移即红(notify-ports.ts「闭包红线」段)。
|
|
27
|
+
|
|
28
|
+
import { join } from "node:path";
|
|
29
|
+
|
|
30
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
31
|
+
import { getLogger } from "@zhushanwen/pi-extension-logger";
|
|
32
|
+
import { countActiveFromEntries } from "@zhushanwen/pi-pending-notifications";
|
|
33
|
+
import { createDelivery } from "@xyz-agent/session-delivery";
|
|
34
|
+
|
|
35
|
+
import type { DiscoveryRoot, HostServices } from "@zhushanwen/subagent-core/core/host-services.ts";
|
|
36
|
+
import type { LogLevel } from "@zhushanwen/subagent-core/core/logger.ts";
|
|
37
|
+
import type { NotifyDomainPorts } from "@zhushanwen/subagent-core/core/notify-ports.ts";
|
|
38
|
+
|
|
39
|
+
/** agents/workflows 共享的 agentDir 派生根(末级目录名由 kind 决定)。
|
|
40
|
+
* 顺序与 source 标签逐项对齐 resource-discovery.ts buildScanTargets 的
|
|
41
|
+
* user-pi → npm → npm-dev 段(根列表按优先级低→高排列,D2 语义边界)。 */
|
|
42
|
+
function agentDirKindRoots(kind: "agents" | "workflows"): DiscoveryRoot[] {
|
|
43
|
+
const agentDir = getAgentDir();
|
|
44
|
+
return [
|
|
45
|
+
// 1. user .pi/agent/<kind>/
|
|
46
|
+
{ dir: join(agentDir, kind), source: "user-pi" },
|
|
47
|
+
// 2. npm global: agentDir/npm/node_modules/*/<pkg>/
|
|
48
|
+
{ dir: join(agentDir, "npm", "node_modules"), source: "npm" },
|
|
49
|
+
// 3. npm dev symlink: agentDir/extensions/*/<pkg>/
|
|
50
|
+
{ dir: join(agentDir, "extensions"), source: "npm-dev" },
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** skills 的 agentDir 派生根。对齐 skill-discovery.ts resolveSkillPath 的两处
|
|
55
|
+
* 推导(<agentDir>/skills + <agentDir>/npm/node_modules)——现状无 npm-dev 根,
|
|
56
|
+
* 刻意不补(避免静默引入新发现源)。 */
|
|
57
|
+
function skillRoots(): DiscoveryRoot[] {
|
|
58
|
+
const agentDir = getAgentDir();
|
|
59
|
+
return [
|
|
60
|
+
{ dir: join(agentDir, "skills"), source: "user-pi" },
|
|
61
|
+
{ dir: join(agentDir, "npm", "node_modules"), source: "npm" },
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** pi 宿主 HostServices 实现(扩展初始化最早处经 configureCore 注入)。 */
|
|
66
|
+
export function createPiHostServices(): HostServices {
|
|
67
|
+
return {
|
|
68
|
+
// 每次现取 getAgentDir(实例隔离,见文件头);env 覆盖段与 warn-once 留 core
|
|
69
|
+
// data-dir.ts,壳只返回数据根本身(D2 计划期细化③分段归属)。
|
|
70
|
+
dataRoot(): string {
|
|
71
|
+
return getAgentDir();
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// 桥接到 pi-extension-logger:component 即 extName(复用其 loggerCache 单例
|
|
75
|
+
// 与 appendEntry/文件日志通路),按 level 分派方法,(message, data) 透传。
|
|
76
|
+
log(level: LogLevel, component: string, message: string, data?: unknown): void {
|
|
77
|
+
const logger = getLogger(component);
|
|
78
|
+
if (level === "error") logger.error(message, data);
|
|
79
|
+
else if (level === "warn") logger.warn(message, data);
|
|
80
|
+
else logger.debug(message, data);
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
discoveryRoots(): {
|
|
84
|
+
agents?: DiscoveryRoot[];
|
|
85
|
+
skills?: DiscoveryRoot[];
|
|
86
|
+
workflows?: DiscoveryRoot[];
|
|
87
|
+
} {
|
|
88
|
+
return {
|
|
89
|
+
agents: agentDirKindRoots("agents"),
|
|
90
|
+
skills: skillRoots(),
|
|
91
|
+
workflows: agentDirKindRoots("workflows"),
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** pi 侧通知域窄端口实现(configureNotifyDomain 注入)。zsw 壳不注入本端口
|
|
98
|
+
* (其完成通知走 HostServices.notify,P2 落地)。 */
|
|
99
|
+
export function createPiNotifyDomainPorts(): NotifyDomainPorts {
|
|
100
|
+
return {
|
|
101
|
+
// pi 真函数返回 CountActiveResult,core 契约只读 .count——壳侧拆数值。
|
|
102
|
+
countActiveFromEntries(entries: unknown[]): number {
|
|
103
|
+
return countActiveFromEntries(entries).count;
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// 投递内核工厂直传本体(结构兼容论证见文件头);不经包装避免多一层间接面。
|
|
107
|
+
createDelivery,
|
|
108
|
+
};
|
|
109
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -16,40 +16,51 @@
|
|
|
16
16
|
import * as fs from "node:fs";
|
|
17
17
|
import * as path from "node:path";
|
|
18
18
|
|
|
19
|
-
import type { BeforeAgentStartEvent, ExtensionAPI, ExtensionContext, SessionShutdownEvent, SessionStartEvent, SessionTreeEvent } from "@earendil-works/pi-coding-agent";
|
|
19
|
+
import type { BeforeAgentStartEvent, ExtensionAPI, ExtensionContext, SessionCompactEvent, SessionShutdownEvent, SessionStartEvent, SessionTreeEvent } from "@earendil-works/pi-coding-agent";
|
|
20
20
|
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
21
21
|
import { getLogger, setPiHandle } from "@zhushanwen/pi-extension-logger";
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
// ═══ core 宿主端口接线(subagent-core 包抽离 u0-wire;实现见 src/host/pi-host.ts) ═══
|
|
24
|
+
import { configureCore } from "@zhushanwen/subagent-core/core/host-services.ts";
|
|
25
|
+
import { configureNotifyDomain } from "@zhushanwen/subagent-core/core/notify-ports.ts";
|
|
26
|
+
import { createPiHostServices, createPiNotifyDomainPorts } from "./host/pi-host.ts";
|
|
27
|
+
|
|
28
|
+
import { bestEffort } from "@zhushanwen/subagent-core/execution/best-effort.ts";
|
|
24
29
|
// ═══ execution/ 层(subagents 核心 + 运行时) ═══
|
|
25
|
-
import { getOrCreateChannelRegistry } from "
|
|
26
|
-
import { DialogGlobalQueue } from "
|
|
30
|
+
import { getOrCreateChannelRegistry } from "@zhushanwen/subagent-core/execution/channel-registry-access.ts";
|
|
31
|
+
import { DialogGlobalQueue } from "@zhushanwen/subagent-core/execution/dialog-queue.ts";
|
|
32
|
+
// [engine-awareness U3] 全局 config 三态读取(检测 poll 与 session_start 基线共用)
|
|
33
|
+
import { readGlobalConfig } from "@zhushanwen/subagent-core/execution/config.ts";
|
|
27
34
|
// [U7] 引擎列表状态文件(registry → engines.json,GUI 引擎选择器数据源)
|
|
28
|
-
import { syncEnginesFile } from "
|
|
35
|
+
import { syncEnginesFile } from "@zhushanwen/subagent-core/execution/engine/engine-discovery.ts";
|
|
29
36
|
// [U7] 引擎模型段注入(defaultEngine 非 pi 时 system prompt 补 <available_<engine>_models>)
|
|
30
|
-
|
|
37
|
+
// [engine-awareness U3] 补恒在状态段 <current_subagent_engine>(D6,pi 引擎也声明)
|
|
38
|
+
import { buildEngineModelsPromptAppend, buildSubagentEngineSection } from "@zhushanwen/subagent-core/execution/engine/model-prompt.ts";
|
|
31
39
|
// [P1 引擎接线] 组合根登记 'pi' 引擎进 registry(引擎获取统一经 getEngine,缺省 id 'pi')
|
|
32
|
-
import { registerPiEngine } from "
|
|
40
|
+
import { registerPiEngine } from "@zhushanwen/subagent-core/execution/engine/engines/pi/registration.ts";
|
|
33
41
|
// [P3 引擎接线] 组合根登记 'zcode' 引擎(spawn 单轮模式;engineDataDir 默认走
|
|
34
42
|
// common/data-dir SSOT,见 engines/zcode/registration.ts)
|
|
35
|
-
import { registerZcodeEngine } from "
|
|
36
|
-
import { createUiRequestHandlerForMode } from "
|
|
43
|
+
import { registerZcodeEngine } from "@zhushanwen/subagent-core/execution/engine/engines/zcode/registration.ts";
|
|
44
|
+
import { createUiRequestHandlerForMode } from "@zhushanwen/subagent-core/execution/ui-request-handler-factory.ts";
|
|
37
45
|
import {
|
|
38
46
|
getModelConfigService,
|
|
39
47
|
ModelConfigService,
|
|
40
48
|
setModelConfigService,
|
|
41
|
-
} from "
|
|
42
|
-
import {
|
|
43
|
-
import
|
|
44
|
-
import {
|
|
49
|
+
} from "@zhushanwen/subagent-core/execution/model-config-service.ts";
|
|
50
|
+
import { bindNotifyLedgerHost, getBoundNotifyLedger, type NotifyLedgerHost } from "@zhushanwen/subagent-core/execution/notify-ledger.ts";
|
|
51
|
+
import { IDENTITY_CUSTOM_TYPE, type SubagentIdentityData } from "@zhushanwen/subagent-core/execution/session-reconstructor.ts";
|
|
52
|
+
import type { ExecutionMode, SubagentRecord } from "@zhushanwen/subagent-core/execution/types.ts";
|
|
53
|
+
import { maybeCleanupExpiredSessionFiles } from "@zhushanwen/subagent-core/execution/session-file-gc.ts";
|
|
45
54
|
import {
|
|
46
55
|
getSubagentService,
|
|
47
56
|
setSubagentService,
|
|
48
57
|
SubagentService,
|
|
49
|
-
} from "
|
|
50
|
-
import { killAllSpawnedChildren } from "
|
|
51
|
-
import { SubprocessAgentRunner } from "
|
|
52
|
-
import { WorktreeManager } from "
|
|
58
|
+
} from "@zhushanwen/subagent-core/execution/subagent-service.ts";
|
|
59
|
+
import { killAllSpawnedChildren } from "@zhushanwen/subagent-core/execution/session-runner.ts";
|
|
60
|
+
import { SubprocessAgentRunner } from "@zhushanwen/subagent-core/execution/subprocess-agent-runner.ts";
|
|
61
|
+
import { WorktreeManager } from "@zhushanwen/subagent-core/execution/worktree-manager.ts";
|
|
62
|
+
// [engine-awareness U3] per-turn 引擎检测编排(D1/D1b/D2/D3/D5)
|
|
63
|
+
import { normalizeEngineId, runEngineAwarenessTurn } from "./injectors/engine-awareness.ts";
|
|
53
64
|
import { setupModelListInjector } from "./injectors/model-list-injector.ts";
|
|
54
65
|
import { setupSubagentListInjector } from "./injectors/subagent-list-injector.ts";
|
|
55
66
|
import { setupWorkflowListInjector } from "./injectors/workflow-list-injector.ts";
|
|
@@ -62,20 +73,20 @@ import { registerSubagentTool } from "./interface/subagent-tool.ts";
|
|
|
62
73
|
import { registerSubagentsCommand } from "./interface/subagents.ts";
|
|
63
74
|
import { registerWorkflowTool } from "./interface/tool-workflow.ts";
|
|
64
75
|
import { registerWorkflowScriptTool } from "./interface/tool-workflow-script.ts";
|
|
65
|
-
import { JsonlRunStore } from "./
|
|
66
|
-
import { clearSkillPathCache } from "
|
|
76
|
+
import { JsonlRunStore } from "./jsonl-run-store.ts";
|
|
77
|
+
import { clearSkillPathCache } from "@zhushanwen/subagent-core/orchestration/skill-discovery.ts";
|
|
67
78
|
// ═══ orchestration/ 层(workflow engine + infra) ═══
|
|
68
|
-
import type { LauncherDeps } from "
|
|
69
|
-
import { executeNestedWorkflow, runAndWait, type WorkflowRunResult } from "
|
|
79
|
+
import type { LauncherDeps } from "@zhushanwen/subagent-core/orchestration/launcher.ts";
|
|
80
|
+
import { executeNestedWorkflow, runAndWait, type WorkflowRunResult } from "@zhushanwen/subagent-core/orchestration/launcher.ts";
|
|
70
81
|
import {
|
|
71
82
|
evictDoneRunsBeyondCap,
|
|
72
83
|
MAX_RETAINED_DONE_RUNS,
|
|
73
84
|
scheduleTimeBudget,
|
|
74
85
|
terminateRunningRuns,
|
|
75
|
-
} from "
|
|
76
|
-
import type { WorkflowRun } from "
|
|
77
|
-
import { WorkerHostImpl } from "
|
|
78
|
-
import { WorkflowScriptRegistryImpl } from "
|
|
86
|
+
} from "@zhushanwen/subagent-core/orchestration/lifecycle.ts";
|
|
87
|
+
import type { WorkflowRun } from "@zhushanwen/subagent-core/orchestration/models/workflow-run.ts";
|
|
88
|
+
import { WorkerHostImpl } from "@zhushanwen/subagent-core/orchestration/worker-host.ts";
|
|
89
|
+
import { WorkflowScriptRegistryImpl } from "@zhushanwen/subagent-core/orchestration/workflow-script-registry-impl.ts";
|
|
79
90
|
|
|
80
91
|
// ── pi.__workflowRun 类型扩展(D-8 签名) ─────────────────
|
|
81
92
|
|
|
@@ -169,6 +180,14 @@ export default function subagentsWorkflowExtension(pi: ExtensionAPI): void {
|
|
|
169
180
|
// 的 getLogger("subagents") 也能走 appendEntry。
|
|
170
181
|
setPiHandle(pi);
|
|
171
182
|
|
|
183
|
+
// [u0-wire] core 宿主端口接线:本波端口尚无 core 消费方(消费切换在 u0-log /
|
|
184
|
+
// u0-data-discovery / u0-notify 波次),接线本身零行为变化。紧随 setPiHandle——
|
|
185
|
+
// core log 桥接走 pi-extension-logger,其 pi handle 先注入则配置完成即桥接链路
|
|
186
|
+
// 完整;且先于任何可能消费 core 端口的初始化逻辑(引擎登记等)。缺省态若被消费,
|
|
187
|
+
// dataRoot 抛 core_host_not_configured(§3.4),接线后不再可达。
|
|
188
|
+
configureCore(createPiHostServices());
|
|
189
|
+
configureNotifyDomain(createPiNotifyDomainPorts());
|
|
190
|
+
|
|
172
191
|
// [P1 引擎接线] 组合根登记缺省引擎:进程级 SubagentService 单例(session_start 注入)
|
|
173
192
|
// 经 registry 以 'pi' 暴露——引擎获取从此统一走 getEngine(DEFAULT_ENGINE_ID),上层
|
|
174
193
|
// 不再硬编码「spawn pi」。幂等(registerEngine 覆盖语义),工厂惰性解析服务单例。
|
|
@@ -266,6 +285,10 @@ export default function subagentsWorkflowExtension(pi: ExtensionAPI): void {
|
|
|
266
285
|
* workflow 域启动时 fail-fast,避免后续 store.save 再次失败导致 run 状态不落地。
|
|
267
286
|
* subagent 域不依赖 store,不受此标志影响。 */
|
|
268
287
|
storeHealthy: boolean;
|
|
288
|
+
/** [engine-awareness D1b] 上一次已知默认引擎(session_start 初始化,per-turn 检测
|
|
289
|
+
* diff 基准)。undefined = 初始化时 config 读失败——首 turn 检测遇 undefined
|
|
290
|
+
* 静默基线化,不算变更、不发通知(防首 turn 伪通知)。 */
|
|
291
|
+
lastEngine?: string;
|
|
269
292
|
}
|
|
270
293
|
>();
|
|
271
294
|
|
|
@@ -410,6 +433,39 @@ export default function subagentsWorkflowExtension(pi: ExtensionAPI): void {
|
|
|
410
433
|
}
|
|
411
434
|
}
|
|
412
435
|
|
|
436
|
+
// ── [U2] 通知账本装配 + 重启恢复(设计 D4:存在性 / 可达性分离)──
|
|
437
|
+
// bind 先于 service.initSession(notifier.revive 在其内——notify() 经
|
|
438
|
+
// getBoundNotifyLedger 消费账本)。recoverFromSession 扫 ledger/ack 两列 entry
|
|
439
|
+
// 差集:未销账号重放投递(已销账零重发,notifyId 幂等);fork 继承未销账
|
|
440
|
+
// pending 属可接受语义(D4 归属规则——扫描域 = 单 session 文件,幂等键作用域
|
|
441
|
+
// 随文件域隔离)。compaction 存活情况归 session_compact handler 的条件降级(P-B4
|
|
442
|
+
// 探针阶段 5 实测,见 notify-ledger.ts compactionCheck)。
|
|
443
|
+
try {
|
|
444
|
+
const ledgerHost: NotifyLedgerHost = {
|
|
445
|
+
appendLedgerEntry: (customType, data) => {
|
|
446
|
+
pi.appendEntry(customType, data);
|
|
447
|
+
},
|
|
448
|
+
readSessionEntries: () => ctx.sessionManager.getEntries(),
|
|
449
|
+
isIdle: () => ctx.isIdle(),
|
|
450
|
+
onAgentSettled: (handler) => {
|
|
451
|
+
pi.on("agent_settled", handler);
|
|
452
|
+
},
|
|
453
|
+
sendDelivery: (message) => {
|
|
454
|
+
// D5 单通道:唯一发送形态 = sendCustomMessage({triggerTurn:true}),
|
|
455
|
+
// courier 已在发送前二次复查 isIdle,多通道投递选项已删(D5)。
|
|
456
|
+
pi.sendMessage(message, { triggerTurn: true });
|
|
457
|
+
},
|
|
458
|
+
};
|
|
459
|
+
// U4:重放观测已内聚到 ledger 分桶日志(recoveryReplays 桶经 extensionLogger
|
|
460
|
+
// 通道落盘),此处不再重复打日志。
|
|
461
|
+
bindNotifyLedgerHost(ledgerHost).recoverFromSession();
|
|
462
|
+
} catch (err) {
|
|
463
|
+
// 账本装配失败不阻断 session_start(通知退回 notifier 的内核路径)
|
|
464
|
+
logger.warn("[subagents] notify ledger bind failed", {
|
|
465
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
413
469
|
// ── subagents 域:双 Service 装配 ──
|
|
414
470
|
const existingService = getSubagentService();
|
|
415
471
|
const existingModelService = getModelConfigService();
|
|
@@ -578,6 +634,13 @@ export default function subagentsWorkflowExtension(pi: ExtensionAPI): void {
|
|
|
578
634
|
ctxModel: ctx.model ?? undefined,
|
|
579
635
|
});
|
|
580
636
|
|
|
637
|
+
// [engine-awareness D1b] lastEngine 初始化:构造性同源——单次 reloadGlobalConfig
|
|
638
|
+
// 读取同时刷新 Service 路由缓存与 lastEngine 基准,消灭 initModel 与本处两次独立
|
|
639
|
+
// 读取间的分叉窗口(两读值不一致时检测走 unchanged 分支不 reload,状态段/路由
|
|
640
|
+
// 永停旧值且永不通知)。ok/absent → 归一后的当前引擎;failed → undefined(首 turn
|
|
641
|
+
// 检测静默基线化兜底,此时缓存亦保持不动)。/resume、/fork 同样走 session_start
|
|
642
|
+
// (SR-3),基线天然覆盖。
|
|
643
|
+
const engineRead = modelService.reloadGlobalConfig();
|
|
581
644
|
sessionState.set(sessionId, {
|
|
582
645
|
store,
|
|
583
646
|
runs,
|
|
@@ -585,19 +648,66 @@ export default function subagentsWorkflowExtension(pi: ExtensionAPI): void {
|
|
|
585
648
|
runner,
|
|
586
649
|
ctx,
|
|
587
650
|
storeHealthy,
|
|
651
|
+
lastEngine:
|
|
652
|
+
engineRead.status === "failed" ? undefined : normalizeEngineId(engineRead.config.defaultEngine),
|
|
588
653
|
});
|
|
589
654
|
});
|
|
590
655
|
|
|
591
656
|
// ════════════════════════════════════════════════════════════
|
|
592
|
-
// [
|
|
593
|
-
//
|
|
594
|
-
//
|
|
657
|
+
// [U2 P-B4 降级] session_compact:compaction 对 custom entry 保留行为实装未
|
|
658
|
+
// 验证——检测 ledger/ack entry 被 compaction 清除时按内存态补写(notify-ledger
|
|
659
|
+
// compactionCheck;未清除则 no-op)。内存态在 compaction 后仍活着,作为补写源;
|
|
660
|
+
// 重启后的权威仍是两列 entry 差集(内存不承担销账职责)。
|
|
661
|
+
// ═══════════════════════════════════════════════════════
|
|
662
|
+
pi.on("session_compact", (_event: SessionCompactEvent, _ctx: ExtensionContext) => {
|
|
663
|
+
try {
|
|
664
|
+
const rewritten = getBoundNotifyLedger()?.compactionCheck() ?? 0;
|
|
665
|
+
if (rewritten > 0) {
|
|
666
|
+
logger.warn(`[subagents] notify ledger entries lost to compaction; rewrote ${rewritten} from memory`);
|
|
667
|
+
}
|
|
668
|
+
} catch (err) {
|
|
669
|
+
logger.warn("[subagents] notify ledger compactionCheck failed", {
|
|
670
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
|
|
595
675
|
// ════════════════════════════════════════════════════════════
|
|
596
|
-
|
|
676
|
+
// [U7 + engine-awareness U3] before_agent_start:引擎感知注入(链尾注册,D7——
|
|
677
|
+
// 段内容变化只断 system prompt 尾部 cache 前缀)。
|
|
678
|
+
// ① per-turn 检测编排(§2.3 数据流):三态 poll config → lastEngine diff →
|
|
679
|
+
// 变更时读取结果先行提交缓存(D2,applyGlobalConfig 纯赋值,本 turn 路由生效)
|
|
680
|
+
// → sendMessage 通知
|
|
681
|
+
// (D3,不设 triggerTurn——P1 探针已证此形态消息进入本 turn LLM 上下文,
|
|
682
|
+
// 证据:真机 pi rpc payload dump + 0.84.4 dist sendMessage→_appendCustomMessage
|
|
683
|
+
// →agent.state.messages.push→createContextSnapshot 调用链)→ 更新 lastEngine。
|
|
684
|
+
// ② 恒在状态段 <current_subagent_engine>(D6)+ 引擎清单段 <available_<engine>_models>。
|
|
685
|
+
// apply 后 getGlobalConfig() 即新值——通知、状态段、路由三处同 turn 对齐(G2)。
|
|
686
|
+
// 段序:状态段在前(文案声明 "listed ... below"),清单段在后;provider models 段
|
|
687
|
+
// 由更早注册的 handler 注入、位于上方。fail-safe 任何异常不注入不阻塞 agent loop。
|
|
688
|
+
// ════════════════════════════════════════════════════════════
|
|
689
|
+
pi.on("before_agent_start", (event: BeforeAgentStartEvent, ctx: ExtensionContext) => {
|
|
597
690
|
try {
|
|
598
691
|
const service = getModelConfigService();
|
|
599
|
-
|
|
600
|
-
|
|
692
|
+
if (service === null || typeof event.systemPrompt !== "string") return undefined;
|
|
693
|
+
const sid = ctx.sessionManager.getSessionId();
|
|
694
|
+
runEngineAwarenessTurn({
|
|
695
|
+
readConfig: () => readGlobalConfig(getAgentDir()),
|
|
696
|
+
applyRead: (read) => service.applyGlobalConfig(read),
|
|
697
|
+
sendMessage: (message) => {
|
|
698
|
+
// D3:不设 triggerTurn——切换是用户主动行为,无需唤醒 AI 立即行动
|
|
699
|
+
pi.sendMessage(message, {});
|
|
700
|
+
},
|
|
701
|
+
getLastEngine: () => sessionState.get(sid)?.lastEngine,
|
|
702
|
+
setLastEngine: (engine) => {
|
|
703
|
+
const state = sessionState.get(sid);
|
|
704
|
+
if (state) state.lastEngine = engine;
|
|
705
|
+
},
|
|
706
|
+
});
|
|
707
|
+
const defaultEngine = service.getGlobalConfig().defaultEngine;
|
|
708
|
+
const append = [buildSubagentEngineSection(defaultEngine), buildEngineModelsPromptAppend(defaultEngine)]
|
|
709
|
+
.filter((part) => part !== "")
|
|
710
|
+
.join("\n\n");
|
|
601
711
|
return { systemPrompt: `${event.systemPrompt}\n\n${append}` };
|
|
602
712
|
} catch {
|
|
603
713
|
return undefined;
|
|
@@ -900,4 +1010,4 @@ export {
|
|
|
900
1010
|
getOrCreateChannelRegistry,
|
|
901
1011
|
type UiChannelRegistry,
|
|
902
1012
|
type ChannelHandler,
|
|
903
|
-
} from "
|
|
1013
|
+
} from "@zhushanwen/subagent-core/execution/channel-registry-access.ts";
|