@zhushanwen/subagent-core 0.4.0 → 0.5.1
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/dist/{chunk-4KN4TTG7.js → chunk-43ONBFZX.js} +1 -1
- package/dist/{chunk-X7SZ5HLQ.js → chunk-V3VHZ2VX.js} +20 -27
- package/dist/execution/engine/engines/zcode/constants.cjs +29 -41
- package/dist/execution/engine/engines/zcode/constants.d.cts +65 -53
- package/dist/execution/engine/engines/zcode/constants.d.ts +65 -53
- package/dist/execution/engine/engines/zcode/constants.js +17 -27
- package/dist/execution/engine/engines/zcode/reader.d.cts +2 -1
- package/dist/execution/engine/engines/zcode/reader.d.ts +2 -1
- package/dist/execution/engine/engines/zcode/reader.js +2 -2
- package/dist/index.cjs +16418 -14070
- package/dist/index.d.cts +5136 -4016
- package/dist/index.d.ts +5136 -4016
- package/dist/index.js +16343 -14048
- package/dist/{types-DpUO16pj.d.cts → types-Dv4QhSJ_.d.cts} +215 -112
- package/dist/{types-DpUO16pj.d.ts → types-Dv4QhSJ_.d.ts} +215 -112
- package/package.json +3 -3
- package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +0 -1
- package/src/__tests__/append-system-prompt-assembly.test.ts +8 -7
- package/src/__tests__/fr4-get-state-handshake.test.ts +2 -2
- package/src/__tests__/m2-append-content-probe.test.ts +0 -1
- package/src/__tests__/manifest-store.test.ts +10 -9
- package/src/__tests__/record-store-cache.test.ts +0 -2
- package/src/__tests__/record-store-index.test.ts +1 -2
- package/src/__tests__/review-fix-loop-script.test.ts +4 -2
- package/src/__tests__/review-fix-loop-utils.test.ts +10 -10
- package/src/__tests__/robustness-low-batch1.test.ts +6 -5
- package/src/__tests__/robustness-medium-batch1.test.ts +2 -2
- package/src/__tests__/robustness-medium-batch2.test.ts +17 -6
- package/src/__tests__/robustness-medium-batch4.test.ts +2 -2
- package/src/__tests__/session-runner.test.ts +1 -1
- package/src/core/__tests__/host-services.test.ts +2 -2
- package/src/core/__tests__/logger.test.ts +1 -1
- package/src/core/error-message.ts +9 -0
- package/src/core/host-services.ts +21 -5
- package/src/core/notify-ports.ts +18 -5
- package/src/execution/__tests__/agent-profile.test.ts +4 -4
- package/src/execution/__tests__/agent-registry.test.ts +370 -0
- package/src/execution/__tests__/agent-result-mapper.test.ts +18 -2
- package/src/execution/__tests__/agents-assembly.test.ts +2 -2
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
- package/src/execution/__tests__/chat-engine-routing.test.ts +68 -33
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +4 -4
- package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
- package/src/execution/__tests__/delivery-methods.test.ts +75 -62
- package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
- package/src/execution/__tests__/descendant-sweep.test.ts +6 -6
- package/src/execution/__tests__/dialog-queue.test.ts +2 -2
- package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
- package/src/execution/__tests__/epipe-fallback.test.ts +29 -24
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +21 -91
- package/src/execution/__tests__/execute-nesting.test.ts +34 -188
- package/src/execution/__tests__/execution-record.test.ts +217 -60
- package/src/execution/__tests__/execution-runtime-face.test.ts +5 -5
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +3 -3
- package/src/execution/__tests__/finalize-record.test.ts +173 -17
- package/src/execution/__tests__/gc-timer.test.ts +55 -2
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +12 -12
- package/src/execution/__tests__/get-state-handshake.test.ts +1 -1
- package/src/execution/__tests__/helpers/mock-extension-api.ts +1 -1
- package/src/execution/__tests__/helpers/session-runner-mocks.ts +113 -0
- package/src/execution/__tests__/helpers/spawn-mock.ts +150 -3
- package/src/execution/__tests__/helpers/subagent-service-mocks.ts +137 -0
- package/src/execution/__tests__/keep-alive-no-progress.test.ts +50 -148
- package/src/execution/__tests__/kill-all-escalation.test.ts +2 -2
- package/src/execution/__tests__/lifecycle-predicates.test.ts +1 -2
- package/src/execution/__tests__/manifest-parentid.test.ts +4 -4
- package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +1 -1
- package/src/execution/__tests__/model-resolver.test.ts +2 -2
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +23 -121
- package/src/execution/__tests__/nested-visibility.test.ts +2 -0
- package/src/execution/__tests__/notify-ledger.test.ts +973 -18
- package/src/execution/__tests__/output-collector.test.ts +117 -6
- package/src/execution/__tests__/pi-invocation.test.ts +1 -1
- package/src/execution/__tests__/record-store.test.ts +10 -9
- package/src/execution/__tests__/records-cwd-isolation.test.ts +2 -2
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +29 -132
- package/src/execution/__tests__/recursive-visibility-env.test.ts +55 -179
- package/src/execution/__tests__/rpc-mode.test.ts +2 -2
- package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +387 -0
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +15 -9
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +4 -4
- package/src/execution/__tests__/run-spawn-edges.test.ts +17 -15
- package/src/execution/__tests__/run-spawn-integration.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-resume.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +4 -4
- package/src/execution/__tests__/service-kill-escalation.test.ts +7 -5
- package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
- package/src/execution/__tests__/session-file-gc.test.ts +35 -0
- package/src/execution/__tests__/session-pending.test.ts +257 -14
- package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
- package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +1 -1
- package/src/execution/__tests__/session-runner-close-prune.test.ts +2 -2
- package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
- package/src/execution/__tests__/session-runner-epipe.test.ts +3 -3
- package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +5 -4
- package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +290 -0
- package/src/execution/__tests__/session-runner-schema-env.test.ts +7 -5
- package/src/execution/__tests__/settled-watchdog.test.ts +282 -47
- package/src/execution/__tests__/spawn-args.test.ts +11 -10
- package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +26 -23
- package/src/execution/__tests__/spawn-event-adapter.test.ts +1 -1
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
- package/src/execution/__tests__/spawned-children.test.ts +2 -1
- package/src/execution/__tests__/start-sync-model-guard.test.ts +4 -4
- package/src/execution/__tests__/stdin-writer.test.ts +6 -4
- package/src/execution/__tests__/stream-sink-retirement.test.ts +6 -6
- package/src/execution/__tests__/subagent-actions-core.test.ts +42 -22
- package/src/execution/__tests__/subagent-service-message-close.test.ts +29 -26
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +8 -8
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -22
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +30 -29
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +45 -20
- package/src/execution/__tests__/subagent-service.test.ts +37 -30
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +88 -12
- package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +75 -0
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +22 -20
- package/src/execution/__tests__/temp-prompt.test.ts +1 -1
- package/src/execution/__tests__/timeout-integration.test.ts +6 -5
- package/src/execution/__tests__/turn-limiter-semantics.test.ts +1 -1
- package/src/execution/__tests__/turn-limiter.test.ts +1 -1
- package/src/execution/__tests__/ui-request-handler-factory.test.ts +12 -6
- package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
- package/src/execution/__tests__/ui-request-queue.test.ts +142 -2
- package/src/execution/__tests__/worktree-manager.test.ts +14 -5
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +4 -3
- package/src/execution/agent-registry.ts +74 -30
- package/src/execution/agent-result-mapper.ts +3 -0
- package/src/execution/cold-resurrect.ts +199 -0
- package/src/execution/engine/__tests__/common/capability-gate.test.ts +91 -0
- package/src/execution/engine/__tests__/common/data-dir.test.ts +1 -1
- package/src/execution/engine/__tests__/common/journal-wiring.test.ts +84 -0
- package/src/execution/engine/__tests__/common/kill-chain.test.ts +34 -7
- package/src/execution/engine/__tests__/common/persona-router.test.ts +4 -5
- package/src/execution/engine/__tests__/common/pool-manager.test.ts +211 -51
- package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +149 -0
- package/src/execution/engine/__tests__/common/session-view-service.test.ts +499 -0
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +22 -112
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +15 -28
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +12 -12
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +1 -1
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +21 -82
- package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +4 -7
- package/src/execution/engine/__tests__/engine-discovery.test.ts +15 -3
- package/src/execution/engine/__tests__/model-prompt.test.ts +15 -3
- package/src/execution/engine/__tests__/registry.test.ts +4 -2
- package/src/execution/engine/__tests__/routing.test.ts +115 -6
- package/src/execution/engine/common/capability-gate.ts +92 -0
- package/src/execution/engine/common/journal-wiring.ts +97 -0
- package/src/execution/engine/common/kill-chain.ts +42 -10
- package/src/execution/engine/common/nesting-guard.ts +66 -0
- package/src/execution/engine/common/persona-router.ts +18 -8
- package/src/execution/engine/common/pool-manager.ts +332 -78
- package/src/execution/engine/common/session-view-service.ts +506 -0
- package/src/execution/engine/common/session-view-types.ts +125 -0
- package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +174 -28
- package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +257 -0
- package/src/execution/{argv-mirror.ts → engine/engines/pi/argv-mirror.ts} +43 -21
- package/src/execution/{get-state-handshake.ts → engine/engines/pi/get-state-handshake.ts} +1 -1
- package/src/execution/{output-collector.ts → engine/engines/pi/output-collector.ts} +108 -19
- package/src/execution/engine/engines/pi/pi-engine.ts +434 -38
- package/src/execution/{pi-invocation.ts → engine/engines/pi/pi-invocation.ts} +2 -2
- package/src/execution/engine/engines/pi/reader.ts +11 -0
- package/src/execution/engine/engines/pi/registration.ts +4 -2
- package/src/execution/{session-runner.ts → engine/engines/pi/session-runner.ts} +617 -412
- package/src/execution/{spawn-event-adapter.ts → engine/engines/pi/spawn-event-adapter.ts} +75 -34
- package/src/execution/{stdin-writer.ts → engine/engines/pi/stdin-writer.ts} +10 -9
- package/src/execution/{temp-prompt.ts → engine/engines/pi/temp-prompt.ts} +2 -2
- package/src/execution/{turn-limiter.ts → engine/engines/pi/turn-limiter.ts} +1 -1
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +54 -27
- package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
- package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +13 -12
- package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +7 -210
- package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +6 -110
- package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +247 -0
- package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +451 -0
- package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +20 -8
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +77 -110
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +25 -319
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +210 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +353 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +282 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +372 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +48 -148
- package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
- package/src/execution/engine/engines/zcode/connection.ts +24 -11
- package/src/execution/engine/engines/zcode/constants.ts +75 -71
- package/src/execution/engine/engines/zcode/golden-sample.ts +8 -46
- package/src/execution/engine/engines/zcode/parser.ts +12 -346
- package/src/execution/engine/engines/zcode/preparer.ts +12 -143
- package/src/execution/engine/engines/zcode/session-channel.ts +351 -39
- package/src/execution/engine/engines/zcode/zcode-engine.ts +665 -760
- package/src/execution/engine/host-task-spec.ts +32 -36
- package/src/execution/engine/model-validation.ts +177 -0
- package/src/execution/engine/port.ts +24 -6
- package/src/execution/engine/routing.ts +75 -1
- package/src/execution/engine/types.ts +30 -103
- package/src/execution/execution-record.ts +222 -144
- package/src/execution/finalize-record.ts +131 -93
- package/src/execution/idle-gc.ts +28 -0
- package/src/execution/lifecycle-predicates.ts +1 -1
- package/src/execution/notify-host.ts +212 -0
- package/src/execution/record-store.ts +119 -73
- package/src/execution/round-settlement.ts +93 -0
- package/src/execution/session-file-gc.ts +96 -62
- package/src/execution/session-reconstructor.ts +256 -143
- package/src/execution/sessions-index.ts +117 -47
- package/src/execution/settled-watchdog.ts +264 -52
- package/src/execution/subagent-actions-core.ts +22 -22
- package/src/execution/subagent-service.ts +815 -963
- package/src/execution/subprocess-agent-runner.ts +144 -97
- package/src/execution/types.ts +9 -0
- package/src/execution/ui-request-handler-factory.ts +102 -74
- package/src/execution/ui-request-queue.ts +50 -19
- package/src/index.ts +442 -316
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +1 -1
- package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
- package/src/orchestration/__tests__/args-validator.test.ts +14 -0
- package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +1 -1
- package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +11 -9
- package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
- package/src/orchestration/__tests__/file-run-store.test.ts +7 -6
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +2 -2
- package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +1 -1
- package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
- package/src/orchestration/__tests__/lifecycle.test.ts +7 -5
- package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
- package/src/orchestration/__tests__/run-snapshot.test.ts +8 -5
- package/src/orchestration/__tests__/script-lint.test.ts +17 -0
- package/src/orchestration/__tests__/test-mocks.ts +2 -0
- package/src/orchestration/__tests__/worker-exit-without-result.test.ts +7 -6
- package/src/orchestration/__tests__/worker-message-pump-finalize-run.test.ts +229 -0
- package/src/orchestration/__tests__/{error-recovery-handlers.test.ts → worker-message-pump-handlers.test.ts} +27 -19
- package/src/orchestration/__tests__/{error-recovery-postmessage-defense.test.ts → worker-message-pump-postmessage-defense.test.ts} +8 -8
- package/src/orchestration/__tests__/{error-recovery-serialize-failed-result.test.ts → worker-message-pump-serialize-failed-result.test.ts} +2 -2
- package/src/orchestration/__tests__/{error-recovery-workflow-call.test.ts → worker-message-pump-workflow-call.test.ts} +1 -1
- package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +1 -1
- package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
- package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
- package/src/orchestration/agent-opts-resolver.ts +1 -1
- package/src/orchestration/args-validator.ts +53 -31
- package/src/orchestration/execute-agent-call.ts +19 -73
- package/src/orchestration/launcher.ts +128 -81
- package/src/orchestration/lifecycle.ts +43 -45
- package/src/orchestration/models/ports.ts +4 -4
- package/src/orchestration/models/run-runtime.ts +2 -2
- package/src/orchestration/models/trace.ts +1 -1
- package/src/orchestration/models/types.ts +111 -22
- package/src/orchestration/models/workflow-run.ts +1 -1
- package/src/orchestration/script-lint.ts +91 -58
- package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +157 -150
- package/src/shared/__tests__/meta-parser.test.ts +151 -0
- package/src/shared/__tests__/resource-discovery.test.ts +258 -215
- package/src/shared/atomic-write.ts +12 -9
- package/src/shared/meta-parser.ts +158 -84
- package/src/shared/model-ref.ts +15 -2
- package/src/shared/resource-discovery.ts +9 -183
- package/src/shared/schema-jsonify.ts +1 -1
- package/workflows/review-fix-loop-utils.cjs +151 -89
- package/workflows/review-fix-loop-utils.d.cts +287 -0
- package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
- package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
- 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__/preparer-appserver.test.ts +0 -387
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -710
- package/src/execution/engine/engines/zcode/appserver-home.ts +0 -442
- package/src/execution/engine/engines/zcode/appserver-probe.ts +0 -141
- package/src/execution/engine/engines/zcode/launcher.ts +0 -161
- package/src/execution/execute-options-mapper.ts +0 -115
- package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/execution/engine/common/capability-gate.ts
|
|
2
|
+
//
|
|
3
|
+
// [D3-④ 预检 capabilities 化] 调用前预检的唯一实现(capabilities 驱动,无引擎 id
|
|
4
|
+
// 特判)。设计权威源:docs/design/subagent-dual-track-convergence.md §3.3 D3-④ + r3 裁定
|
|
5
|
+
// (EngineCapabilities 新增 maxTurns 能力位,不保留硬编码 shape 检查)+ §3.4 错误规格
|
|
6
|
+
// 第 1 行(engine_capability_unsupported,既有错误族)。
|
|
7
|
+
//
|
|
8
|
+
// 判据形态:每个引擎拦截「自己 capabilities 声明不支持的能力」——
|
|
9
|
+
// - conversation → capabilities.conversation === 'unsupported'
|
|
10
|
+
// - fork/forkFromSessionFile → session 分叉通道族全缺(steer 与 conversation 均
|
|
11
|
+
// 'unsupported',见下方 fork 判据说明)
|
|
12
|
+
// - maxTurns → capabilities.maxTurns === false(r3 扩位)
|
|
13
|
+
// - worktree(boolean true 或 WorktreeHandle)→ capabilities.sandbox === 'none'
|
|
14
|
+
//
|
|
15
|
+
// 调用点仍是两处(单点的是实现,不是调用点):
|
|
16
|
+
// - chat 域:executeViaEngine 同步段、record 创建前(engine.capabilities() 同步可得,
|
|
17
|
+
// 承接「全部同步拒绝发生在 record 创建前、不产生孤儿 record」不变量);
|
|
18
|
+
// - workflow 域:SAR.run 路由后、engine.run 前(同模块调用)。
|
|
19
|
+
//
|
|
20
|
+
// 行为变化声明(§3.4):唯一有意行为变化 = workflow 域 zcode+worktree 由漏拦变拦截
|
|
21
|
+
// (修复双轨清单 #7 的跨域缺口);pi 的 maxTurns/fork/conversation/worktree 等既有
|
|
22
|
+
// 合法能力零拦截(V4⑤ 反向守护——pi 声明 conversation='native'、sandbox='emulated'、
|
|
23
|
+
// maxTurns=true,全数放行)。
|
|
24
|
+
|
|
25
|
+
import { EngineError } from "./errors.ts";
|
|
26
|
+
import type { EngineCapabilities } from "../types.ts";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 预检输入的任务形状子集——ExecuteOptions(chat 域)与 AgentCallOpts(D6 合流后的
|
|
30
|
+
* 单一任务形状,workflow 域 SAR 直传)共有的能力相关字段面。结构子集而非具体类型:
|
|
31
|
+
* 两域的 opts 类型都能直接传入。
|
|
32
|
+
*/
|
|
33
|
+
export interface TaskShapeForGate {
|
|
34
|
+
conversation?: boolean;
|
|
35
|
+
fork?: boolean;
|
|
36
|
+
forkFromSessionFile?: string;
|
|
37
|
+
worktree?: boolean | { path: string };
|
|
38
|
+
maxTurns?: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 调用前预检:任务形状中的能力参数对引擎 capabilities 逐一对照,声明不支持即抛
|
|
43
|
+
* EngineError(engine_capability_unsupported)——同步 throw、进程/record 创建前,文案
|
|
44
|
+
* 含 capabilities 依据与恢复指引(换参数/换引擎)。
|
|
45
|
+
*
|
|
46
|
+
* fork 判据说明(借位裁定):fork 依赖父 session 上下文继承(父会话文件作为分叉源),
|
|
47
|
+
* 引擎具备该语义的能力面信号 = 会话分叉/交互通道族(steer 或 conversation 任一非
|
|
48
|
+
* 'unsupported')。pi conversation='native'(chatMode idle 复用)→ 放行;zcode 双
|
|
49
|
+
* 'unsupported'(argv-only spawn 单轮,无父 session 分叉通道)→ 拒绝。仅凭 steer 判
|
|
50
|
+
* 会误拦 pi(pi 的 steer 声明 'unsupported'——RPC 有但 spawn 链路未接通,与 fork 的
|
|
51
|
+
* 初始上下文继承是两条轴),故取通道族任一可用即支持的分寸。
|
|
52
|
+
*/
|
|
53
|
+
export function assertTaskShapeSupported(
|
|
54
|
+
engineId: string,
|
|
55
|
+
caps: EngineCapabilities,
|
|
56
|
+
task: TaskShapeForGate,
|
|
57
|
+
): void {
|
|
58
|
+
if (task.conversation === true && caps.conversation === "unsupported") {
|
|
59
|
+
throw new EngineError(
|
|
60
|
+
"engine_capability_unsupported",
|
|
61
|
+
`engine '${engineId}' 不支持 conversation(capabilities.conversation = 'unsupported',` +
|
|
62
|
+
`spawn 单轮模式无同进程 idle 复用,message/close 交互控制面不可用)`,
|
|
63
|
+
`改用 engine: pi(支持 conversation 续聊),或不传该参数(一次性任务默认形态)`,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
if (task.fork === true || task.forkFromSessionFile !== undefined) {
|
|
67
|
+
if (caps.steer === "unsupported" && caps.conversation === "unsupported") {
|
|
68
|
+
throw new EngineError(
|
|
69
|
+
"engine_capability_unsupported",
|
|
70
|
+
`engine '${engineId}' 不支持 fork${task.forkFromSessionFile !== undefined ? "(fork-from 同为父 session 上下文继承)" : ""}(fork 依赖父 session 上下文继承,` +
|
|
71
|
+
`capabilities.steer = '${caps.steer}' / conversation = '${caps.conversation}'——引擎无父 session 分叉通道)`,
|
|
72
|
+
`把所需父上下文写进 task 正文后不传 fork,或改用 engine: pi`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (task.maxTurns !== undefined && caps.maxTurns === false) {
|
|
77
|
+
throw new EngineError(
|
|
78
|
+
"engine_capability_unsupported",
|
|
79
|
+
`engine '${engineId}' 不支持 maxTurns(capabilities.maxTurns = false,轮数上限依赖 turn_end 事件流,` +
|
|
80
|
+
`本引擎无此语义——静默丢弃会造成「传了上限却失控」的假象)`,
|
|
81
|
+
`去掉 maxTurns 参数重派,或改用 engine: pi(turn limiter 执行轮数上限)`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if ((task.worktree === true || typeof task.worktree === "object") && caps.sandbox === "none") {
|
|
85
|
+
throw new EngineError(
|
|
86
|
+
"engine_capability_unsupported",
|
|
87
|
+
`engine '${engineId}' 不支持 worktree 隔离(capabilities.sandbox = 'none',` +
|
|
88
|
+
`引擎未接文件系统隔离层)`,
|
|
89
|
+
`改用 engine: pi(worktree 隔离可用),或不传该参数(在 parent cwd 执行)`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// src/execution/engine/common/journal-wiring.ts
|
|
2
|
+
//
|
|
3
|
+
// [D3-③ journal 接线合一] host 侧 event journal 接线的共享 helper(唯一实现,两调用
|
|
4
|
+
// 点——SubagentService.runEngineTask(chat 域)与 SubprocessAgentRunner.run(workflow
|
|
5
|
+
// 域))。设计权威源:docs/design/subagent-dual-track-convergence.md §3.3 D3-③(writer +
|
|
6
|
+
// retarget + handle 回填两份提为 common 层共享 helper)+ 双轨清单 #6。
|
|
7
|
+
//
|
|
8
|
+
// 收敛前形态(两份同构接线):
|
|
9
|
+
// - subagent-service.ts:new JournalWriter(占位池 key 'shared')+ retarget 闭包 +
|
|
10
|
+
// record.engineHandle.journalPath 回填;
|
|
11
|
+
// - subprocess-agent-runner.ts:new JournalWriter(占位 PI_POOL_KEY)+ retarget 闭包 +
|
|
12
|
+
// journalingOnEvent 包装(先落盘再转发 workflow liveRecord)+ handle.data.journalPath 回填。
|
|
13
|
+
//
|
|
14
|
+
// 机制语义(对齐点③:路径权威 = 引擎声明的池 key):writer 初始用占位池 key 建路径,
|
|
15
|
+
// 非池化稳定引擎(zcode)在 prepare 期经 RunContext.onPoolResolved 声明实际池 key →
|
|
16
|
+
// retarget——保证 journal 落盘路径与 handle.poolKey 同源。run 终态后 close(flush +
|
|
17
|
+
// fsync 一次,§3.3.6 写入纪律;写失败已由 writer 内部 warn + failed 收口,close 不抛,
|
|
18
|
+
// journal 是②级尽力而为数据源)。
|
|
19
|
+
|
|
20
|
+
import type { AgentEvent } from "../../../shared/agent-event.ts";
|
|
21
|
+
import { getEngineDataDir } from "./data-dir.ts";
|
|
22
|
+
import { JournalWriter } from "./event-journal.ts";
|
|
23
|
+
import { resolveJournalPath } from "../paths.ts";
|
|
24
|
+
import type { EngineHandle } from "../types.ts";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* journal 初始占位池 key(= pi 的恒定池 key 'shared')。pi 无隔离池
|
|
28
|
+
* (PI_CODING_AGENT_DIR 全局一份,设计 §3.3.9),占位即终值;zcode 在 prepare 期
|
|
29
|
+
* retarget 到实际池 key。值与 RunContext.poolKey 的初始占位同源——本常量是该值在
|
|
30
|
+
* common 层的单一权威(原先 Service 用 'shared' 字面量、SAR 用 PI_POOL_KEY,等值异名)。
|
|
31
|
+
*/
|
|
32
|
+
export const JOURNAL_INITIAL_POOL_KEY = "shared";
|
|
33
|
+
|
|
34
|
+
/** wireEventJournal 的参数。 */
|
|
35
|
+
export interface JournalWiringOptions {
|
|
36
|
+
/** 实际执行引擎 id(journal 路径分段 + line 元数据)。 */
|
|
37
|
+
engineId: string;
|
|
38
|
+
/** 宿主侧任务标识(journal 文件名与池引用计数 key:chat 域 = record.id;workflow 域 = 'sa-' 前缀占位)。 */
|
|
39
|
+
taskId: string;
|
|
40
|
+
/**
|
|
41
|
+
* journal 落盘后的事件转发(workflow 域的 liveRecord 通道)。缺省不转发(chat 域
|
|
42
|
+
* 无下游 onEvent 消费者——journal 是事件唯一出口)。
|
|
43
|
+
*/
|
|
44
|
+
forwardEvents?: (event: AgentEvent) => void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** wireEventJournal 的产物(喂给 RunContext 的回调簇 + 终态收口/回填面)。 */
|
|
48
|
+
export interface JournalWiring {
|
|
49
|
+
/** journaling onEvent:先落盘再转发——RunContext.onEvent 的值。 */
|
|
50
|
+
onEvent: (event: AgentEvent) => void;
|
|
51
|
+
/** RunContext.onPoolResolved 的值(引擎声明实际池 key 后重定向落盘路径)。 */
|
|
52
|
+
onPoolResolved: (poolKey: string) => void;
|
|
53
|
+
/**
|
|
54
|
+
* 终态落盘路径(writer 是路径权威——retarget 后的实际路径)。read 第②级的自描述
|
|
55
|
+
* 定位符数据源:record.engineHandle.journalPath(chat 域)与 handle.data.journalPath
|
|
56
|
+
* (workflow 域 backfillHandle)都取本值。
|
|
57
|
+
*/
|
|
58
|
+
readonly path: string;
|
|
59
|
+
/** run 终态收口(flush + fsync;幂等,不抛——见文件头)。 */
|
|
60
|
+
close(): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* handle 回填:EngineHandleData.journalPath = writer 终态路径(read ②级经
|
|
63
|
+
* handle.journalPath 自描述定位——运行期落盘路径权威在 writer)。
|
|
64
|
+
*/
|
|
65
|
+
backfillHandle(handle: EngineHandle): void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 接线 host 侧 event journal(两域共用):创建 writer(占位池 key)+ retarget 回调 +
|
|
70
|
+
* journaling onEvent 包装 + 终态路径访问。close 在 run 终态(成功/失败路径均达)调用。
|
|
71
|
+
*/
|
|
72
|
+
export function wireEventJournal(opts: JournalWiringOptions): JournalWiring {
|
|
73
|
+
const journal = new JournalWriter({
|
|
74
|
+
path: resolveJournalPath(getEngineDataDir(), opts.engineId, JOURNAL_INITIAL_POOL_KEY, opts.taskId),
|
|
75
|
+
taskId: opts.taskId,
|
|
76
|
+
engineId: opts.engineId,
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
// 先落盘再转发(原 onEvent 未传时也恒传包装版——下游 onEvent 通道是事件生成后的
|
|
80
|
+
// 纯转发,无行为分支,仅多一次入队)
|
|
81
|
+
onEvent: (event) => {
|
|
82
|
+
journal.append(event);
|
|
83
|
+
opts.forwardEvents?.(event);
|
|
84
|
+
},
|
|
85
|
+
onPoolResolved: (poolKey) => {
|
|
86
|
+
journal.retarget(resolveJournalPath(getEngineDataDir(), opts.engineId, poolKey, opts.taskId));
|
|
87
|
+
},
|
|
88
|
+
// getter 而非快照:retarget 后取实际落盘路径(writer 是路径权威)
|
|
89
|
+
get path() {
|
|
90
|
+
return journal.path;
|
|
91
|
+
},
|
|
92
|
+
close: () => journal.close(),
|
|
93
|
+
backfillHandle: (handle) => {
|
|
94
|
+
handle.data.journalPath = journal.path;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
import { getLogger } from "../../../core/logger.ts";
|
|
11
11
|
|
|
12
12
|
import { engineTimeoutDetail } from "./errors.ts";
|
|
13
|
-
import type {
|
|
13
|
+
import type { AgentCallOpts } from "../../../orchestration/models/types.ts";
|
|
14
|
+
import type { AgentOutcome } from "../types.ts";
|
|
14
15
|
import { DEFAULT_ENGINE_ID } from "../registry.ts";
|
|
16
|
+
import { toErrorMessage } from "../../../core/error-message.ts";
|
|
15
17
|
|
|
16
18
|
const logger = getLogger("subagents");
|
|
17
19
|
|
|
@@ -34,6 +36,11 @@ export interface KillableChild {
|
|
|
34
36
|
once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): unknown;
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
// 毫秒→秒换算(SIGKILL 升级 warn 日志的秒数显示)。文件内私有定义:工程内 MS_PER_SECOND
|
|
40
|
+
// 惯例是各使用文件私有常量(execution-record / lifecycle-manager / session-file-gc /
|
|
41
|
+
// session-runner 四处先例),无共享导出源可 import,保持同惯例不另立导出点。
|
|
42
|
+
const MS_PER_SECOND = 1_000;
|
|
43
|
+
|
|
37
44
|
/** SIGTERM 优雅窗口默认值(ms)。实测校准点:设计 §5 待验证检查点⑤(zcode 对 SIGTERM 的响应时序)。 */
|
|
38
45
|
export const DEFAULT_KILL_GRACE_MS = 5_000;
|
|
39
46
|
|
|
@@ -47,6 +54,25 @@ const SIGKILL_REAP_TIMEOUT_MS = 10_000;
|
|
|
47
54
|
*/
|
|
48
55
|
export const HOST_TIMEOUT_ABORT_REASON = "agent-call-timeout";
|
|
49
56
|
|
|
57
|
+
/** killChain 的参数形状。 */
|
|
58
|
+
export interface KillChainOptions {
|
|
59
|
+
/**
|
|
60
|
+
* SIGTERM 优雅窗口(ms)。grace 窗口按引擎参数化(D3-① 杀链合一):pi 传 30s
|
|
61
|
+
* ([race-F4] 现状值)、zcode 传 5s(ZCODE_KILL_GRACE_MS)——两引擎现状逐字节保持。
|
|
62
|
+
*/
|
|
63
|
+
graceMs: number;
|
|
64
|
+
/**
|
|
65
|
+
* [D3-①] 内部 timer unref。pi 路径现状 = 升级 timer unref(不阻止主进程退出,dispose
|
|
66
|
+
* killAll 兜底);zcode 现状 = ref'd(timer 挂起时进程等待收尸)——各引擎按现状传。
|
|
67
|
+
*/
|
|
68
|
+
unrefTimers?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* SIGKILL 升级时的 warn 留痕载体(如 `child sa-xxx (source: spawn watchdog)`)。
|
|
71
|
+
* 不传则升级静默(zcode 现状)——pi 侧现状有 warn,由调用方组装完整语境。
|
|
72
|
+
*/
|
|
73
|
+
escalationNote?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
50
76
|
/**
|
|
51
77
|
* 杀链:SIGTERM → 等待 graceMs → 仍存活则 SIGKILL。
|
|
52
78
|
*
|
|
@@ -54,7 +80,7 @@ export const HOST_TIMEOUT_ABORT_REASON = "agent-call-timeout";
|
|
|
54
80
|
*/
|
|
55
81
|
export async function killChain(
|
|
56
82
|
child: KillableChild,
|
|
57
|
-
opts:
|
|
83
|
+
opts: KillChainOptions,
|
|
58
84
|
): Promise<"terminated" | "killed"> {
|
|
59
85
|
// 已退出(自然/已被杀)→ 无需发信号,按优雅终止口径返回
|
|
60
86
|
if (child.exitCode !== null || child.signalCode !== null) return "terminated";
|
|
@@ -62,14 +88,19 @@ export async function killChain(
|
|
|
62
88
|
const exited = waitForExit(child);
|
|
63
89
|
safeKill(child, "SIGTERM");
|
|
64
90
|
|
|
65
|
-
const graceful = await raceTimeout(exited, opts.graceMs);
|
|
91
|
+
const graceful = await raceTimeout(exited, opts.graceMs, opts.unrefTimers === true);
|
|
66
92
|
if (graceful === "settled") return "terminated";
|
|
67
93
|
// grace 超时后进程可能恰好在检查前一刻退出——复核退出态,避免误杀已死进程
|
|
68
94
|
if (child.exitCode !== null || child.signalCode !== null) return "terminated";
|
|
69
95
|
|
|
96
|
+
if (opts.escalationNote !== undefined) {
|
|
97
|
+
logger.warn(
|
|
98
|
+
`[kill-chain] ${opts.escalationNote} still alive ${opts.graceMs / MS_PER_SECOND}s after SIGTERM, escalating to SIGKILL`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
70
101
|
safeKill(child, "SIGKILL");
|
|
71
102
|
// 有界收尸:无论等到与否都返回 'killed'(信号已发出,返回值表达「走了 SIGKILL」)
|
|
72
|
-
await raceTimeout(exited, SIGKILL_REAP_TIMEOUT_MS);
|
|
103
|
+
await raceTimeout(exited, SIGKILL_REAP_TIMEOUT_MS, opts.unrefTimers === true);
|
|
73
104
|
return "killed";
|
|
74
105
|
}
|
|
75
106
|
|
|
@@ -83,7 +114,7 @@ function safeKill(child: KillableChild, signal: NodeJS.Signals): void {
|
|
|
83
114
|
child.kill(signal);
|
|
84
115
|
} catch (err) {
|
|
85
116
|
logger.debug(
|
|
86
|
-
`[kill-chain] ${signal} on exited process: ${
|
|
117
|
+
`[kill-chain] ${signal} on exited process: ${toErrorMessage(err)}`,
|
|
87
118
|
);
|
|
88
119
|
}
|
|
89
120
|
}
|
|
@@ -98,14 +129,14 @@ function safeKill(child: KillableChild, signal: NodeJS.Signals): void {
|
|
|
98
129
|
* exitCode: null = 被信号杀死(AgentOutcome 的杀链判据,§3.3.5)。
|
|
99
130
|
*/
|
|
100
131
|
export function synthesizeTimeoutOutcome(
|
|
101
|
-
task:
|
|
132
|
+
task: AgentCallOpts,
|
|
102
133
|
stdoutTail: string,
|
|
103
134
|
engineId: string = DEFAULT_ENGINE_ID,
|
|
104
135
|
): AgentOutcome {
|
|
105
136
|
return {
|
|
106
137
|
content: "",
|
|
107
138
|
// slug 进错误信息:单看 outcome(record 之外)也能定位是哪个任务超时
|
|
108
|
-
error: `engine_timeout: [slug=${task.
|
|
139
|
+
error: `engine_timeout: [slug=${task.description ?? "unknown"}] ${engineTimeoutDetail(stdoutTail)}`,
|
|
109
140
|
// 被信号杀死:退出码语义为 null(§3.3.5 AgentOutcome.exitCode 注释)
|
|
110
141
|
exitCode: null,
|
|
111
142
|
engineId,
|
|
@@ -161,7 +192,7 @@ export function abortWithFallback(
|
|
|
161
192
|
// debug 级留诊断线索:这不是错误终态,只是该引擎优雅中断不可用
|
|
162
193
|
logger.debug(
|
|
163
194
|
`[kill-chain] native interrupt failed, falling back to kill chain: ${
|
|
164
|
-
|
|
195
|
+
toErrorMessage(err)
|
|
165
196
|
}`,
|
|
166
197
|
);
|
|
167
198
|
}
|
|
@@ -202,10 +233,11 @@ function waitForExit(child: KillableChild): Promise<void> {
|
|
|
202
233
|
});
|
|
203
234
|
}
|
|
204
235
|
|
|
205
|
-
/** promise vs 超时:超时先到返回 'timeout'(promise 继续但被放弃等待)。 */
|
|
206
|
-
function raceTimeout(p: Promise<void>, ms: number): Promise<"settled" | "timeout"> {
|
|
236
|
+
/** promise vs 超时:超时先到返回 'timeout'(promise 继续但被放弃等待)。unref 见 KillChainOptions。 */
|
|
237
|
+
function raceTimeout(p: Promise<void>, ms: number, unref = false): Promise<"settled" | "timeout"> {
|
|
207
238
|
return new Promise<"settled" | "timeout">((resolve) => {
|
|
208
239
|
const timer = setTimeout(() => resolve("timeout"), ms);
|
|
240
|
+
if (unref) timer.unref();
|
|
209
241
|
p.then(
|
|
210
242
|
() => {
|
|
211
243
|
clearTimeout(timer);
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
//
|
|
9
9
|
// 为什么 env 标记是唯一跨引擎可靠手段(被否方案见设计):「隔离目录里不装扩展」
|
|
10
10
|
// 依赖配置洁癖,且 opencode/CC 会吃项目级配置;env 由宿主显式控制,随 spawn 必达。
|
|
11
|
+
//
|
|
12
|
+
// [D3-⑤ 嵌套防护合一] 进程内执行嵌套上下文(原 SubagentService.execCtxAls,pi 路径
|
|
13
|
+
// 私有)并入本文件——「嵌套防护」的两层机制(跨进程 env 标记 / 进程内 ALS 深度计数)
|
|
14
|
+
// 单点于公共层。设计权威源:docs/design/subagent-dual-track-convergence.md §3.3 D3-⑤
|
|
15
|
+
// + 双轨清单 #10。
|
|
16
|
+
|
|
17
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
11
18
|
|
|
12
19
|
import { nestedSpawnRejectedError } from "./errors.ts";
|
|
13
20
|
|
|
@@ -48,3 +55,62 @@ export function assertNotNestedSpawn(env: SpawnEnv): void {
|
|
|
48
55
|
throw nestedSpawnRejectedError();
|
|
49
56
|
}
|
|
50
57
|
}
|
|
58
|
+
|
|
59
|
+
// ============================================================
|
|
60
|
+
// [D3-⑤] 进程内执行嵌套上下文(原 SubagentService.execCtxAls 下沉)
|
|
61
|
+
// ============================================================
|
|
62
|
+
|
|
63
|
+
/** 执行嵌套状态:当前正在跑的 record 身份 + 递归深度(D-033 通用嵌套深度护栏的计数载体)。 */
|
|
64
|
+
export interface ExecutionNestingState {
|
|
65
|
+
recordId: string | undefined;
|
|
66
|
+
depth: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 进程内执行嵌套上下文([D3-⑤] 从 SubagentService 的 execCtxAls 私有字段并入公共层)。
|
|
71
|
+
*
|
|
72
|
+
* 机制(原样迁移,行为零变化):
|
|
73
|
+
* - ALS 按异步调用链传递当前 record 身份:B run() 期间包 this 上下文,B 内创建 C 时
|
|
74
|
+
* 读到 B → C.parentRecordId=B.id、C.depth=B.depth+1;主 session 链上无 store → 顶层。
|
|
75
|
+
* - 进程级基线兜底 [ALS 断裂修复]:pi RPC mode 的 stdin JSONL 是事件回调式
|
|
76
|
+
* (attachJsonlLineReader stream.on("data")),每个命令是独立异步链,enterWith 的
|
|
77
|
+
* store 不会贯穿到后续 tool 调用事件(实测:递归第二层 parentRecordId/depth 丢失
|
|
78
|
+
* 而 rootSessionId 正确)。基线 = 本进程自己的身份(initSession 从 env 读取):
|
|
79
|
+
* 读 ALS store 失败时兜底,保证「本进程派发的 subagent 都是本进程记录的孩子」。
|
|
80
|
+
*
|
|
81
|
+
* 实例归属:per-Service(基线随宿主进程身份而异),Service 构造时创建并持有。
|
|
82
|
+
* 深度上限判据(MAX_FORK_DEPTH)留在调用方——上限常量属 execution 层
|
|
83
|
+
* (session-context-resolver),公共层只提供状态存取单点。
|
|
84
|
+
*/
|
|
85
|
+
export class ExecutionNestingContext {
|
|
86
|
+
private readonly als = new AsyncLocalStorage<ExecutionNestingState>();
|
|
87
|
+
private baselineState: ExecutionNestingState | null = null;
|
|
88
|
+
|
|
89
|
+
/** 建立进程级基线(initSession:有 env 自我标记 → env 身份;根进程 → null 顶层)。 */
|
|
90
|
+
setBaseline(state: ExecutionNestingState | null): void {
|
|
91
|
+
this.baselineState = state;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** 读当前嵌套状态:ALS store 优先,断裂时基线兜底(顶层 = null)。 */
|
|
95
|
+
current(): ExecutionNestingState | null {
|
|
96
|
+
return this.als.getStore() ?? this.baselineState;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 读进程级基线(与 current() 的差异:不看 ALS store——直接父归属校验等场景要的是
|
|
101
|
+
* 「本进程自己的身份」而非「当前异步链正在跑的 record 身份」)。
|
|
102
|
+
*/
|
|
103
|
+
baseline(): ExecutionNestingState | null {
|
|
104
|
+
return this.baselineState;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** 包裹执行(B run() 期间挂 B 身份——内层创建 C 时 current() 读到 B)。 */
|
|
108
|
+
run<T>(state: ExecutionNestingState, fn: () => T): T {
|
|
109
|
+
return this.als.run(state, fn);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** 顶层 enterWith(initSession 建立基线身份后挂入当前异步链)。 */
|
|
113
|
+
enterWith(state: ExecutionNestingState): void {
|
|
114
|
+
this.als.enterWith(state);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -14,7 +14,18 @@
|
|
|
14
14
|
// - 'prompt'→ promptSegment 为带引导结构的人设段(拼进最终 prompt——zcode 形态)。
|
|
15
15
|
|
|
16
16
|
import { promptTooLargeError } from "./errors.ts";
|
|
17
|
-
import type { EngineCapabilities
|
|
17
|
+
import type { EngineCapabilities } from "../types.ts";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 人设注入内容([D6 合流] 原 PersonaSpec 的内容面——收拢层删除后 persona 路由
|
|
21
|
+
* 只需人设正文的两个来源字段,取合流形状 AgentCallOpts 的结构子集:appendSystemPrompt
|
|
22
|
+
* 是人设正文,skillPath 以引用提示行进文本。原 agentRef 字段随 PersonaSpec 裁撤
|
|
23
|
+
* (无生产写入方)。
|
|
24
|
+
*/
|
|
25
|
+
export interface PersonaContent {
|
|
26
|
+
appendSystemPrompt?: string[];
|
|
27
|
+
skillPath?: string;
|
|
28
|
+
}
|
|
18
29
|
|
|
19
30
|
// ============================================================
|
|
20
31
|
// persona 三策略路由
|
|
@@ -35,10 +46,10 @@ const PERSONA_FILE_NAME = "persona.md";
|
|
|
35
46
|
* 按 capabilities.personaInjection 路由 persona 的注入通道。
|
|
36
47
|
*
|
|
37
48
|
* router 不解析 agent .md / skill 文件内容(身份解析归宿主 resolveIdentity)——
|
|
38
|
-
* 只把
|
|
39
|
-
*
|
|
49
|
+
* 只把 PersonaContent 声明的内容组装成通道载体:appendSystemPrompt 是人设正文,
|
|
50
|
+
* skillPath 以引用提示行进文本(prompt 通道)或正文头(file 通道)。
|
|
40
51
|
*/
|
|
41
|
-
export function applyPersona(persona:
|
|
52
|
+
export function applyPersona(persona: PersonaContent, capabilities: EngineCapabilities): PersonaRouting {
|
|
42
53
|
switch (capabilities.personaInjection) {
|
|
43
54
|
case "file": {
|
|
44
55
|
const content = buildPersonaBody(persona);
|
|
@@ -54,10 +65,9 @@ export function applyPersona(persona: PersonaSpec, capabilities: EngineCapabilit
|
|
|
54
65
|
}
|
|
55
66
|
}
|
|
56
67
|
|
|
57
|
-
/** 人设正文:appendSystemPrompt join +
|
|
58
|
-
function buildPersonaBody(persona:
|
|
68
|
+
/** 人设正文:appendSystemPrompt join + skillPath 头部引用行。 */
|
|
69
|
+
function buildPersonaBody(persona: PersonaContent): string {
|
|
59
70
|
const parts: string[] = [];
|
|
60
|
-
if (persona.agentRef !== undefined) parts.push(`# Agent: ${persona.agentRef}`);
|
|
61
71
|
if (persona.skillPath !== undefined) parts.push(`Skill context: ${persona.skillPath}`);
|
|
62
72
|
const body = persona.appendSystemPrompt?.join("\n") ?? "";
|
|
63
73
|
if (body !== "") parts.push(body);
|
|
@@ -65,7 +75,7 @@ function buildPersonaBody(persona: PersonaSpec): string {
|
|
|
65
75
|
}
|
|
66
76
|
|
|
67
77
|
/** prompt 通道的人设段(带结构头,拼进最终 prompt)。 */
|
|
68
|
-
function buildPromptSegment(persona:
|
|
78
|
+
function buildPromptSegment(persona: PersonaContent): string {
|
|
69
79
|
const body = buildPersonaBody(persona);
|
|
70
80
|
if (body === "") return "";
|
|
71
81
|
return `## Persona\n${body}`;
|