@zhushanwen/pi-subagent-workflow 8.6.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 +9 -13
- 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 +89 -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 +2 -2
- 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 +4 -4
- package/src/interface/commands.ts +3 -3
- package/src/interface/format.ts +2 -2
- package/src/interface/helpers.ts +1 -1
- 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 +263 -11
- package/src/interface/subagent-tool-schema.ts +20 -13
- package/src/interface/subagent-tool.ts +11 -6
- package/src/interface/subagents.ts +3 -3
- 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} +11 -11
- 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
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
9
|
|
|
10
|
-
import type { AgentEventLogEntry } from "
|
|
11
|
-
import type { ExecutionTraceNode, ToolCallEntry } from "
|
|
12
|
-
import type { DoneReason, RunStatus } from "
|
|
13
|
-
import { displayAgentName } from "
|
|
10
|
+
import type { AgentEventLogEntry } from "@zhushanwen/subagent-core/execution/types.ts";
|
|
11
|
+
import type { ExecutionTraceNode, ToolCallEntry } from "@zhushanwen/subagent-core/orchestration/models/types.ts";
|
|
12
|
+
import type { DoneReason, RunStatus } from "@zhushanwen/subagent-core/orchestration/models/types.ts";
|
|
13
|
+
import { displayAgentName } from "@zhushanwen/subagent-core/shared/agent-ref.ts";
|
|
14
14
|
|
|
15
15
|
// ── Constants ─────────────────────────────────────────────────
|
|
16
16
|
|
|
@@ -62,17 +62,17 @@ import * as fs from "node:fs";
|
|
|
62
62
|
import * as path from "node:path";
|
|
63
63
|
|
|
64
64
|
import type { CustomEntry, ExtensionAPI, ExtensionContext, SessionEntry } from "@earendil-works/pi-coding-agent";
|
|
65
|
-
import { getLogger } from "@zhushanwen/
|
|
66
|
-
|
|
67
|
-
import { AgentCall } from "
|
|
68
|
-
import { Budget } from "
|
|
69
|
-
import type { RunSpec } from "
|
|
70
|
-
import type { RunState } from "
|
|
71
|
-
import { Trace } from "
|
|
72
|
-
import type { DoneReason, RunStatus, WorkerLogEntry } from "
|
|
73
|
-
import type { AgentCallOpts, AgentResult, ExecutionTraceNode } from "
|
|
74
|
-
import type { WorkflowRunMeta } from "
|
|
75
|
-
import { WorkflowRun } from "
|
|
65
|
+
import { getLogger } from "@zhushanwen/subagent-core/core/logger.ts";
|
|
66
|
+
|
|
67
|
+
import { AgentCall } from "@zhushanwen/subagent-core/orchestration/models/agent-call.ts";
|
|
68
|
+
import { Budget } from "@zhushanwen/subagent-core/orchestration/models/budget.ts";
|
|
69
|
+
import type { RunSpec } from "@zhushanwen/subagent-core/orchestration/models/run-spec.ts";
|
|
70
|
+
import type { RunState } from "@zhushanwen/subagent-core/orchestration/models/run-state.ts";
|
|
71
|
+
import { Trace } from "@zhushanwen/subagent-core/orchestration/models/trace.ts";
|
|
72
|
+
import type { DoneReason, RunStatus, WorkerLogEntry } from "@zhushanwen/subagent-core/orchestration/models/types.ts";
|
|
73
|
+
import type { AgentCallOpts, AgentResult, ExecutionTraceNode } from "@zhushanwen/subagent-core/orchestration/models/types.ts";
|
|
74
|
+
import type { WorkflowRunMeta } from "@zhushanwen/subagent-core/orchestration/models/workflow-run.ts";
|
|
75
|
+
import { WorkflowRun } from "@zhushanwen/subagent-core/orchestration/models/workflow-run.ts";
|
|
76
76
|
|
|
77
77
|
// ── Snapshot format (D-5 version guard) ──────────────────────
|
|
78
78
|
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_meta": "Golden snapshots for BgNotifier.buildLlmContent — captured pre-migration (commit HEAD at time of capture). Used by migration verification to ensure zero behavioral regression.",
|
|
3
|
-
"single_closed_success": {
|
|
4
|
-
"input": { "id": "sa-ptr-7", "status": "closed", "agent": "worker", "result": "done", "startedAt": 1, "endedAt": 2 },
|
|
5
|
-
"output": "Subagent \"worker\" (sa-ptr-7) completed. Result:\ndone"
|
|
6
|
-
},
|
|
7
|
-
"single_closed_with_sessionfile": {
|
|
8
|
-
"input": { "id": "sa-ptr-2", "status": "closed", "agent": "w", "result": "final result", "sessionFile": "/tmp/sessions/child-2.jsonl", "startedAt": 1, "endedAt": 2 },
|
|
9
|
-
"output": "Subagent \"w\" (sa-ptr-2) completed. Result:\nfinal result\n\nFull transcript: /tmp/sessions/child-2.jsonl"
|
|
10
|
-
},
|
|
11
|
-
"single_running_round": {
|
|
12
|
-
"input": { "id": "sa-ptr-4", "status": "running", "agent": "w", "round": 2, "result": "round2 text", "startedAt": 1, "endedAt": 2 },
|
|
13
|
-
"output": "Subagent \"w\" (sa-ptr-4) finished a round. Reply:\nround2 text"
|
|
14
|
-
},
|
|
15
|
-
"single_running_round_with_sessionfile": {
|
|
16
|
-
"input": { "id": "sa-ptr-1", "status": "running", "agent": "w", "round": 1, "result": "round1 text", "sessionFile": "/tmp/sessions/child-1.jsonl", "startedAt": 1, "endedAt": 2 },
|
|
17
|
-
"output": "Subagent \"w\" (sa-ptr-1) finished a round. Reply:\nround1 text\n\nFull transcript: /tmp/sessions/child-1.jsonl"
|
|
18
|
-
},
|
|
19
|
-
"single_cancelled": {
|
|
20
|
-
"input": { "id": "sa-ptr-5", "status": "closed", "closedReason": "cancelled", "agent": "w", "startedAt": 1, "endedAt": 2 },
|
|
21
|
-
"output": "Subagent \"w\" (sa-ptr-5) cancelled."
|
|
22
|
-
},
|
|
23
|
-
"single_gc_failed": {
|
|
24
|
-
"input": { "id": "sa-ptr-6", "status": "closed", "closedReason": "gc", "agent": "w", "error": "spawn EPIPE", "startedAt": 1, "endedAt": 2 },
|
|
25
|
-
"output": "Subagent \"w\" (sa-ptr-6) failed: spawn EPIPE"
|
|
26
|
-
},
|
|
27
|
-
"single_gc_failed_with_patchfile": {
|
|
28
|
-
"input": { "id": "sa-ptr-8", "status": "closed", "closedReason": "gc", "agent": "w", "error": "spawn EPIPE", "patchFile": "/tmp/patches/sa-ptr-8.patch", "startedAt": 1, "endedAt": 2 },
|
|
29
|
-
"output": "Subagent \"w\" (sa-ptr-8) failed: spawn EPIPE"
|
|
30
|
-
},
|
|
31
|
-
"single_closed_with_patchfile_and_sessionfile": {
|
|
32
|
-
"input": { "id": "sa-ptr-3", "status": "closed", "agent": "w", "result": "did work", "patchFile": "/tmp/patches/sa-ptr-3.patch", "sessionFile": "/tmp/sessions/child-3.jsonl", "startedAt": 1, "endedAt": 2 },
|
|
33
|
-
"output_contains": "git apply /tmp/patches/sa-ptr-3.patch",
|
|
34
|
-
"output_ends_with": "\n\nFull transcript: /tmp/sessions/child-3.jsonl"
|
|
35
|
-
},
|
|
36
|
-
"single_closed_totalrounds": {
|
|
37
|
-
"input": { "id": "sa-rounds-1", "status": "closed", "agent": "w", "totalRounds": 3, "result": "", "sessionFile": "/tmp/sessions/child-rounds.jsonl", "startedAt": 1, "endedAt": 2 },
|
|
38
|
-
"output": "Subagent \"w\" (sa-rounds-1) completed after 3 rounds. Result:\n\n\nFull transcript: /tmp/sessions/child-rounds.jsonl"
|
|
39
|
-
},
|
|
40
|
-
"single_closed_no_totalrounds": {
|
|
41
|
-
"input": { "id": "sa-rounds-2", "status": "closed", "agent": "w", "result": "done", "sessionFile": "/tmp/sessions/child-oneshot.jsonl", "startedAt": 1, "endedAt": 2 },
|
|
42
|
-
"output": "Subagent \"w\" (sa-rounds-2) completed. Result:\ndone\n\nFull transcript: /tmp/sessions/child-oneshot.jsonl"
|
|
43
|
-
},
|
|
44
|
-
"batch_two_closed": {
|
|
45
|
-
"description": "Two closed records merged in one message (simulating 60s merge window)",
|
|
46
|
-
"records": [
|
|
47
|
-
{ "id": "batch-1", "status": "closed", "agent": "w1", "result": "result1", "startedAt": 1, "endedAt": 2 },
|
|
48
|
-
{ "id": "batch-2", "status": "closed", "agent": "w2", "result": "result2", "startedAt": 3, "endedAt": 4 }
|
|
49
|
-
],
|
|
50
|
-
"separator": "\n\n---\n\n",
|
|
51
|
-
"details_shape": { "batch": true, "items": "array-of-records" }
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[{"label":"plain-ascii-long","maxWidth":40,"text":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","expected":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…"},{"label":"cjk-long","maxWidth":33,"text":"你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界","expected":"你好世界你好世界你好世界你好世界…"},{"label":"sgr-mixed-10k","maxWidth":60,"text":"汉字测试 data \u001b[0m\u001b[38;5;9m汉字测试 \u001b[mbeta \u001b[0mγλυφ \u001b[0malpha alpha \u001b[31m\u001b[38;5;9malpha \u001b[mdata \u001b[Kalpha \u001b[0mbeta beta \u001b[K→arrow beta \u001b[1;32m\u001b[38;5;9mdata alpha 汉字测试 alpha \u001b[31m\u001b]0;title\u0007γλυφ alpha →arrow \u001b[38;5;9m\u001b[0malpha γλυφ 汉字测试 汉字测试 beta beta →arrow →arrow 汉字测试 beta \u001b[38;5;9m\u001b[K→arrow \u001b[0malpha beta data \u001b[0m\u001b[38;5;9m\u001b[K\u001b[38;5;9mbeta 汉字测试 \u001b[m\u001b]0;title\u0007\u001b[38;5;9m→arrow beta 汉字测试 \u001b[31mdata \u001b[1;32m\u001b[K\u001b[1;32mγλυφ alpha \u001b[0m\u001b[1;32m汉字测试 汉字测试 \u001b[Kbeta γλυφ γλυφ \u001b[1;32m\u001b[1;32mbeta \u001b[38;5;9m\u001b[K\u001b[1;32m\u001b[0m\u001b[0m\u001b]0;title\u0007→arrow 汉字测试 \u001b[m→arrow 汉字测试 \u001b[38;5;9mbeta \u001b]0;title\u0007→arrow →arrow data \u001b[31m\u001b[0mdata data →arrow γλυφ \u001b[K→arrow 汉字测试 γλυφ \u001b[Kalpha \u001b]0;title\u0007\u001b[31mdata →arrow data \u001b[1;32m\u001b[31m\u001b[0mdata data \u001b[38;5;9m汉字测试 汉字测试 \u001bZ\u001b[K\u001b[K\u001b[0m\u001b[0mγλυφ alpha \u001b[31malpha 汉字测试 alpha alpha \u001b]0;title\u0007\u001b[38;5;9malpha data data data beta \u001b[31m\u001b[1;32mdata →arrow \u001b[1;32m\u001b[K\u001b[mbeta →arrow \u001b[0m→arrow γλυφ beta data data γλυφ →arrow beta data 汉字测试 beta 汉字测试 \u001b[K→arrow →arrow alpha \u001b[mbeta data data \u001b[mγλυφ alpha →arrow 汉字测试 γλυφ γλυφ \u001b[31m\u001b[31m\u001b]0;title\u0007→arrow alpha \u001b[1;32mbeta γλυφ →arrow \u001b[K\u001b[38;5;9m\u001b[0m\u001b[1;32mγλυφ γλυφ \u001b[38;5;9m→arrow \u001b[31m\u001b[1;32m\u001b[1;32mγλυφ 汉字测试 alpha data \u001b]0;title\u0007\u001b[38;5;9malpha \u001b[38;5;9m→arrow 汉字测试 beta \u001b[0mbeta beta \u001b[38;5;9mγλυφ \u001b[mdata \u001b[mbeta \u001b[1;32mdata \u001b[mbeta γλυφ \u001b[m\u001b[31mbeta γλυφ 汉字测试 alpha data \u001b[K\u001b[0m汉字测试 beta alpha 汉字测试 \u001bZ\u001b[0m\u001b[38;5;9m\u001b[mγλυφ alpha γλυφ γλυφ 汉字测试 alpha alpha beta \u001b]0;title\u0007→arrow \u001b[38;5;9m汉字测试 \u001b[0m汉字测试 data \u001b[38;5;9m→arrow 汉字测试 \u001b[m\u001b[0mdata γλυφ γλυφ →arrow data data \u001b[31malpha →arrow data \u001b[K汉字测试 γλυφ \u001b[31m\u001b]0;title\u0007alpha \u001b[1;32m汉字测试 →arrow \u001bZdata \u001b[38;5;9mbeta →arrow 汉字测试 γλυφ \u001b[Kγλυφ beta alpha data γλυφ 汉字测试 beta beta data γλυφ →arrow alpha \u001b[31malpha \u001b[0m\u001b[38;5;9malpha \u001bZ汉字测试 \u001b[38;5;9malpha γλυφ γλυφ \u001bZ汉字测试 beta \u001b[38;5;9mbeta →arrow γλυφ \u001b[K→arrow data \u001b[Kγλυφ beta \u001b[1;32mγλυφ alpha γλυφ beta beta beta 汉字测试 \u001b[1;32mγλυφ \u001b[K汉字测试 beta →arrow γλυφ γλυφ 汉字测试 汉字测试 γλυφ 汉字测试 \u001b[31m汉字测试 \u001b[K\u001b[31mbeta \u001b[0malpha beta \u001b[38;5;9m\u001b[K\u001b[K汉字测试 alpha \u001b[1;32m→arrow 汉字测试 \u001b[38;5;9mdata 汉字测试 \u001b]0;title\u0007\u001b[mbeta \u001b[m\u001b[0mγλυφ γλυφ γλυφ →arrow \u001b[1;32m汉字测试 γλυφ beta \u001b]0;title\u0007\u001b[K→arrow beta 汉字测试 data 汉字测试 beta \u001bZ\u001b[31m\u001b[31m\u001b[Kγλυφ 汉字测试 data 汉字测试 beta beta \u001b[m\u001b]0;title\u0007\u001b[m\u001b[38;5;9malpha →arrow \u001b[m\u001b[m汉字测试 \u001b[1;32m\u001b[1;32m汉字测试 \u001b[mbeta \u001b[31mdata →arrow beta γλυφ beta \u001b[m→arrow \u001b[31m\u001b[mγλυφ \u001b[38;5;9mdata \u001b[m\u001b[0m\u001b]0;title\u0007\u001b[1;32m→arrow beta \u001b[m\u001b[m\u001b[K→arrow alpha \u001b]0;title\u0007\u001b[31mγλυφ γλυφ alpha data 汉字测试 beta \u001bZ\u001b[m\u001b[1;32mγλυφ 汉字测试 \u001bZ\u001b[K\u001bZalpha γλυφ →arrow 汉字测试 alpha γλυφ \u001bZ\u001b[m汉字测试 →arrow \u001b[0mbeta data \u001b[K汉字测试 alpha data beta \u001b[1;32m\u001b[1;32m\u001b[38;5;9m\u001b[1;32m\u001b[38;5;9m\u001b[38;5;9m汉字测试 \u001b[Kγλυφ \u001b[K→arrow γλυφ 汉字测试 →arrow \u001b[0m\u001bZ\u001b[38;5;9m\u001b[K\u001b[38;5;9mγλυφ →arrow γλυφ 汉字测试 beta \u001b[38;5;9m\u001b[31mbeta \u001b[31m\u001b]0;title\u0007汉字测试 →arrow beta 汉字测试 \u001b[31mdata 汉字测试 \u001b[38;5;9mbeta data γλυφ →arrow \u001bZdata \u001b[m→arrow \u001b[31m汉字测试 →arrow \u001bZ\u001b]0;title\u0007alpha \u001b[mγλυφ beta \u001b[m\u001b[1;32mγλυφ \u001b[1;32m\u001b[1;32m→arrow 汉字测试 beta 汉字测试 汉字测试 汉字测试 γλυφ \u001b[38;5;9mγλυφ \u001b[1;32m\u001b[m\u001b[0mbeta \u001b[0m\u001b[38;5;9mbeta γλυφ →arrow beta \u001b[mγλυφ \u001b[1;32m\u001b[malpha \u001b[38;5;9mdata 汉字测试 →arrow →arrow \u001b]0;title\u0007\u001b[31mγλυφ \u001b[mdata beta alpha \u001b[Kγλυφ data data data γλυφ 汉字测试 alpha \u001b]0;title\u0007\u001b[38;5;9m\u001b[38;5;9m\u001b[38;5;9m\u001b[31m\u001b[31m→arrow \u001b[K\u001b[Kdata \u001b[1;32m\u001b[0mdata →arrow data \u001b[1;32m\u001bZ\u001b[m\u001b[0m汉字测试 →arrow beta \u001b[0m汉字测试 alpha \u001b[38;5;9m\u001b]0;title\u0007\u001b[38;5;9mbeta \u001b[31m\u001b[1;32m→arrow \u001b]0;title\u0007beta beta \u001b[38;5;9m汉字测试 γλυφ \u001b[mγλυφ \u001b[31m→arrow \u001b[K\u001b[1;32m汉字测试 \u001b[K汉字测试 \u001b[0malpha \u001b[1;32m\u001b[0m→arrow 汉字测试 beta beta data γλυφ \u001b[Kγλυφ \u001b[0m\u001b[1;32malpha 汉字测试 \u001b[1;32m\u001b[K\u001b[38;5;9m\u001b[0mγλυφ alpha alpha \u001b[m\u001b[0m\u001bZγλυφ data 汉字测试 \u001b[38;5;9m→arrow data beta \u001b[31mdata γλυφ \u001b[38;5;9mbeta \u001bZ→arrow alpha →arrow \u001b[31m\u001b[0m\u001b[mγλυφ \u001b[m\u001b[Kbeta data →arrow \u001b[K\u001b[31mbeta γλυφ →arrow data \u001b[31m\u001b[31malpha \u001b[31m\u001b[0malpha →arrow 汉字测试 \u001b]0;title\u0007\u001b[malpha \u001b[31m\u001b[31mdata \u001b]0;title\u0007\u001b[0malpha \u001b[0m汉字测试 \u001b[31mγλυφ 汉字测试 \u001bZ\u001bZ\u001b[38;5;9mbeta →arrow 汉字测试 \u001b[38;5;9m\u001b[31m→arrow \u001b]0;title\u0007beta 汉字测试 \u001b]0;title\u0007\u001b]0;title\u0007\u001b]0;title\u0007→arrow 汉字测试 \u001b[31m\u001b[malpha data 汉字测试 data beta 汉字测试 →arrow γλυφ \u001b[0m\u001b[mγλυφ beta \u001b[38;5;9malpha \u001b[0m\u001b[mγλυφ \u001b[K汉字测试 \u001b[1;32m\u001b[31malpha alpha \u001b[m\u001bZγλυφ 汉字测试 γλυφ alpha \u001b[31mdata γλυφ \u001b[1;32mdata \u001b[malpha \u001b[Kγλυφ \u001b[31m→arrow beta \u001b[K\u001b[K\u001b[1;32malpha \u001b]0;title\u0007\u001b[31m\u001b[1;32mbeta \u001b[Kbeta γλυφ alpha γλυφ \u001b[38;5;9malpha \u001b[31mdata \u001b]0;title\u0007beta \u001b[K\u001b[m\u001b[K\u001b[K汉字测试 \u001b[K\u001b[38;5;9mdata alpha \u001b[Kdata \u001b[mdata γλυφ beta \u001b[38;5;9m\u001b[mγλυφ \u001b[mbeta \u001b[m\u001bZ\u001b[38;5;9m\u001b]0;title\u0007\u001b[K\u001b[malpha 汉字测试 \u001b[38;5;9mγλυφ beta →arrow beta →arrow γλυφ \u001b[31m→arrow \u001b[38;5;9mγλυφ alpha 汉字测试 beta \u001b[31malpha \u001b[Kalpha alpha \u001b[m\u001b[38;5;9m\u001b[1;32m\u001b[0m→arrow data \u001b]0;title\u0007汉字测试 \u001b[38;5;9mbeta \u001b[mbeta \u001b[0m汉字测试 alpha 汉字测试 \u001b[mdata γλυφ \u001bZ\u001b[1;32mbeta data alpha γλυφ data \u001b[malpha \u001b[38;5;9mbeta beta alpha \u001b[0m\u001b[31m\u001b[m\u001b[31m汉字测试 \u001b[K\u001b[38;5;9mdata \u001b[38;5;9malpha alpha \u001bZ\u001b]0;title\u0007beta \u001b[0m\u001bZ汉字测试 γλυφ γλυφ γλυφ \u001b[malpha \u001b]0;title\u0007汉字测试 汉字测试 \u001b[0m\u001b[Kbeta \u001b[mbeta beta γλυφ 汉字测试 \u001b[1;32m\u001b[Kdata →arrow \u001b[31m→arrow γλυφ γλυφ 汉字测试 \u001b]0;title\u0007\u001b[m\u001b[1;32malpha data \u001bZalpha \u001b]0;title\u0007\u001b[K→arrow \u001b[m\u001b[mγλυφ \u001b[m\u001b[31m\u001b[1;32m→arrow \u001b[31m\u001b[m→arrow 汉字测试 →arrow beta alpha γλυφ \u001b[Kbeta \u001bZ\u001b[38;5;9mdata γλυφ γλυφ alpha \u001b[31m\u001b[K\u001b[1;32m\u001b[m\u001b]0;title\u0007data →arrow alpha →arrow beta beta data beta 汉字测试 alpha \u001b[31malpha beta \u001b[0m\u001b[38;5;9m\u001b[31m\u001b[38;5;9m→arrow \u001b[K\u001b[Kalpha beta \u001b[31m\u001b[1;32mdata \u001b[1;32m\u001b[K\u001b[m\u001b]0;title\u0007\u001b[31m\u001b[38;5;9m\u001b[Kbeta →arrow γλυφ \u001bZalpha γλυφ →arrow →arrow \u001b[m\u001b[K\u001b[1;32m\u001b[malpha 汉字测试 \u001b[mbeta →arrow γλυφ alpha \u001b[0m\u001b[0malpha beta \u001b[m\u001b[1;32m\u001b[1;32malpha →arrow γλυφ \u001b[38;5;9m\u001b[0m\u001b[1;32m\u001bZ→arrow \u001b[38;5;9m\u001b[31malpha alpha 汉字测试 →arrow data beta data \u001b]0;title\u0007γλυφ \u001b[K\u001b[0m→arrow γλυφ alpha \u001b[31m\u001b[m→arrow \u001b]0;title\u0007\u001b[38;5;9m\u001b[0m\u001b[malpha 汉字测试 \u001b[31mγλυφ →arrow \u001b[Kalpha alpha beta \u001b[38;5;9mbeta →arrow data γλυφ beta beta \u001b[38;5;9malpha \u001b[38;5;9m\u001b[m汉字测试 \u001b[m\u001b]0;title\u0007alpha \u001b[K\u001b[38;5;9m\u001b[mγλυφ \u001b[Kγλυφ data 汉字测试 \u001b]0;title\u0007\u001b[0mγλυφ →arrow →arrow →arrow \u001b[1;32mγλυφ 汉字测试 汉字测试 \u001b[0m\u001b[m\u001b[38;5;9mdata 汉字测试 \u001b[1;32m\u001b[0m\u001b[31mγλυφ \u001b]0;title\u0007alpha \u001b[38;5;9m\u001b[31m\u001b[31m\u001b[31malpha 汉字测试 alpha \u001b[0m\u001bZbeta →arrow \u001b[31malpha alpha \u001b[0mdata beta alpha alpha data →arrow beta γλυφ \u001b[31m\u001b[K\u001b[1;32mγλυφ \u001b[1;32m\u001b[1;32m汉字测试 data 汉字测试 beta beta \u001b[m\u001b[Kγλυφ data \u001b[mγλυφ 汉字测试 γλυφ \u001b[m\u001b]0;title\u0007→arrow →arrow \u001b[0m\u001b[mbeta beta 汉字测试 →arrow γλυφ γλυφ \u001b[38;5;9m→arrow \u001b[1;32mγλυφ \u001b]0;title\u0007data \u001b[1;32mbeta \u001b[31m→arrow 汉字测试 alpha data →arrow data \u001b[0m汉字测试 \u001b[m\u001b]0;title\u0007beta alpha \u001b[38;5;9m汉字测试 \u001b[mγλυφ beta \u001b[1;32m\u001b[malpha 汉字测试 \u001b[1;32m\u001b[0m\u001b[31m\u001bZalpha →arrow alpha \u001b[1;32mdata beta data →arrow \u001b]0;title\u0007beta data γλυφ alpha \u001b[38;5;9malpha alpha data \u001bZ\u001b[38;5;9m汉字测试 alpha \u001bZ\u001b[38;5;9mdata alpha →arrow →arrow \u001b[31m\u001b[Kbeta alpha γλυφ beta \u001b[mbeta \u001b[31mγλυφ \u001bZ\u001bZ\u001b[K\u001bZbeta alpha \u001b[1;32m\u001b[31m\u001b]0;title\u0007beta \u001b]0;title\u0007\u001b[1;32malpha beta beta \u001b[0m\u001bZγλυφ alpha \u001b[mdata \u001b[38;5;9m汉字测试 beta \u001b[38;5;9malpha \u001b[Kdata \u001b[0m汉字测试 γλυφ →arrow data \u001b[31mdata γλυφ \u001b[1;32m汉字测试 alpha \u001b]0;title\u0007alpha \u001b[38;5;9m\u001bZalpha 汉字测试 alpha beta γλυφ \u001b[38;5;9m\u001b[Kdata \u001b[1;32malpha data \u001b]0;title\u0007\u001b[m\u001b[1;32m\u001b[K\u001b[38;5;9m\u001b[38;5;9mγλυφ \u001b[m→arrow →arrow \u001b[1;32mγλυφ \u001b[31mdata →arrow \u001b[malpha \u001b]0;title\u0007\u001b[K\u001b[0mbeta 汉字测试 \u001b[31m→arrow \u001b[K\u001b]0;title\u0007alpha beta \u001b]0;title\u0007\u001b[0m汉字测试 beta →arrow beta γλυφ →arrow beta \u001b[m\u001b[K\u001b]0;title\u0007\u001b[m\u001b[0m\u001b[1;32m\u001b[38;5;9mbeta γλυφ data alpha γλυφ \u001b[mγλυφ \u001b[1;32m汉字测试 →arrow 汉字测试 汉字测试 \u001b]0;title\u0007beta alpha \u001b[0mbeta data \u001b[0malpha \u001b[31m\u001b[38;5;9m→arrow data \u001b[31m\u001b]0;title\u0007\u001b[malpha γλυφ \u001b[31m\u001b[38;5;9m\u001bZ\u001b]0;title\u0007alpha \u001b[38;5;9m\u001b[mdata \u001b[31m→arrow alpha \u001b[Kbeta \u001bZ\u001b[0m\u001b[38;5;9m\u001b[m\u001b[1;32mγλυφ alpha data \u001b[31mbeta data \u001b[1;32mbeta →arrow \u001b[mbeta \u001b[31m\u001b[31m\u001b[m\u001b[1;32mdata γλυφ \u001b[38;5;9m→arrow 汉字测试 alpha alpha \u001b[K汉字测试 \u001b[m\u001b[m\u001b[38;5;9m\u001b[31m\u001b[m\u001b[K\u001b[mγλυφ data \u001b[31m\u001b[38;5;9m→arrow 汉字测试 \u001b[38;5;9mdata data alpha \u001b[38;5;9m汉字测试 \u001b[38;5;9m\u001b[31m\u001b[31mbeta \u001b[Kdata data data 汉字测试 γλυφ \u001b]0;title\u0007γλυφ \u001b[m\u001b[38;5;9m汉字测试 data 汉字测试 \u001b[Kγλυφ \u001b]0;title\u0007data \u001b[mdata γλυφ \u001b[1;32m\u001b[31mbeta 汉字测试 \u001b[38;5;9m→arrow \u001b[1;32m汉字测试 beta →arrow γλυφ beta γλυφ alpha \u001b[38;5;9m\u001bZbeta \u001b[38;5;9m\u001b[1;32m\u001b[K→arrow \u001b[38;5;9m\u001b[K\u001b[0mγλυφ alpha beta \u001b[1;32mbeta beta →arrow →arrow 汉字测试 γλυφ alpha \u001b[31mdata \u001b]0;title\u0007→arrow \u001b[38;5;9m\u001b[1;32m\u001b]0;title\u0007\u001b[0m→arrow beta \u001b[Kdata data data beta data data γλυφ γλυφ 汉字测试 \u001b[mγλυφ \u001bZ汉字测试 \u001b]0;title\u0007\u001b]0;title\u0007\u001b[0m\u001bZ\u001b[31mγλυφ data \u001b[38;5;9m\u001b[Kdata γλυφ γλυφ \u001b[0m\u001b[K\u001b[0m→arrow alpha \u001b[K\u001b]0;title\u0007data \u001b[38;5;9mdata →arrow \u001b[m\u001b[38;5;9m汉字测试 \u001bZbeta beta \u001b[Kalpha \u001b[38;5;9m\u001b[0m\u001bZ\u001b[31m\u001b[38;5;9m→arrow \u001b[0m→arrow →arrow →arrow →arrow \u001b[0m汉字测试 data \u001b[1;32m→arrow alpha →arrow \u001b[38;5;9m汉字测试 \u001b[38;5;9m\u001b[38;5;9mdata \u001b]0;title\u0007\u001b]0;title\u0007\u001b]0;title\u0007\u001b[38;5;9mγλυφ \u001b]0;title\u0007\u001b[1;32mγλυφ 汉字测试 \u001b[malpha \u001b[0m汉字测试 beta \u001bZ\u001b[K\u001b[K→arrow \u001b[38;5;9mγλυφ γλυφ \u001b[1;32mγλυφ →arrow \u001bZdata γλυφ \u001bZ\u001b[K\u001bZ\u001bZγλυφ \u001b]0;title\u0007\u001bZ\u001b[38;5;9m\u001b[1;32m\u001b[1;32m\u001b[m\u001b[mdata beta \u001b[K\u001bZ\u001b[38;5;9m\u001bZalpha \u001b[0m\u001b[K→arrow 汉字测试 beta beta alpha \u001b[m汉字测试 beta →arrow \u001b[38;5;9malpha data →arrow 汉字测试 γλυφ \u001b[38;5;9m\u001b[m\u001b]0;title\u0007\u001b]0;title\u0007\u001b[Kbeta beta \u001bZγλυφ \u001b[1;32m\u001b[31m\u001b[31m\u001b[38;5;9mγλυφ \u001bZdata \u001b[0m\u001b[31mγλυφ data \u001b[0m\u001b[31m→arrow \u001b[38;5;9malpha beta \u001bZdata \u001b[Kdata \u001b[1;32mdata 汉字测试 γλυφ \u001b[K\u001b]0;title\u0007→arrow 汉字测试 \u001b[38;5;9m\u001b[K\u001b[38;5;9mbeta \u001b[38;5;9m\u001b[31m→arrow →arrow \u001b[31m\u001b[31m\u001b]0;title\u0007→arrow 汉字测试 \u001b[malpha beta \u001b[38;5;9mγλυφ data γλυφ \u001b]0;title\u0007\u001b[m\u001bZalpha beta \u001b[0m\u001b[0m汉字测试 \u001b[mdata 汉字测试 \u001b[0m→arrow \u001b[0mγλυφ data data \u001b[0m\u001bZ\u001b[m\u001b[0mbeta γλυφ alpha \u001b[K汉字测试 \u001b[0m\u001bZ\u001b[38;5;9mγλυφ beta \u001b[Kalpha γλυφ 汉字测试 \u001b[31mγλυφ γλυφ beta beta \u001b[1;32m→arrow 汉字测试 \u001b[38;5;9m\u001b]0;title\u0007data \u001b[K\u001b[31mdata γλυφ \u001b]0;title\u0007alpha γλυφ \u001b[1;32m\u001b[Kalpha data data \u001b[1;32m\u001b[m→arrow 汉字测试 →arrow beta γλυφ \u001b[38;5;9m\u001bZalpha \u001b[Kalpha \u001bZ\u001b[m\u001b[0m\u001b[38;5;9m→arrow \u001b[m→arrow beta \u001b[Kbeta \u001b[38;5;9m\u001b[Kdata beta 汉字测试 \u001b[Kγλυφ \u001b[38;5;9m\u001b]0;title\u0007γλυφ \u001b[0m汉字测试 汉字测试 \u001b[31mdata \u001b[1;32m\u001b[m\u001b[Kdata \u001b[K\u001b]0;title\u0007\u001b[1;32mbeta \u001b[0mdata \u001b[31m汉字测试 γλυφ →arrow data γλυφ alpha →arrow \u001b[0m\u001b[38;5;9mbeta beta \u001b[malpha 汉字测试 data →arrow γλυφ \u001b[1;32mdata alpha beta \u001b[31m\u001b[Kbeta →arrow data \u001b[31m\u001b[38;5;9mdata \u001b[38;5;9malpha \u001b[Kγλυφ \u001b]0;title\u0007→arrow data \u001b[1;32m\u001b[31m\u001b[0m\u001b[1;32m\u001b[38;5;9m→arrow 汉字测试 beta γλυφ 汉字测试 →arrow \u001b[mdata alpha \u001b[mγλυφ →arrow \u001b[31mγλυφ beta \u001b[1;32mdata \u001b[0m→arrow beta \u001b[31m\u001b[31m\u001b[1;32m汉字测试 data data γλυφ ","expected":"汉字测试 data \u001b[0m\u001b[38;5;9m汉字测试 \u001b[mbeta \u001b[0mγλυφ \u001b[0malpha alpha \u001b[31m\u001b[38;5;9malpha \u001b[mdata \u001b[K…"},{"label":"sgr-mixed-10k-narrow","maxWidth":12,"text":"\u001b[31mdata 汉字测试 beta data \u001b[31mγλυφ \u001b[1;32m\u001b[0m\u001b[m\u001b[m\u001b[31m\u001b[1;32mdata \u001b[mγλυφ →arrow →arrow alpha \u001b[1;32m\u001bZ\u001b[31m汉字测试 \u001bZ→arrow data \u001b[K\u001b[K\u001b[31mbeta \u001b[38;5;9m\u001b[K\u001b[38;5;9mγλυφ γλυφ alpha γλυφ →arrow γλυφ →arrow data \u001b[0m\u001b[Kγλυφ →arrow data \u001bZdata beta \u001b[31m\u001b[mγλυφ \u001b[38;5;9mdata beta γλυφ γλυφ alpha γλυφ alpha \u001b]0;title\u0007\u001b[mdata →arrow data 汉字测试 \u001b[0m→arrow \u001b[0mγλυφ \u001b[1;32m汉字测试 \u001b[31m\u001b[31m\u001b[malpha \u001b[0mdata \u001b]0;title\u0007\u001b]0;title\u0007data γλυφ 汉字测试 beta data \u001b[1;32mdata 汉字测试 \u001b[Kbeta \u001b]0;title\u0007data \u001bZγλυφ 汉字测试 beta γλυφ →arrow 汉字测试 →arrow γλυφ \u001b[38;5;9m\u001b]0;title\u0007→arrow \u001b]0;title\u0007\u001b[31mdata beta \u001b[31m→arrow data beta beta 汉字测试 data data γλυφ \u001b[malpha 汉字测试 γλυφ →arrow \u001b[31m\u001b[0m\u001b]0;title\u0007→arrow →arrow \u001b[0mdata 汉字测试 →arrow alpha \u001b[38;5;9m\u001b[31mbeta beta data \u001b[0malpha \u001b[1;32mdata \u001b[0m\u001b[0mγλυφ \u001b[38;5;9m\u001b[Kdata \u001b[31m→arrow \u001b[mbeta \u001b[31mdata \u001b[0m\u001b[0m\u001bZalpha beta \u001b[1;32malpha \u001b[m汉字测试 data \u001b[0m\u001b[0m→arrow \u001b[0m\u001b]0;title\u0007\u001b[m\u001b[31m\u001b[1;32mdata data →arrow data beta \u001bZbeta \u001b[0mdata \u001bZbeta γλυφ 汉字测试 alpha γλυφ γλυφ \u001b[0mdata data \u001b[Kalpha 汉字测试 \u001b[0m\u001b[mγλυφ alpha beta \u001b[38;5;9mbeta \u001b[0mbeta →arrow \u001b[0mbeta \u001b[38;5;9m\u001b[0mdata data data data γλυφ data data →arrow γλυφ \u001b[1;32mbeta alpha γλυφ beta \u001b[1;32mγλυφ \u001b[K\u001b[1;32malpha \u001b[1;32malpha alpha γλυφ γλυφ \u001b]0;title\u0007beta \u001b]0;title\u0007data data \u001b]0;title\u0007beta \u001b[1;32m\u001b[38;5;9m\u001b[1;32m\u001b[1;32m→arrow data alpha \u001b[1;32m\u001bZalpha 汉字测试 \u001b[31m汉字测试 \u001b[K\u001b[0m→arrow data →arrow \u001b[Kdata →arrow data \u001b[K\u001b[K汉字测试 alpha γλυφ \u001b[0m→arrow \u001b[31m汉字测试 \u001b[31m\u001bZ\u001b[38;5;9mdata data →arrow γλυφ →arrow \u001b[Kdata 汉字测试 \u001b[0mdata \u001b[Kdata data data \u001b[38;5;9mbeta \u001bZdata 汉字测试 →arrow \u001b[38;5;9m\u001b[0mγλυφ \u001bZγλυφ alpha \u001b[m\u001b[m\u001b[K汉字测试 beta \u001b[0malpha alpha γλυφ \u001b[mdata \u001b[31mbeta \u001b[Kbeta \u001b[0m→arrow γλυφ 汉字测试 \u001b[1;32mγλυφ alpha \u001b[31mdata alpha →arrow →arrow 汉字测试 \u001b[1;32malpha \u001b]0;title\u0007data \u001bZdata γλυφ \u001b[31mdata \u001b]0;title\u0007γλυφ alpha \u001b[1;32mdata data beta \u001b]0;title\u0007\u001b[0m\u001b[31m\u001b[Kbeta →arrow alpha →arrow →arrow data data \u001b[K\u001b[0m\u001b[31malpha \u001b[0m\u001b[m汉字测试 beta \u001b[0m→arrow alpha →arrow alpha beta alpha \u001b[m\u001b[31m→arrow →arrow 汉字测试 \u001b[31m→arrow 汉字测试 data 汉字测试 \u001b[38;5;9m\u001b[31mγλυφ \u001b[1;32mγλυφ →arrow 汉字测试 汉字测试 汉字测试 \u001b[m\u001b[31m\u001b[1;32malpha 汉字测试 alpha \u001b[31mbeta \u001b[38;5;9mbeta 汉字测试 \u001b[m\u001b[K汉字测试 →arrow beta γλυφ →arrow γλυφ \u001b]0;title\u0007\u001b[mdata \u001b[0mbeta \u001b[K\u001bZ→arrow data \u001b]0;title\u0007alpha \u001b[38;5;9m\u001b[Kdata \u001b[38;5;9m\u001b[m汉字测试 data \u001b]0;title\u0007汉字测试 \u001b[1;32malpha \u001b[0m汉字测试 \u001b[38;5;9malpha alpha beta 汉字测试 汉字测试 beta γλυφ →arrow \u001b[31m\u001b[K\u001b[31m\u001b]0;title\u0007\u001b[0mγλυφ alpha beta data \u001b[31mdata data \u001bZγλυφ γλυφ γλυφ \u001b[m→arrow \u001b[38;5;9m汉字测试 汉字测试 γλυφ \u001b[K→arrow \u001b[0m\u001b[1;32mγλυφ data data data 汉字测试 \u001b[1;32mγλυφ →arrow beta γλυφ \u001b[0mbeta \u001b[0m\u001b[0malpha \u001b[38;5;9mbeta \u001bZalpha \u001b]0;title\u0007\u001b[38;5;9mγλυφ beta data \u001b[Kγλυφ \u001b[0m→arrow data \u001b[1;32mdata \u001b[31mbeta \u001b[0m\u001b[m\u001b[Kdata data \u001b[0m→arrow \u001b[K\u001b[Kalpha →arrow \u001b[Kbeta beta \u001b[31m\u001b[Kγλυφ beta data beta \u001b[Kdata \u001b[0mγλυφ →arrow →arrow alpha \u001b[mbeta alpha →arrow alpha \u001b[0mγλυφ 汉字测试 γλυφ data γλυφ \u001bZ\u001b[Kγλυφ \u001b[mbeta \u001b]0;title\u0007\u001b[0mbeta 汉字测试 汉字测试 →arrow \u001b[0m\u001b[K\u001b[m\u001b[38;5;9m\u001b[38;5;9m\u001b[m\u001bZ\u001b[1;32mbeta \u001b[31m\u001b[38;5;9m汉字测试 →arrow beta alpha \u001b[0m\u001b[1;32m\u001b[38;5;9m\u001b[38;5;9m\u001b[38;5;9m\u001b[Kγλυφ beta 汉字测试 \u001b[mdata alpha data \u001b[Kdata \u001b[K\u001b[31m→arrow beta γλυφ 汉字测试 \u001b[Kγλυφ data γλυφ \u001b[38;5;9m→arrow data alpha γλυφ data \u001b[31m\u001b[K\u001b[38;5;9mdata 汉字测试 alpha \u001b[31m\u001b[31mbeta \u001b[0mγλυφ \u001b[1;32m\u001b[38;5;9m\u001b[K\u001b[K\u001b[0m\u001bZ→arrow γλυφ 汉字测试 beta \u001bZalpha γλυφ beta \u001b[1;32malpha γλυφ \u001b[31m\u001b[31m\u001b[38;5;9m→arrow \u001b[31malpha 汉字测试 data \u001b[1;32mbeta 汉字测试 γλυφ alpha \u001b[38;5;9m汉字测试 data \u001b[0mbeta alpha →arrow beta beta γλυφ γλυφ \u001b[0m\u001b[K\u001b[0m\u001b[31m→arrow \u001b[38;5;9malpha \u001b[0m\u001b[K→arrow \u001b[0m\u001b]0;title\u0007\u001b[38;5;9m\u001b[0malpha \u001b[0m\u001b]0;title\u0007\u001b[38;5;9mbeta beta \u001b[K\u001b[1;32mbeta →arrow 汉字测试 \u001b[38;5;9m\u001b[K→arrow \u001b[0malpha beta \u001b[0m汉字测试 →arrow alpha 汉字测试 →arrow \u001b[mdata beta \u001b[38;5;9m汉字测试 beta \u001b[31m\u001b[38;5;9m\u001b[Kalpha data \u001b[31m汉字测试 beta →arrow \u001b[38;5;9malpha data alpha \u001b[1;32m\u001b[0m\u001bZγλυφ \u001b[Kγλυφ beta →arrow \u001b[38;5;9m\u001b[m\u001b]0;title\u0007\u001b[1;32mγλυφ alpha \u001b[1;32m→arrow \u001bZγλυφ \u001b[1;32m\u001bZγλυφ 汉字测试 →arrow beta \u001b[malpha →arrow \u001b[1;32malpha alpha \u001b[31malpha alpha \u001b[31m\u001b[Kγλυφ beta \u001b[m\u001b[31mγλυφ \u001b[0m→arrow γλυφ beta alpha \u001b[0mγλυφ alpha alpha \u001b[38;5;9mbeta data γλυφ beta \u001b]0;title\u0007\u001bZγλυφ \u001bZ\u001b[0m\u001b[1;32mγλυφ beta 汉字测试 \u001b[0malpha \u001b[31m\u001b[38;5;9m\u001b[m\u001b[mbeta \u001b[Kalpha →arrow \u001b[38;5;9m\u001bZdata γλυφ \u001b]0;title\u0007γλυφ \u001b[K→arrow \u001bZ\u001b[38;5;9mbeta γλυφ 汉字测试 alpha data γλυφ \u001b[38;5;9m\u001bZγλυφ \u001b]0;title\u0007alpha →arrow 汉字测试 \u001b[31m汉字测试 \u001b[1;32m\u001b[K\u001b[K\u001b[0mbeta 汉字测试 \u001b]0;title\u0007beta data \u001bZ\u001b[m\u001b[m\u001b[0m\u001bZ\u001b[1;32m汉字测试 γλυφ \u001b[38;5;9m\u001b[K→arrow data →arrow \u001b[1;32m\u001b[K\u001b[1;32m汉字测试 汉字测试 beta →arrow data alpha \u001b[m→arrow \u001b[31m\u001bZγλυφ \u001b[1;32mγλυφ \u001b[m\u001bZ\u001b[31m\u001b[0malpha 汉字测试 \u001b[38;5;9m汉字测试 \u001b[38;5;9mγλυφ alpha γλυφ \u001b[1;32m\u001b[38;5;9m\u001b[mdata \u001b[38;5;9mdata \u001b]0;title\u0007\u001b[38;5;9m\u001b[1;32mγλυφ \u001b[38;5;9m\u001b[31m\u001b[1;32mbeta \u001b[31mγλυφ \u001b[38;5;9m→arrow \u001b[31malpha \u001b[38;5;9m汉字测试 \u001b[mbeta beta \u001b[Kγλυφ \u001b[38;5;9m\u001b]0;title\u0007\u001b[0m\u001b[1;32m\u001b[1;32m\u001b[31mbeta \u001b]0;title\u0007data data beta 汉字测试 \u001b]0;title\u0007\u001b[38;5;9m\u001bZdata \u001b[31mγλυφ \u001b[m→arrow \u001b]0;title\u0007beta →arrow 汉字测试 \u001b[mdata \u001b[31malpha γλυφ \u001b[38;5;9m→arrow beta 汉字测试 →arrow γλυφ →arrow \u001b]0;title\u0007\u001b]0;title\u0007汉字测试 alpha \u001b[31m汉字测试 \u001b[1;32m\u001b[38;5;9m\u001b[m\u001b[0m汉字测试 \u001b[m\u001b[38;5;9m→arrow γλυφ \u001b[38;5;9mbeta →arrow \u001b[Kdata alpha 汉字测试 \u001b[1;32m汉字测试 \u001bZ\u001bZalpha \u001b[31m\u001b[mbeta \u001b[m\u001b[K\u001bZ\u001b[1;32mγλυφ \u001b[K→arrow \u001b[m\u001b[1;32mbeta alpha \u001b[0m\u001b[38;5;9m\u001b[1;32mbeta →arrow beta beta 汉字测试 \u001b[0m汉字测试 alpha \u001bZalpha data \u001b[1;32mdata \u001b[malpha alpha \u001b]0;title\u0007\u001b[0m\u001b[0malpha 汉字测试 alpha \u001b[1;32mγλυφ \u001b[0malpha beta \u001b]0;title\u0007\u001bZ\u001b[38;5;9mγλυφ beta γλυφ \u001b[Kalpha \u001b[31m\u001b[0malpha alpha beta \u001b[1;32mγλυφ beta \u001b[0m\u001b[K汉字测试 汉字测试 \u001b[31mbeta \u001b[1;32m汉字测试 alpha \u001b[0m→arrow \u001b[mdata γλυφ alpha alpha beta data \u001b[mγλυφ γλυφ \u001b[0mγλυφ \u001b[0malpha beta \u001b[31mbeta alpha \u001b[malpha data \u001bZ\u001b[1;32m\u001b]0;title\u0007\u001b[38;5;9mγλυφ 汉字测试 γλυφ beta \u001b[38;5;9m\u001b[0m→arrow 汉字测试 →arrow beta beta beta beta →arrow →arrow \u001b[1;32mdata \u001b[0m\u001b[1;32malpha \u001b[m\u001b[38;5;9m汉字测试 \u001b[K\u001bZ汉字测试 \u001b[1;32m→arrow beta alpha \u001b[0mγλυφ →arrow \u001b[mdata →arrow \u001b]0;title\u0007data beta \u001b[Kbeta →arrow alpha 汉字测试 \u001bZ\u001b[K\u001b[0mdata \u001b[31m\u001b[Kγλυφ →arrow γλυφ beta \u001b[38;5;9m→arrow \u001b[38;5;9mdata →arrow 汉字测试 \u001b[38;5;9m\u001b[1;32m汉字测试 \u001b[1;32m\u001b[38;5;9m\u001b[0mγλυφ \u001b[K\u001b[1;32malpha alpha \u001b[K→arrow \u001b[1;32m\u001b[Kalpha \u001b[K汉字测试 \u001b[1;32m\u001b[Kγλυφ \u001b[0m→arrow data →arrow 汉字测试 γλυφ alpha 汉字测试 beta beta data data \u001bZ\u001b[1;32m\u001b]0;title\u0007\u001bZ\u001b]0;title\u0007\u001b[0m\u001b[31mdata data γλυφ \u001b[31m→arrow \u001b[m\u001b[31mdata →arrow data alpha \u001b[38;5;9mdata data \u001b[Kγλυφ \u001b[1;32malpha \u001b[m→arrow data →arrow alpha \u001b[0m\u001b]0;title\u0007alpha alpha \u001b[38;5;9m\u001b[m\u001b[38;5;9mbeta \u001b[m\u001b[31malpha alpha \u001b[m\u001b[K\u001b[m→arrow \u001b[K\u001b[1;32mγλυφ →arrow →arrow alpha \u001b[m\u001b[38;5;9m\u001b[31m\u001b[m汉字测试 γλυφ beta \u001b[0mbeta data \u001b[K\u001b[K\u001b[m→arrow \u001b[1;32m\u001b[31mbeta \u001b[31malpha \u001b[Kalpha γλυφ 汉字测试 \u001b[K\u001b[1;32mbeta →arrow alpha data 汉字测试 \u001b]0;title\u0007beta γλυφ \u001b[K\u001b[0m\u001b[31malpha \u001b[Kbeta \u001b[1;32mbeta \u001b[malpha →arrow 汉字测试 \u001b[1;32m→arrow \u001bZ\u001b[K\u001b[1;32mbeta 汉字测试 \u001b[K汉字测试 γλυφ γλυφ γλυφ \u001b[31m\u001b[Kγλυφ alpha γλυφ \u001b[31mγλυφ \u001bZ\u001b]0;title\u0007\u001b[0malpha →arrow \u001b[1;32m\u001b[m汉字测试 \u001b[38;5;9mbeta \u001b[m\u001b[0m\u001b]0;title\u0007汉字测试 \u001b[38;5;9m→arrow \u001b]0;title\u0007alpha \u001b[m→arrow \u001b[38;5;9m\u001b[0m\u001b[0mbeta \u001b[0m\u001b]0;title\u0007data →arrow γλυφ beta \u001b[38;5;9malpha beta \u001b[mdata γλυφ alpha \u001b[38;5;9m\u001b[38;5;9malpha \u001b[1;32m汉字测试 γλυφ \u001b[1;32mdata →arrow alpha \u001b[K\u001b[malpha \u001b[0mγλυφ \u001bZ\u001bZ汉字测试 γλυφ →arrow \u001b[31m\u001b[1;32mdata \u001b[0mγλυφ beta \u001b]0;title\u0007汉字测试 data \u001b[38;5;9malpha →arrow beta \u001b[38;5;9mγλυφ alpha \u001b[1;32mγλυφ 汉字测试 汉字测试 \u001b[38;5;9m\u001b[1;32m汉字测试 \u001b[0m\u001b[0mγλυφ \u001b[0mbeta data alpha alpha 汉字测试 γλυφ \u001bZ\u001b[38;5;9mbeta γλυφ alpha γλυφ alpha \u001b[m汉字测试 →arrow \u001b[0m汉字测试 γλυφ \u001b]0;title\u0007beta data \u001b[0m\u001b[1;32m\u001b]0;title\u0007\u001b[38;5;9m\u001b]0;title\u0007\u001b[1;32mbeta \u001b[31m汉字测试 γλυφ \u001b[1;32m→arrow 汉字测试 γλυφ 汉字测试 \u001b[m→arrow 汉字测试 beta 汉字测试 →arrow 汉字测试 \u001b[38;5;9m\u001b]0;title\u0007\u001b[38;5;9mdata 汉字测试 \u001b[m\u001b[38;5;9mdata \u001b[Kdata 汉字测试 \u001b[38;5;9mbeta \u001b[0m\u001bZbeta \u001b[1;32malpha 汉字测试 \u001b[1;32mbeta data beta \u001b[1;32m\u001b[38;5;9m→arrow beta \u001b[31mdata beta \u001b[m\u001b[38;5;9mdata \u001b[38;5;9m\u001b[0mdata beta data beta →arrow \u001b[malpha \u001b[31m\u001b[m→arrow \u001b[K→arrow \u001b[31m\u001b[m\u001b]0;title\u0007汉字测试 data beta \u001b[0m汉字测试 data γλυφ alpha \u001b[K\u001b[K→arrow \u001bZ\u001b[0m→arrow →arrow \u001b[m\u001bZγλυφ data \u001b]0;title\u0007beta γλυφ γλυφ \u001b[malpha \u001b[K\u001b[38;5;9m汉字测试 data \u001b[mγλυφ \u001bZ\u001b[0m\u001b[31m\u001b]0;title\u0007data 汉字测试 alpha \u001bZ\u001b]0;title\u0007→arrow beta \u001b[38;5;9mγλυφ \u001b[K\u001b[1;32m\u001b[K\u001b]0;title\u0007beta \u001b[0m汉字测试 data 汉字测试 \u001b]0;title\u0007beta data data →arrow \u001b[mbeta \u001b[K汉字测试 data 汉字测试 汉字测试 beta \u001b[31m\u001bZ→arrow \u001b[1;32m\u001b[mdata \u001bZalpha \u001b[0m\u001bZ\u001b[K\u001b[1;32m→arrow \u001b[1;32m→arrow 汉字测试 \u001b]0;title\u0007\u001b[31mdata \u001b[K\u001bZ→arrow 汉字测试 →arrow 汉字测试 beta \u001b[38;5;9m→arrow \u001b[31mγλυφ →arrow \u001b[31m\u001b[1;32malpha \u001b[38;5;9m\u001b[K\u001b[Kdata \u001b[Kγλυφ γλυφ \u001b[31mγλυφ →arrow \u001b[31mγλυφ γλυφ γλυφ \u001b[1;32m汉字测试 \u001b]0;title\u0007beta \u001b[K\u001b[K\u001b[31m→arrow \u001b]0;title\u0007\u001b[K\u001b[1;32malpha \u001b[31m汉字测试 γλυφ γλυφ →arrow \u001b]0;title\u0007data alpha γλυφ \u001b[0m\u001b[0m\u001b[38;5;9m\u001b[0m\u001bZ\u001b[31m\u001b[31m\u001b[31mdata \u001b[0mdata \u001b[1;32mγλυφ \u001b]0;title\u0007γλυφ →arrow beta data \u001b[1;32malpha beta γλυφ 汉字测试 beta data \u001b[mγλυφ \u001bZbeta \u001b[m\u001b[31mdata \u001b[38;5;9malpha \u001bZ\u001b[31malpha \u001b[0m→arrow \u001b[38;5;9m汉字测试 汉字测试 \u001b[mγλυφ \u001b[31malpha beta data \u001b[Kdata →arrow γλυφ data γλυφ \u001b[m汉字测试 \u001b[31m→arrow data →arrow \u001b[31m\u001b[38;5;9m汉字测试 alpha \u001b[0m\u001b[31mγλυφ \u001b[K→arrow γλυφ 汉字测试 汉字测试 \u001b[m汉字测试 alpha \u001b[0m\u001b[1;32m\u001b[K汉字测试 \u001b[0m\u001b[Kalpha 汉字测试 \u001b[1;32mbeta beta \u001b[0malpha data \u001b[31mγλυφ γλυφ 汉字测试 \u001b]0;title\u0007\u001b[K→arrow 汉字测试 \u001b[31malpha \u001b[31mγλυφ \u001b[K\u001b[malpha \u001b[1;32mbeta 汉字测试 beta →arrow \u001b[m\u001b[m\u001b[mdata alpha 汉字测试 beta \u001b[1;32mdata \u001b[malpha \u001b[0mbeta \u001b[mγλυφ γλυφ →arrow →arrow γλυφ beta data \u001b[31m\u001b[38;5;9m汉字测试 \u001b]0;title\u0007alpha \u001b]0;title\u0007alpha \u001b[0m\u001b[mγλυφ 汉字测试 beta γλυφ γλυφ data beta \u001b[31m\u001b[1;32m\u001b[1;32m汉字测试 γλυφ \u001b[38;5;9m\u001b[m\u001b]0;title\u0007data \u001b[31mγλυφ →arrow alpha \u001b[38;5;9mbeta 汉字测试 \u001b]0;title\u0007\u001b[38;5;9m→arrow \u001b]0;title\u0007\u001b[31m汉字测试 beta \u001b[38;5;9m\u001b[K\u001b[0m\u001b[38;5;9m\u001b[0mbeta beta data γλυφ →arrow \u001b[1;32m\u001b[Kbeta \u001b]0;title\u0007beta 汉字测试 beta alpha →arrow γλυφ \u001b[m\u001bZ\u001b[31malpha \u001b[31mbeta \u001b[m\u001b[0mγλυφ \u001b[0m\u001b[Kdata data \u001b[Kbeta \u001b[K\u001b[0m汉字测试 汉字测试 \u001b]0;title\u0007\u001b[38;5;9m\u001b[1;32m→arrow alpha alpha \u001b[1;32m\u001b[0m→arrow \u001b[K\u001b[1;32malpha alpha \u001b[m\u001b[38;5;9mbeta beta 汉字测试 汉字测试 \u001b[31malpha \u001b[1;32m\u001bZ\u001b[K→arrow \u001b[1;32m汉字测试 →arrow →arrow \u001b[38;5;9m\u001b[Kγλυφ data data alpha γλυφ →arrow data 汉字测试 汉字测试 \u001b[31mγλυφ \u001b[38;5;9malpha →arrow \u001b[mγλυφ \u001b[38;5;9mbeta \u001b[38;5;9m→arrow \u001b[mdata alpha γλυφ \u001b[m汉字测试 \u001b[38;5;9m\u001b[31m汉字测试 \u001b[0m\u001b[38;5;9mγλυφ \u001b[K汉字测试 \u001b[38;5;9mbeta γλυφ γλυφ alpha \u001bZ汉字测试 γλυφ beta 汉字测试 data \u001b[1;32m","expected":"\u001b[31mdata 汉字测\u001b[31m…\u001b[0m"},{"label":"osc-title","maxWidth":30,"text":"\u001b]0;window title\u0007plain text after osc that is long enough to truncate here","expected":"\u001b]0;window title\u0007plain text a…"},{"label":"bare-esc","maxWidth":25,"text":"before \u001bZ after bare esc char continues to exceed the width limit easily","expected":"before \u001bZ after bare esc…"},{"label":"csi-k-mixed-sgr","maxWidth":20,"text":"\u001b[31mred\u001b[K\u001b[32mgreen tail that keeps going past the boundary here ok","expected":"\u001b[31mred\u001b[K\u001b[32mgreen tail th\u001b[31m\u001b[32m…\u001b[0m"},{"label":"osc-inside-truncation","maxWidth":24,"text":"AAAAAAAAAAAAAAAAAAAA\u001b]0;t\u0007BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB","expected":"AAAAAAAAAAAAAAAAAAAA\u001b]0…"},{"label":"esc-at-end","maxWidth":22,"text":"text almost at width limit\u001b","expected":"text almost at width …"},{"label":"sgr-exact-fit","maxWidth":31,"text":"\u001b[31mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\u001b[0m","expected":"\u001b[31mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\u001b[0m"},{"label":"emoji-mix","maxWidth":17,"text":"😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅😀🚀✅\u001b[1mbold\u001b[0myyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy","expected":"😀🚀✅😀🚀✅😀🚀✅😀🚀✅…"}]
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
// src/execution/__tests__/agent-registry.test.ts
|
|
2
|
-
//
|
|
3
|
-
// AgentRegistry 测试(S2 路径统一版)。
|
|
4
|
-
//
|
|
5
|
-
// S2 重构:AgentRegistry 从「按名查找(discoverAll + cache Map<name>)」收敛为
|
|
6
|
-
// 「按绝对路径加载(loadByPath)」——agentRef 唯一形态 = .md 绝对路径(注入段
|
|
7
|
-
// <location>),内置 agent 即包内物理路径,无 builtin 合并、无名字查找。
|
|
8
|
-
// 发现(注入段数据源)职责由 shared/resource-discovery + injector 承担,
|
|
9
|
-
// 本文件不再测发现层(见 resource-discovery.test.ts)。
|
|
10
|
-
import * as fs from "node:fs";
|
|
11
|
-
import * as os from "node:os";
|
|
12
|
-
import * as path from "node:path";
|
|
13
|
-
|
|
14
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
15
|
-
|
|
16
|
-
// 隔离真实用户全局目录(~/.agents/agents/ 可能有真实 agent 文件)
|
|
17
|
-
vi.mock("node:os", async (importOriginal) => {
|
|
18
|
-
const actual = await importOriginal<typeof import("node:os")>();
|
|
19
|
-
return { ...actual, homedir: () => "/nonexistent-home-for-tests" };
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
import { lintAgentMeta } from "../../orchestration/script-lint.ts";
|
|
23
|
-
import { parseResourceMeta } from "../../shared/meta-parser.ts";
|
|
24
|
-
import { AgentRegistry, parseAgentFrontmatter, parseAgentWithMeta } from "../agent-registry.ts";
|
|
25
|
-
import type { EnginePort } from "../engine/port.ts";
|
|
26
|
-
import { clearEngines, registerEngine } from "../engine/registry.ts";
|
|
27
|
-
|
|
28
|
-
// ============================================================
|
|
29
|
-
// helpers
|
|
30
|
-
// ============================================================
|
|
31
|
-
|
|
32
|
-
function tmpWorkspace(): string {
|
|
33
|
-
return fs.mkdtempSync(path.join(os.tmpdir(), "agent-reg-test-"));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function writeAgent(dir: string, name: string, body: string): string {
|
|
37
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
38
|
-
const filePath = path.join(dir, `${name}.md`);
|
|
39
|
-
fs.writeFileSync(filePath, body, "utf-8");
|
|
40
|
-
return filePath;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ============================================================
|
|
44
|
-
// parseAgentFrontmatter
|
|
45
|
-
// ============================================================
|
|
46
|
-
|
|
47
|
-
describe("parseAgentFrontmatter", () => {
|
|
48
|
-
it("parses name from filename + body as systemPrompt when no frontmatter", () => {
|
|
49
|
-
const cfg = parseAgentFrontmatter("/x/worker.md", "You are a worker.");
|
|
50
|
-
expect(cfg.name).toBe("worker");
|
|
51
|
-
expect(cfg.systemPrompt).toBe("You are a worker.");
|
|
52
|
-
});
|
|
53
|
-
it("extracts model/thinkingLevel/tools from frontmatter", () => {
|
|
54
|
-
const cfg = parseAgentFrontmatter("/x/coder.md", `---
|
|
55
|
-
name: coder
|
|
56
|
-
description: coding agent
|
|
57
|
-
model: anthropic/claude-3.5-sonnet
|
|
58
|
-
thinkingLevel: high
|
|
59
|
-
tools: [read, bash]
|
|
60
|
-
---
|
|
61
|
-
body text`);
|
|
62
|
-
expect(cfg.name).toBe("coder");
|
|
63
|
-
expect(cfg.model).toBe("anthropic/claude-3.5-sonnet");
|
|
64
|
-
expect(cfg.thinkingLevel).toBe("high");
|
|
65
|
-
expect(cfg.tools).toEqual(["read", "bash"]);
|
|
66
|
-
expect(cfg.systemPrompt).toBe("body text");
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// ============================================================
|
|
71
|
-
// parseAgentWithMeta(m5 T2:W4 lint 用 AgentMeta 二元组)
|
|
72
|
-
// ============================================================
|
|
73
|
-
|
|
74
|
-
describe("parseAgentWithMeta", () => {
|
|
75
|
-
it("有 frontmatter(IF1 通过):meta 非 null 且路由字段完整,config 同步正确", () => {
|
|
76
|
-
const { config, meta } = parseAgentWithMeta("/x/coder.md", `---
|
|
77
|
-
name: coder
|
|
78
|
-
description: 编码 agent
|
|
79
|
-
when: 需要写代码
|
|
80
|
-
notFor: 纯分析
|
|
81
|
-
model: anthropic/claude-3.5-sonnet
|
|
82
|
-
thinkingLevel: high
|
|
83
|
-
tools: [read, bash]
|
|
84
|
-
---
|
|
85
|
-
body text`);
|
|
86
|
-
expect(meta).not.toBeNull();
|
|
87
|
-
expect(meta!.kind).toBe("agent");
|
|
88
|
-
expect(meta!.name).toBe("coder");
|
|
89
|
-
expect(meta!.description).toBe("编码 agent");
|
|
90
|
-
expect(meta!.when).toBe("需要写代码");
|
|
91
|
-
expect(meta!.notFor).toBe("纯分析");
|
|
92
|
-
expect(config.name).toBe("coder");
|
|
93
|
-
expect(config.systemPrompt).toBe("body text");
|
|
94
|
-
expect(config.model).toBe("anthropic/claude-3.5-sonnet");
|
|
95
|
-
expect(config.thinkingLevel).toBe("high");
|
|
96
|
-
expect(config.tools).toEqual(["read", "bash"]);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("无 frontmatter:meta = null,整个内容作为 systemPrompt", () => {
|
|
100
|
-
const { config, meta } = parseAgentWithMeta("/x/plain.md", "Just a prompt body.");
|
|
101
|
-
expect(meta).toBeNull();
|
|
102
|
-
expect(config).toEqual({
|
|
103
|
-
name: "plain",
|
|
104
|
-
systemPrompt: "Just a prompt body.",
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it("MF-3 fallback:缺 description(IF1 返 null)时 model/tools 经 extractYamlField 仍生效", () => {
|
|
109
|
-
const { config, meta } = parseAgentWithMeta("/x/legacy.md", `---
|
|
110
|
-
name: legacy
|
|
111
|
-
model: anthropic/claude-3.5-sonnet
|
|
112
|
-
tools: read, bash, write
|
|
113
|
-
---
|
|
114
|
-
body text`);
|
|
115
|
-
// 缺 description → parseResourceMeta 返 null → meta 为 null(结构化路由不可见)
|
|
116
|
-
expect(meta).toBeNull();
|
|
117
|
-
// 但 config 的 model/tools 不丢(direct-path loadByPath 与重构前行为一致)
|
|
118
|
-
expect(config.name).toBe("legacy");
|
|
119
|
-
expect(config.model).toBe("anthropic/claude-3.5-sonnet");
|
|
120
|
-
expect(config.tools).toEqual(["read", "bash", "write"]);
|
|
121
|
-
expect(config.systemPrompt).toBe("body text");
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("未闭合 frontmatter:meta = null,name 经 extractYamlField fallback,其余作为 systemPrompt", () => {
|
|
125
|
-
const { config, meta } = parseAgentWithMeta("/x/broken.md", `---
|
|
126
|
-
name: broken
|
|
127
|
-
model: x/y`);
|
|
128
|
-
expect(meta).toBeNull();
|
|
129
|
-
expect(config.name).toBe("broken");
|
|
130
|
-
// 未闭合分支只取 name(原行为),不解析 model
|
|
131
|
-
expect(config.systemPrompt).toBe(`---\nname: broken\nmodel: x/y`);
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// ============================================================
|
|
136
|
-
// AgentRegistry.loadByPath(S2:agentRef = .md 绝对路径)
|
|
137
|
-
// ============================================================
|
|
138
|
-
|
|
139
|
-
describe("AgentRegistry.loadByPath", () => {
|
|
140
|
-
let ws: string;
|
|
141
|
-
beforeEach(() => { ws = tmpWorkspace(); });
|
|
142
|
-
afterEach(() => { fs.rmSync(ws, { recursive: true, force: true }); });
|
|
143
|
-
|
|
144
|
-
it("按绝对路径加载 agent:frontmatter + body → AgentConfig", () => {
|
|
145
|
-
const file = writeAgent(path.join(ws, ".pi", "agents"), "worker", `---
|
|
146
|
-
name: worker
|
|
147
|
-
description: 通用执行 agent
|
|
148
|
-
tools: [read, bash]
|
|
149
|
-
---
|
|
150
|
-
You are a worker.`);
|
|
151
|
-
const reg = new AgentRegistry();
|
|
152
|
-
const cfg = reg.loadByPath(file);
|
|
153
|
-
expect(cfg?.name).toBe("worker");
|
|
154
|
-
expect(cfg?.systemPrompt).toBe("You are a worker.");
|
|
155
|
-
expect(cfg?.tools).toEqual(["read", "bash"]);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it("无 frontmatter 文件:整个内容作为 systemPrompt", () => {
|
|
159
|
-
const file = writeAgent(ws, "plain", "Just a prompt body.");
|
|
160
|
-
const cfg = new AgentRegistry().loadByPath(file);
|
|
161
|
-
expect(cfg?.name).toBe("plain");
|
|
162
|
-
expect(cfg?.systemPrompt).toBe("Just a prompt body.");
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it("mtime 缓存:未变文件不重读(config 引用稳定)", () => {
|
|
166
|
-
const file = writeAgent(ws, "cached", "v1");
|
|
167
|
-
const reg = new AgentRegistry();
|
|
168
|
-
const first = reg.loadByPath(file);
|
|
169
|
-
const second = reg.loadByPath(file);
|
|
170
|
-
expect(second).toBe(first);
|
|
171
|
-
// 修改后 mtime 变化 → 新 config
|
|
172
|
-
fs.writeFileSync(file, "v2", "utf-8");
|
|
173
|
-
const third = reg.loadByPath(file);
|
|
174
|
-
expect(third?.systemPrompt).toBe("v2");
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it("相对路径引用返回 undefined(引用唯一形态 = 绝对路径)", () => {
|
|
178
|
-
const reg = new AgentRegistry();
|
|
179
|
-
expect(reg.loadByPath("worker")).toBeUndefined();
|
|
180
|
-
expect(reg.loadByPath("./agents/worker.md")).toBeUndefined();
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it("非 .md 引用返回 undefined", () => {
|
|
184
|
-
const reg = new AgentRegistry();
|
|
185
|
-
expect(reg.loadByPath("/tmp/worker.txt")).toBeUndefined();
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it("文件不存在返回 undefined,require=true 抛错带指引", () => {
|
|
189
|
-
const reg = new AgentRegistry();
|
|
190
|
-
expect(reg.loadByPath("/nonexistent/x.md")).toBeUndefined();
|
|
191
|
-
// R5(D7):三态错误文案统一带 <available_subagents> <location> 恢复指引
|
|
192
|
-
expect(() => reg.loadByPath("/nonexistent/x.md", true)).toThrow(/not found or unreadable/);
|
|
193
|
-
expect(() => reg.loadByPath("/nonexistent/x.md", true)).toThrow(/<available_subagents> <location>/);
|
|
194
|
-
expect(() => reg.loadByPath("relative", true)).toThrow(/Invalid agent ref/);
|
|
195
|
-
expect(() => reg.loadByPath("relative", true)).toThrow(/<available_subagents>/);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it("~/ 前缀展开", () => {
|
|
199
|
-
const reg = new AgentRegistry();
|
|
200
|
-
// homedir 被 mock 为 /nonexistent-home-for-tests → 文件必然不存在,验证展开逻辑
|
|
201
|
-
expect(reg.loadByPath("~/agent.md")).toBeUndefined();
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
// ============================================================
|
|
206
|
-
// 包内 agents/*.md 数据合规(S2:内置 agent = 包内路径文件)
|
|
207
|
-
// ============================================================
|
|
208
|
-
|
|
209
|
-
describe("builtin agents 数据合规", () => {
|
|
210
|
-
const AGENTS_DIR = path.resolve(__dirname, "../../../agents");
|
|
211
|
-
const CORE = ["explorer", "coder", "reviewer", "debugger", "analyst", "planner", "researcher", "orchestrator", "general-purpose", "doc-reviewer"];
|
|
212
|
-
|
|
213
|
-
it("agents/*.md 全部 IF1 解析成功", () => {
|
|
214
|
-
for (const f of fs.readdirSync(AGENTS_DIR).filter((x) => x.endsWith(".md"))) {
|
|
215
|
-
const meta = parseResourceMeta(fs.readFileSync(path.join(AGENTS_DIR, f), "utf-8"), "agent");
|
|
216
|
-
expect(meta?.kind, `${f} parse 失败`).toBe("agent");
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
it("核心 agent 均含 when/notFor/examples 且正反各一(lintAgentMeta 无 finding)", () => {
|
|
221
|
-
for (const name of CORE) {
|
|
222
|
-
const meta = parseResourceMeta(fs.readFileSync(path.join(AGENTS_DIR, `${name}.md`), "utf-8"), "agent");
|
|
223
|
-
expect(meta, `${name} 解析失败`).not.toBeNull();
|
|
224
|
-
if (meta?.kind !== "agent") continue;
|
|
225
|
-
expect(meta.when, `${name} 缺 when`).toBeDefined();
|
|
226
|
-
expect(meta.notFor, `${name} 缺 notFor`).toBeDefined();
|
|
227
|
-
expect(meta.examples?.length, `${name} 缺 examples`).toBeGreaterThanOrEqual(2);
|
|
228
|
-
expect(meta.examples?.some((e) => e.positive), `${name} 缺正向样本`).toBe(true);
|
|
229
|
-
expect(meta.examples?.some((e) => !e.positive), `${name} 缺反向样本`).toBe(true);
|
|
230
|
-
expect(lintAgentMeta(meta), `${name} examples 不合规`).toEqual([]);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it("loadByPath 直接加载包内 agent(内置 = 路径文件,无名字查找)", () => {
|
|
235
|
-
const reg = new AgentRegistry();
|
|
236
|
-
const coder = reg.loadByPath(path.join(AGENTS_DIR, "coder.md"));
|
|
237
|
-
expect(coder?.name).toBe("coder");
|
|
238
|
-
expect(coder?.systemPrompt.length).toBeGreaterThan(0);
|
|
239
|
-
// tools 字段精确匹配:未声明的为 undefined,声明的为具体数组。
|
|
240
|
-
// 改 frontmatter 时这里会立即报错,拦住拼写错误或字段遗漏。
|
|
241
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "explorer.md"))?.tools).toEqual(
|
|
242
|
-
["read", "bash", "grep", "find", "structured-output"],
|
|
243
|
-
);
|
|
244
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "researcher.md"))?.tools).toEqual(["read", "bash"]);
|
|
245
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "orchestrator.md"))?.tools).toEqual([
|
|
246
|
-
"todo", "goal_control", "workflow", "subagent", "ask_user",
|
|
247
|
-
]);
|
|
248
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "reviewer.md"))?.tools).toEqual(["read", "bash", "grep", "find", "structured-output"]);
|
|
249
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "planner.md"))?.tools).toEqual(["read", "bash", "grep", "find", "structured-output"]);
|
|
250
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "coder.md"))?.tools).toEqual(["read", "write", "edit", "bash", "grep", "find", "structured-output"]);
|
|
251
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "debugger.md"))?.tools).toEqual(["read", "write", "edit", "bash", "grep", "find", "structured-output"]);
|
|
252
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "analyst.md"))?.tools).toEqual(["read", "bash", "grep", "find", "structured-output"]);
|
|
253
|
-
expect(reg.loadByPath(path.join(AGENTS_DIR, "doc-reviewer.md"))?.tools).toEqual(["read", "grep", "structured-output"]);
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
// ============================================================
|
|
258
|
-
// engine 字段(P4 D9:frontmatter 主通道 + 解析期注册表校验)
|
|
259
|
-
// ============================================================
|
|
260
|
-
|
|
261
|
-
describe("parseAgentWithMeta engine 字段(P4 路由)", () => {
|
|
262
|
-
beforeEach(() => {
|
|
263
|
-
// 解析期校验消费注册表——测试内注册假引擎(惰性工厂无副作用)
|
|
264
|
-
clearEngines();
|
|
265
|
-
// 工厂恒 throw:解析期校验只查注册表存在性,不实例化(惰性工厂契约)
|
|
266
|
-
const neverInstantiate = (): EnginePort => {
|
|
267
|
-
throw new Error("parse-time validation must not instantiate engines");
|
|
268
|
-
};
|
|
269
|
-
registerEngine("pi", neverInstantiate);
|
|
270
|
-
registerEngine("zcode", neverInstantiate);
|
|
271
|
-
});
|
|
272
|
-
afterEach(() => {
|
|
273
|
-
clearEngines();
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
it("frontmatter engine 进 config.engine(结构化路径,IF1)", () => {
|
|
277
|
-
const { config, meta } = parseAgentWithMeta(
|
|
278
|
-
"/x/reviewer.md",
|
|
279
|
-
`---
|
|
280
|
-
name: reviewer
|
|
281
|
-
description: review agent
|
|
282
|
-
engine: zcode
|
|
283
|
-
---
|
|
284
|
-
body`,
|
|
285
|
-
);
|
|
286
|
-
expect(config.engine).toBe("zcode");
|
|
287
|
-
expect(meta?.kind === "agent" && meta.engine).toBe("zcode");
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
it("IF1 未通过(缺 description)时 legacy fallback 取 engine(配置不丢,与 model 同判)", () => {
|
|
291
|
-
const { config } = parseAgentWithMeta(
|
|
292
|
-
"/x/reviewer.md",
|
|
293
|
-
`---
|
|
294
|
-
name: reviewer
|
|
295
|
-
engine: zcode
|
|
296
|
-
---
|
|
297
|
-
body`,
|
|
298
|
-
);
|
|
299
|
-
expect(config.engine).toBe("zcode");
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it("未注册 engine id:解析期抛 EngineNotFoundError,文案含注册清单与文件路径", () => {
|
|
303
|
-
expect(() =>
|
|
304
|
-
parseAgentWithMeta(
|
|
305
|
-
"/x/reviewer.md",
|
|
306
|
-
`---
|
|
307
|
-
name: reviewer
|
|
308
|
-
description: review agent
|
|
309
|
-
engine: nonexistent-engine
|
|
310
|
-
---
|
|
311
|
-
body`,
|
|
312
|
-
),
|
|
313
|
-
).toThrowError(/engine_not_found: engine 'nonexistent-engine'/);
|
|
314
|
-
expect(() =>
|
|
315
|
-
parseAgentWithMeta(
|
|
316
|
-
"/x/reviewer.md",
|
|
317
|
-
`---
|
|
318
|
-
name: reviewer
|
|
319
|
-
description: review agent
|
|
320
|
-
engine: nonexistent-engine
|
|
321
|
-
---
|
|
322
|
-
body`,
|
|
323
|
-
),
|
|
324
|
-
).toThrowError(/Registered engines: pi, zcode/);
|
|
325
|
-
expect(() =>
|
|
326
|
-
parseAgentWithMeta(
|
|
327
|
-
"/x/my-agent.md",
|
|
328
|
-
`---
|
|
329
|
-
name: my-agent
|
|
330
|
-
description: d
|
|
331
|
-
engine: nonexistent-engine
|
|
332
|
-
---
|
|
333
|
-
body`,
|
|
334
|
-
),
|
|
335
|
-
).toThrowError(/Source: \/x\/my-agent\.md/);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
it("已注册 id(pi/zcode):解析通过,不抛", () => {
|
|
339
|
-
expect(() =>
|
|
340
|
-
parseAgentWithMeta(
|
|
341
|
-
"/x/reviewer.md",
|
|
342
|
-
`---
|
|
343
|
-
name: reviewer
|
|
344
|
-
description: review agent
|
|
345
|
-
engine: pi
|
|
346
|
-
---
|
|
347
|
-
body`,
|
|
348
|
-
),
|
|
349
|
-
).not.toThrow();
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
it("无 engine 字段:config.engine 缺省(走全局默认层)", () => {
|
|
353
|
-
const { config } = parseAgentWithMeta(
|
|
354
|
-
"/x/worker.md",
|
|
355
|
-
`---
|
|
356
|
-
name: worker
|
|
357
|
-
description: d
|
|
358
|
-
---
|
|
359
|
-
body`,
|
|
360
|
-
);
|
|
361
|
-
expect(config.engine).toBeUndefined();
|
|
362
|
-
});
|
|
363
|
-
});
|