@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/execution/engine/engines/pi/spawn-event-adapter.ts
|
|
2
2
|
//
|
|
3
3
|
// pi 子进程 stdout JSON 事件流的解析器。Core 叶子原语(仅依赖 types.ts)。
|
|
4
4
|
//
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
import * as fs from "node:fs";
|
|
21
21
|
import * as path from "node:path";
|
|
22
22
|
|
|
23
|
-
import type { SdkEvent } from "
|
|
23
|
+
import type { SdkEvent } from "../../../types.ts";
|
|
24
|
+
import { toErrorMessage } from "../../../../core/error-message.ts";
|
|
24
25
|
|
|
25
26
|
/** pi stdout header 行(session 元信息)。type 固定为 "session"。 */
|
|
26
27
|
export interface SpawnSessionHeader {
|
|
@@ -158,6 +159,56 @@ function isExtensionUiRequest(obj: unknown): obj is ExtensionUiRequestEnvelope {
|
|
|
158
159
|
);
|
|
159
160
|
}
|
|
160
161
|
|
|
162
|
+
/** 必填 string 字段提取:类型不符降级空串(字段容错——仍归类已知 method,不丢 method 信息)。 */
|
|
163
|
+
function reqStr(r: Record<string, unknown>, key: string): string {
|
|
164
|
+
const v = r[key];
|
|
165
|
+
return typeof v === "string" ? v : "";
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** string[] 字段提取:数组剔除非字符串元素;非数组降级 onMissing(options 传 [],
|
|
169
|
+
* widgetLines 传 undefined——两者对缺失值的载荷语义不同:前者恒挂键,后者键挂值 undefined)。 */
|
|
170
|
+
function strArrayField<T extends string[] | undefined>(
|
|
171
|
+
r: Record<string, unknown>,
|
|
172
|
+
key: string,
|
|
173
|
+
onMissing: T,
|
|
174
|
+
): string[] | T {
|
|
175
|
+
const v = r[key];
|
|
176
|
+
return Array.isArray(v)
|
|
177
|
+
? v.filter((x): x is string => typeof x === "string")
|
|
178
|
+
: onMissing;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** timeout 条件展开:非 number 不挂键(timeout?: number 的字段省略语义)。 */
|
|
182
|
+
function optTimeout(r: Record<string, unknown>): { timeout?: number } {
|
|
183
|
+
return typeof r.timeout === "number" ? { timeout: r.timeout } : {};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** placeholder 条件展开:非 string 不挂键。 */
|
|
187
|
+
function optPlaceholder(r: Record<string, unknown>): { placeholder?: string } {
|
|
188
|
+
return typeof r.placeholder === "string" ? { placeholder: r.placeholder } : {};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** prefill 条件展开:非 string 不挂键。 */
|
|
192
|
+
function optPrefill(r: Record<string, unknown>): { prefill?: string } {
|
|
193
|
+
return typeof r.prefill === "string" ? { prefill: r.prefill } : {};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** notifyType 条件展开:仅接受三种已知枚举值,其余不挂键。 */
|
|
197
|
+
function optNotifyType(
|
|
198
|
+
r: Record<string, unknown>
|
|
199
|
+
): { notifyType?: "info" | "warning" | "error" } {
|
|
200
|
+
const v = r.notifyType;
|
|
201
|
+
return v === "info" || v === "warning" || v === "error" ? { notifyType: v } : {};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** widgetPlacement 条件展开:仅接受两种已知枚举值,其余不挂键。 */
|
|
205
|
+
function optWidgetPlacement(
|
|
206
|
+
r: Record<string, unknown>
|
|
207
|
+
): { widgetPlacement?: "aboveEditor" | "belowEditor" } {
|
|
208
|
+
const v = r.widgetPlacement;
|
|
209
|
+
return v === "aboveEditor" || v === "belowEditor" ? { widgetPlacement: v } : {};
|
|
210
|
+
}
|
|
211
|
+
|
|
161
212
|
/**
|
|
162
213
|
* 从已通过 isExtensionUiRequest 守卫的 envelope 构造 ExtensionUiRequest 变体。
|
|
163
214
|
*
|
|
@@ -166,6 +217,7 @@ function isExtensionUiRequest(obj: unknown): obj is ExtensionUiRequestEnvelope {
|
|
|
166
217
|
*
|
|
167
218
|
* 字段类型容错:协议字段类型不符(如 options 非数组)时,该字段降级为空数组/undefined
|
|
168
219
|
*(数组类字段做元素类型过滤,剔除非字符串元素),仍归类为已知 method(不丢 method 信息)。
|
|
220
|
+
* 字段级提取/条件展开由上方字段 helper 承担,本函数只做 method 分发。
|
|
169
221
|
*/
|
|
170
222
|
function buildExtensionUiRequest(env: ExtensionUiRequestEnvelope): ExtensionUiRequest {
|
|
171
223
|
const r: Record<string, unknown> = env;
|
|
@@ -173,69 +225,58 @@ function buildExtensionUiRequest(env: ExtensionUiRequestEnvelope): ExtensionUiRe
|
|
|
173
225
|
case "select":
|
|
174
226
|
return {
|
|
175
227
|
method: "select",
|
|
176
|
-
title:
|
|
177
|
-
options:
|
|
178
|
-
|
|
179
|
-
: [],
|
|
180
|
-
...(typeof r.timeout === "number" ? { timeout: r.timeout } : {}),
|
|
228
|
+
title: reqStr(r, "title"),
|
|
229
|
+
options: strArrayField(r, "options", []),
|
|
230
|
+
...optTimeout(r),
|
|
181
231
|
};
|
|
182
232
|
case "confirm":
|
|
183
233
|
return {
|
|
184
234
|
method: "confirm",
|
|
185
|
-
title:
|
|
186
|
-
message:
|
|
187
|
-
...(
|
|
235
|
+
title: reqStr(r, "title"),
|
|
236
|
+
message: reqStr(r, "message"),
|
|
237
|
+
...optTimeout(r),
|
|
188
238
|
};
|
|
189
239
|
case "input":
|
|
190
240
|
return {
|
|
191
241
|
method: "input",
|
|
192
|
-
title:
|
|
193
|
-
...(
|
|
194
|
-
...(
|
|
242
|
+
title: reqStr(r, "title"),
|
|
243
|
+
...optPlaceholder(r),
|
|
244
|
+
...optTimeout(r),
|
|
195
245
|
};
|
|
196
246
|
case "editor":
|
|
197
247
|
return {
|
|
198
248
|
method: "editor",
|
|
199
|
-
title:
|
|
200
|
-
...(
|
|
249
|
+
title: reqStr(r, "title"),
|
|
250
|
+
...optPrefill(r),
|
|
201
251
|
};
|
|
202
252
|
case "notify":
|
|
203
253
|
return {
|
|
204
254
|
method: "notify",
|
|
205
|
-
message:
|
|
206
|
-
...(r
|
|
207
|
-
? { notifyType: r.notifyType }
|
|
208
|
-
: {}),
|
|
255
|
+
message: reqStr(r, "message"),
|
|
256
|
+
...optNotifyType(r),
|
|
209
257
|
};
|
|
210
258
|
case "setStatus":
|
|
211
259
|
return {
|
|
212
260
|
method: "setStatus",
|
|
213
|
-
statusKey:
|
|
261
|
+
statusKey: reqStr(r, "statusKey"),
|
|
214
262
|
statusText: typeof r.statusText === "string" ? r.statusText : undefined,
|
|
215
263
|
};
|
|
216
|
-
case "setWidget":
|
|
217
|
-
const placement = r.widgetPlacement;
|
|
218
|
-
const widgetLines = Array.isArray(r.widgetLines)
|
|
219
|
-
? r.widgetLines.filter((x): x is string => typeof x === "string")
|
|
220
|
-
: undefined;
|
|
264
|
+
case "setWidget":
|
|
221
265
|
return {
|
|
222
266
|
method: "setWidget",
|
|
223
|
-
widgetKey:
|
|
224
|
-
widgetLines,
|
|
225
|
-
...(
|
|
226
|
-
? { widgetPlacement: placement }
|
|
227
|
-
: {}),
|
|
267
|
+
widgetKey: reqStr(r, "widgetKey"),
|
|
268
|
+
widgetLines: strArrayField(r, "widgetLines", undefined),
|
|
269
|
+
...optWidgetPlacement(r),
|
|
228
270
|
};
|
|
229
|
-
}
|
|
230
271
|
case "setTitle":
|
|
231
272
|
return {
|
|
232
273
|
method: "setTitle",
|
|
233
|
-
title:
|
|
274
|
+
title: reqStr(r, "title"),
|
|
234
275
|
};
|
|
235
276
|
case "set_editor_text":
|
|
236
277
|
return {
|
|
237
278
|
method: "set_editor_text",
|
|
238
|
-
text:
|
|
279
|
+
text: reqStr(r, "text"),
|
|
239
280
|
};
|
|
240
281
|
default:
|
|
241
282
|
// 未知 method:保留全部原始字段,避免协议演进时丢信息
|
|
@@ -273,7 +314,7 @@ export function parseSpawnLine(line: string): ParsedSpawnLine | null {
|
|
|
273
314
|
return {
|
|
274
315
|
kind: "invalid",
|
|
275
316
|
raw: trimmed,
|
|
276
|
-
error:
|
|
317
|
+
error: toErrorMessage(err),
|
|
277
318
|
};
|
|
278
319
|
}
|
|
279
320
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/execution/stdin-writer.ts
|
|
1
|
+
// src/execution/engine/engines/pi/stdin-writer.ts
|
|
2
2
|
//
|
|
3
3
|
// 向 rpc 子进程 stdin 写入命令的 helper 集合。
|
|
4
4
|
//
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
import type { ChildProcess } from "node:child_process";
|
|
11
11
|
import * as crypto from "node:crypto";
|
|
12
12
|
|
|
13
|
-
import { getLogger } from "
|
|
13
|
+
import { getLogger } from "../../../../core/logger.ts";
|
|
14
14
|
|
|
15
|
-
import type { UiResponse } from "
|
|
15
|
+
import type { UiResponse } from "../../../dialog-queue.ts";
|
|
16
|
+
import { toErrorMessage } from "../../../../core/error-message.ts";
|
|
16
17
|
|
|
17
18
|
const logger = getLogger("subagents");
|
|
18
19
|
|
|
@@ -25,7 +26,7 @@ const logger = getLogger("subagents");
|
|
|
25
26
|
* 是 stdin 域中立模块,epipe 计数属 stdin 错误域,职责合理。
|
|
26
27
|
*
|
|
27
28
|
* 错误处理两半面共用本计数器(合并计数,防 spawn→EPIPE→resume 死循环):
|
|
28
|
-
* ① 同步 write 抛错(writeStdinLine throw →
|
|
29
|
+
* ① 同步 write 抛错(writeStdinLine throw → PiEngine.deliverPrompt catch 递增)
|
|
29
30
|
* ② 异步 stream 'error' event(session-runner.ts child.stdin.on('error') 递增)
|
|
30
31
|
*/
|
|
31
32
|
const epipeConsecutiveFailures = new Map<string, number>();
|
|
@@ -79,7 +80,7 @@ export function respond(child: ChildProcess, id: string, out: UiResponse, signal
|
|
|
79
80
|
} catch (err) {
|
|
80
81
|
// [R2] out.value 含循环引用/BigInt 等不可序列化结构——降级 cancelled,避免父进程崩溃。
|
|
81
82
|
logger.warn(`[subagents] JSON.stringify failed for ui response ${id}, degrading to cancelled`, {
|
|
82
|
-
detail:
|
|
83
|
+
detail: toErrorMessage(err),
|
|
83
84
|
});
|
|
84
85
|
line = JSON.stringify({ type: "extension_ui_response", id, cancelled: true });
|
|
85
86
|
}
|
|
@@ -158,7 +159,7 @@ export function sendGetStateCommand(child: ChildProcess): string {
|
|
|
158
159
|
*
|
|
159
160
|
* [R1] write 返回 false 时记 warn(不阻塞,内核缓冲会随后排空)。
|
|
160
161
|
* [R3] write 抛 EPIPE / ERR_STREAM_DESTROYED 时 throw 含 EPIPE 关键词的 Error,
|
|
161
|
-
* 让上层(
|
|
162
|
+
* 让上层(PiEngine.deliverPrompt)能捕获并自动转冷路径 resume。
|
|
162
163
|
* stdin 已关闭/销毁时跳过——respond 已检查 signal,sendPromptCommand 已检查 destroyed。
|
|
163
164
|
*
|
|
164
165
|
* @param child 子进程
|
|
@@ -173,11 +174,11 @@ function writeStdinLine(child: ChildProcess, line: string, warnTag: string): voi
|
|
|
173
174
|
if (!ok) logger.warn(`[subagents] stdin backpressure on ${warnTag}`);
|
|
174
175
|
} catch (err) {
|
|
175
176
|
// [R3] EPIPE / ERR_STREAM_DESTROYED:stdin 管道已断,子进程已退出或 stdin 被销毁。
|
|
176
|
-
// [v4 A-1] 错误处理两半面:① 同步 write 抛错(本 catch
|
|
177
|
+
// [v4 A-1] 错误处理两半面:① 同步 write 抛错(本 catch)——上层(PiEngine.deliverPrompt)捕获后
|
|
177
178
|
// 调 recordEpipeFailure 递增计数;② 异步 stream 'error' event(session-runner.ts 的
|
|
178
179
|
// child.stdin.on('error') listener)。两者共用本模块 export 的 recordEpipeFailure
|
|
179
180
|
// helper 合并计数(防 spawn→EPIPE→resume 死循环)。
|
|
180
|
-
// throw 让上层(
|
|
181
|
+
// throw 让上层(PiEngine.deliverPrompt)捕获并自动转冷路径 resume + 消息重放。
|
|
181
182
|
if (
|
|
182
183
|
err !== null &&
|
|
183
184
|
typeof err === "object" &&
|
|
@@ -192,7 +193,7 @@ function writeStdinLine(child: ChildProcess, line: string, warnTag: string): voi
|
|
|
192
193
|
}
|
|
193
194
|
// 非 EPIPE 错误(不应发生,但兜底降级为 warn 不崩溃)
|
|
194
195
|
logger.warn(`[subagents] unexpected stdin write error on ${warnTag}`, {
|
|
195
|
-
detail:
|
|
196
|
+
detail: toErrorMessage(err),
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
199
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/execution/engine/engines/pi/temp-prompt.ts
|
|
2
2
|
//
|
|
3
3
|
// 将 agent systemPrompt 写入临时文件,供 pi CLI --append-system-prompt 使用。
|
|
4
4
|
// Core 叶子原语(node 内置 + 同目录 bestEffort 清理 helper)。注意 bestEffort
|
|
@@ -14,7 +14,7 @@ import * as fs from "node:fs";
|
|
|
14
14
|
import * as os from "node:os";
|
|
15
15
|
import * as path from "node:path";
|
|
16
16
|
|
|
17
|
-
import { bestEffort } from "
|
|
17
|
+
import { bestEffort } from "../../../best-effort.ts";
|
|
18
18
|
|
|
19
19
|
/** 临时 prompt 文件创建结果。dir 供调用方清理。 */
|
|
20
20
|
export interface TempPromptFile {
|
|
@@ -43,13 +43,29 @@
|
|
|
43
43
|
* sendPushes?: [frame, ...] send 应答前逐帧推送(推送流 + 终态帧全显式
|
|
44
44
|
* 逐字回放,不经 withExtra 改写)
|
|
45
45
|
* sendResult?: object 缺省 {accepted:true}
|
|
46
|
+
* crashAfterSendMs?: number [P0-1 U4] send 应答后 N ms 自杀 exit(1)(连接
|
|
47
|
+
* 崩溃收割注入——onClose → failAllTurns 在途
|
|
48
|
+
* turn 收割;进程死 → 下次 request 惰性重建
|
|
49
|
+
* boot 新代重读 scenario,重试轮/下一任务形态
|
|
50
|
+
* 切换经测试侧 rewriteScenario)
|
|
51
|
+
* rebootSendPushes?: [frame, ...] [P0-1 U4] 非首代进程(本 fake 启动时 state 流水
|
|
52
|
+
* 已有 boot 记录——崩溃/杀链后的重建代)的 send
|
|
53
|
+
* 推送序列,替代 sendPushes:崩溃后惰性重建的
|
|
54
|
+
* 重试轮拿到不同行为(如完整终态流)——首轮挂起
|
|
55
|
+
* + 重试轮成功的静态注入通道(同任务重试轮无法
|
|
56
|
+
* 经测试侧 rewriteScenario 插手,run 整体 await)
|
|
46
57
|
* readError?: {code,message,data} read 应答 error 帧(read 兜底降级链断言)
|
|
47
58
|
* readResult?: object 覆盖 read 应答
|
|
48
|
-
* stopBehavior?: 'terminal'|'none'
|
|
59
|
+
* stopBehavior?: 'terminal'|'none'|'hang'
|
|
60
|
+
* session/stop 的行为(R4 abort 链断言面):
|
|
49
61
|
* 'terminal'(缺省)= stop 时推送该会话的
|
|
50
62
|
* turn.terminal 终态帧(stop 优雅生效——不杀
|
|
51
63
|
* 进程的 abort 路径);'none' = 只应答不推终态
|
|
52
|
-
* (grace 窗口耗尽 → killChain
|
|
64
|
+
* (grace 窗口耗尽 → killChain 兜底路径);
|
|
65
|
+
* 'hang' = 连应答都不给(P0-1 U2 超时入口态③——
|
|
66
|
+
* 控制面假死注入,stop 3s 超时 → 连接级失败判据)
|
|
67
|
+
* stopError?: {code,message,data} stop 应答 error 帧(P0-1 U2 超时入口态②——
|
|
68
|
+
* 协议性 error(如会话已回收)注入,断言不升级杀链)
|
|
53
69
|
* }
|
|
54
70
|
*
|
|
55
71
|
* 多会话支持(R4 引擎接线 / RA3 双会话地基):
|
|
@@ -59,15 +75,6 @@
|
|
|
59
75
|
* (缺省关:R2/R3 单会话用例的字节级行为不变。)
|
|
60
76
|
* session/stop 应答 {stopped:true};按 scenario.stopBehavior 决定是否
|
|
61
77
|
* 推送终态帧(见上)。stopTerminal 推送同样受 STAMP 改写。
|
|
62
|
-
*
|
|
63
|
-
* 探针连接支持(R5 降级链——D8 冒烟探针 / D2 门控断言面):
|
|
64
|
-
* ZCODE_APPSERVER_PROBE_CONN=1 本进程是探针连接(引擎 runAppServerSmokeProbe 叠加
|
|
65
|
-
* 的 env 标记):scenario 只读 FAKE_PROBE_SCENARIO(常驻
|
|
66
|
-
* 主连接的 FAKE_SESSION_SCENARIO 不作用于探针——故障注入可
|
|
67
|
-
* 只命中主连接或只命中探针);env 快照记 probe 标志。
|
|
68
|
-
* FAKE_PROBE_SCENARIO=<path> 仅探针进程消费的 JSON:
|
|
69
|
-
* { createError?: {code,message,data} } 探针 create 应答 error 帧(探针失败注入)
|
|
70
|
-
* { hangCreate?: true } create 永不应答(预算超时注入)
|
|
71
78
|
*/
|
|
72
79
|
import fs from 'node:fs';
|
|
73
80
|
import readline from 'node:readline';
|
|
@@ -77,25 +84,28 @@ const EXTRA_KEYS = process.env.FAKE_EXTRA_KEYS === '1';
|
|
|
77
84
|
const PROTOCOL_AS_PUSH = process.env.FAKE_PROTOCOL_PUSH === '1';
|
|
78
85
|
// [R4] 多会话推送改写开关(见文件头注释)
|
|
79
86
|
const STAMP_SESSION = process.env.FAKE_STAMP_SESSION === '1';
|
|
80
|
-
// [R5] 探针连接判定(引擎探针在 env 叠 ZCODE_APPSERVER_PROBE_CONN=1——见 appserver-probe.ts)
|
|
81
|
-
const IS_PROBE = process.env.ZCODE_APPSERVER_PROBE_CONN === '1';
|
|
82
87
|
|
|
83
|
-
// 会话场景(R3
|
|
84
|
-
// 只读 FAKE_PROBE_SCENARIO(与主连接的故障注入互不串扰)
|
|
88
|
+
// 会话场景(R3):启动时读取一次(env 固化语义与其他 FAKE_ 开关一致)
|
|
85
89
|
let SCENARIO = null;
|
|
86
|
-
if (process.env.FAKE_SESSION_SCENARIO
|
|
90
|
+
if (process.env.FAKE_SESSION_SCENARIO) {
|
|
87
91
|
try {
|
|
88
92
|
SCENARIO = JSON.parse(fs.readFileSync(process.env.FAKE_SESSION_SCENARIO, 'utf8'));
|
|
89
93
|
} catch (err) {
|
|
90
94
|
log('scenario-load-failed', { message: String(err && err.message) });
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
|
-
|
|
97
|
+
|
|
98
|
+
// [P0-1 U4] 本进程代数(state 流水已有 boot 记录数 + 1):崩溃/杀链后的惰性重建代
|
|
99
|
+
// ≥2——rebootSendPushes 仅对重建代生效(重试轮拿到与首轮不同的推送序列)
|
|
100
|
+
let BOOT_GEN = 1;
|
|
101
|
+
if (STATE_FILE && SCENARIO && SCENARIO.rebootSendPushes) {
|
|
94
102
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
103
|
+
const priorBoots = fs
|
|
104
|
+
.readFileSync(STATE_FILE, 'utf8')
|
|
105
|
+
.split('\n')
|
|
106
|
+
.filter((l) => l.includes('"ev":"boot"')).length;
|
|
107
|
+
BOOT_GEN = priorBoots + 1;
|
|
108
|
+
} catch { /* 流水读失败按首代处理 */ }
|
|
99
109
|
}
|
|
100
110
|
|
|
101
111
|
let seq = 0;
|
|
@@ -130,7 +140,6 @@ log('env', {
|
|
|
130
140
|
telemetry: process.env.ZCODE_MODEL_TELEMETRY_ENABLED,
|
|
131
141
|
nested: process.env.ZSW_NESTED,
|
|
132
142
|
unifiedNested: process.env.XYZ_AGENT_SUBAGENT,
|
|
133
|
-
probe: process.env.ZCODE_APPSERVER_PROBE_CONN,
|
|
134
143
|
});
|
|
135
144
|
log('boot', { pid: process.pid, argv: process.argv.slice(2) });
|
|
136
145
|
if (process.env.FAKE_STDERR === '1') {
|
|
@@ -212,8 +221,6 @@ async function handleRequest(f) {
|
|
|
212
221
|
process.exit(1);
|
|
213
222
|
return; // 不可达(exit 先行),保持 switch 完整
|
|
214
223
|
case 'session/create': {
|
|
215
|
-
// [R5] 探针预算超时注入:hangCreate 时永不应答(探针 deadline 收割判据)
|
|
216
|
-
if (SCENARIO && SCENARIO.hangCreate) return;
|
|
217
224
|
if (SCENARIO && SCENARIO.createError) {
|
|
218
225
|
return replyErr(id, SCENARIO.createError.code, SCENARIO.createError.message, SCENARIO.createError.data);
|
|
219
226
|
}
|
|
@@ -228,13 +235,33 @@ async function handleRequest(f) {
|
|
|
228
235
|
if (SCENARIO && SCENARIO.sendError) {
|
|
229
236
|
return replyErr(id, SCENARIO.sendError.code, SCENARIO.sendError.message, SCENARIO.sendError.data);
|
|
230
237
|
}
|
|
231
|
-
// 推送帧逐字回放(STAMP_SESSION
|
|
232
|
-
|
|
238
|
+
// 推送帧逐字回放(STAMP_SESSION 时按目标会话归因改写);重建代走 rebootSendPushes
|
|
239
|
+
// (U4:重试轮的不同行为通道)
|
|
240
|
+
const pushes =
|
|
241
|
+
BOOT_GEN > 1 && SCENARIO && SCENARIO.rebootSendPushes
|
|
242
|
+
? SCENARIO.rebootSendPushes
|
|
243
|
+
: SCENARIO && SCENARIO.sendPushes;
|
|
244
|
+
pushFrames(pushes, String(params.sessionId || ''));
|
|
245
|
+
// [P0-1 U4] 崩溃收割注入:应答后 N ms 自杀(onClose → failAllTurns 在途 turn
|
|
246
|
+
// 收割的确定性触发面;exit(1) 非零码与 test/suicide 同形态)
|
|
247
|
+
const crashAfterSendMs = SCENARIO && SCENARIO.crashAfterSendMs;
|
|
248
|
+
if (typeof crashAfterSendMs === 'number' && crashAfterSendMs >= 0) {
|
|
249
|
+
setTimeout(() => {
|
|
250
|
+
log('crash-injected', { afterMs: crashAfterSendMs });
|
|
251
|
+
process.exit(1);
|
|
252
|
+
}, crashAfterSendMs).unref();
|
|
253
|
+
}
|
|
233
254
|
return reply(id, (SCENARIO && SCENARIO.sendResult) || { accepted: true });
|
|
234
255
|
}
|
|
235
256
|
case 'session/stop': {
|
|
236
|
-
// [R4] abort 链断言面:缺省推终态(stop 优雅生效);stopBehavior:'none'
|
|
257
|
+
// [R4] abort 链断言面:缺省推终态(stop 优雅生效);stopBehavior:'none' 只应答;
|
|
258
|
+
// stopError 注入协议性 error 应答帧(P0-1 U2 态②——不升级杀链判据);
|
|
259
|
+
// stopBehavior:'hang' 永不应答(态③——stop 3s 超时 = 连接级失败判据)
|
|
237
260
|
const behavior = (SCENARIO && SCENARIO.stopBehavior) || 'terminal';
|
|
261
|
+
if (behavior === 'hang') return;
|
|
262
|
+
if (SCENARIO && SCENARIO.stopError) {
|
|
263
|
+
return replyErr(id, SCENARIO.stopError.code, SCENARIO.stopError.message, SCENARIO.stopError.data);
|
|
264
|
+
}
|
|
238
265
|
if (behavior === 'terminal') {
|
|
239
266
|
pushFrames([TURN_TERMINAL_FRAME], String(params.sessionId || ''));
|
|
240
267
|
}
|