@sema-agent/server 7.43.0 → 7.44.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/USAGE.md +18 -0
- package/dist/adoption/plan.js +31 -192
- package/dist/adoption/quiesce.js +3 -86
- package/dist/adoption/runner.js +3 -140
- package/dist/adoption/sql.js +0 -74
- package/dist/adoption/wire.js +0 -80
- package/dist/approval-ask-machine.js +0 -75
- package/dist/approval-card.js +0 -323
- package/dist/approval-deny-reasons.js +0 -42
- package/dist/approval-hmac.js +0 -35
- package/dist/approval-reconciler.js +8 -166
- package/dist/approval.js +4 -67
- package/dist/audit.js +1 -44
- package/dist/auth-bridge.js +4 -47
- package/dist/auth-keys.js +0 -23
- package/dist/bake-runner/main.js +4 -65
- package/dist/bake-runner/protocol.js +3 -58
- package/dist/bake-runner/runner.js +5 -91
- package/dist/bench/l8/artifact.js +2 -61
- package/dist/bench/l8/escape.js +0 -25
- package/dist/bench/l8/index.js +0 -14
- package/dist/bench/l8/probes.js +0 -60
- package/dist/bench/l8/run-probes.js +2 -45
- package/dist/bench/s1/arms.js +14 -189
- package/dist/bench/s1/live-deps.js +11 -253
- package/dist/bench/s1/oracle.js +1 -36
- package/dist/bench/s1/repair-oracle-adapter.js +0 -30
- package/dist/bench/s1/reviewer.js +0 -34
- package/dist/bench/s1/row.js +0 -62
- package/dist/bench/s1/run-firm.js +4 -70
- package/dist/bench/s1/runner-ctx.js +0 -40
- package/dist/bench/s1/tasks.js +0 -115
- package/dist/boot/adoption.js +0 -20
- package/dist/boot/budget-tracing.js +3 -55
- package/dist/boot/config-center.js +43 -551
- package/dist/boot/coordinators.js +1 -69
- package/dist/boot/crash-last.js +0 -18
- package/dist/boot/deferred-sandbox-path-env.js +3 -119
- package/dist/boot/execution-env.js +5 -171
- package/dist/boot/governance-seams.js +0 -92
- package/dist/boot/leader.js +0 -69
- package/dist/boot/limit-sync.js +0 -2
- package/dist/boot/memory-boundary.js +3 -91
- package/dist/boot/org-memory.js +1 -25
- package/dist/boot/parked-revive-gate.js +0 -150
- package/dist/boot/permission-rules-audit.js +1 -56
- package/dist/boot/reapers.js +15 -273
- package/dist/boot/resolve-spec.js +9 -768
- package/dist/boot/retention-lane.js +4 -87
- package/dist/boot/runner-deps.js +3 -297
- package/dist/boot/runtime-caps.js +0 -40
- package/dist/boot/session-faces.js +2 -133
- package/dist/boot/shutdown.js +9 -83
- package/dist/boot/side-query-lane.js +2 -137
- package/dist/boot/stores.js +15 -215
- package/dist/boot/task-list-lane.js +0 -18
- package/dist/boot/webfetch-summarize-lane.js +0 -47
- package/dist/boot/workflow-orchestration.js +3 -99
- package/dist/boot-reclaim.js +0 -20
- package/dist/bounded-session-map.js +0 -19
- package/dist/brain.js +2 -139
- package/dist/budget.js +9 -244
- package/dist/capabilities/builtin-tools.js +0 -3
- package/dist/capabilities/center-plugins.js +6 -51
- package/dist/capabilities/center-prompts.js +6 -71
- package/dist/capabilities/code-review-council.js +7 -40
- package/dist/capabilities/collab-workflows.js +1 -44
- package/dist/capabilities/hands-lane.js +0 -65
- package/dist/capabilities/memory-notice.js +0 -70
- package/dist/capabilities/prompt.js +0 -14
- package/dist/capabilities/prompts/code-review.js +0 -14
- package/dist/capabilities/prompts/identity.js +0 -6
- package/dist/capabilities/prompts/team.js +0 -4
- package/dist/capabilities/repo-tools.js +0 -34
- package/dist/capabilities/sandbox-file-send.js +3 -92
- package/dist/capabilities/scenarios.d.ts +0 -1
- package/dist/capabilities/scenarios.js +18 -279
- package/dist/capabilities/select-environment-tool.js +0 -32
- package/dist/capabilities/send-user-file-tool.js +2 -66
- package/dist/capabilities/skills.d.ts +1 -2
- package/dist/capabilities/skills.js +3 -21
- package/dist/capabilities/team.d.ts +3 -11
- package/dist/capabilities/team.js +3 -51
- package/dist/capabilities/tool-defer.js +0 -3
- package/dist/config-center/apply-effective.js +15 -330
- package/dist/config-center/apply-ledger.js +5 -38
- package/dist/config-center/facade.js +0 -41
- package/dist/config-center/hot-keys-registry.js +0 -20
- package/dist/config-center/http-client.js +2 -125
- package/dist/config-center/mcp-revocation.js +2 -34
- package/dist/config-center/read-face.js +0 -59
- package/dist/config-center/restart-signal.js +1 -85
- package/dist/config-center/skills-mcp.d.ts +1 -1
- package/dist/config-center/skills-mcp.js +9 -76
- package/dist/config-center/stage-limits.js +8 -35
- package/dist/config-invariants.js +0 -16
- package/dist/config-lkg.js +0 -42
- package/dist/config-provider.js +3 -186
- package/dist/config-types.js +0 -5
- package/dist/config.js +107 -1145
- package/dist/degenerate-instrument.js +3 -67
- package/dist/deployment-governance.js +0 -124
- package/dist/digest-form.js +0 -12
- package/dist/elicitation.js +3 -86
- package/dist/env-facts.js +7 -75
- package/dist/fleet/fleet-bus.js +34 -507
- package/dist/fleet/fleet-reconciler.js +9 -149
- package/dist/fleet/fleet-terminal-window.js +10 -178
- package/dist/fleet/subagent-tail-bus.js +3 -72
- package/dist/fleet-client.js +10 -70
- package/dist/fleet-lease.js +5 -79
- package/dist/git-api-kind.js +0 -3
- package/dist/governance-ask-marks.js +2 -78
- package/dist/hooks/branch-transcript.js +0 -74
- package/dist/hooks/cc-agent-hook-prompt.js +0 -29
- package/dist/hooks/cc-stop-prompt.js +1 -46
- package/dist/hooks/hook-llm.js +1 -53
- package/dist/hooks/hook-runner.js +20 -414
- package/dist/http/active-run-conflict.js +4 -129
- package/dist/http/cursor-fingerprint.d.ts +5 -0
- package/dist/http/cursor-fingerprint.js +5 -0
- package/dist/http/idempotency.js +0 -37
- package/dist/http/principal-gate.js +3 -40
- package/dist/http/route-ctx.js +0 -9
- package/dist/http/routes/a2a-serve.js +7 -319
- package/dist/http/routes/admin-config-refresh.js +0 -4
- package/dist/http/routes/admin-drain.js +0 -10
- package/dist/http/routes/adoption.js +1 -29
- package/dist/http/routes/agents-roster.js +1 -47
- package/dist/http/routes/approvals-assistant.js +32 -395
- package/dist/http/routes/attachments.js +4 -22
- package/dist/http/routes/capabilities.js +3 -420
- package/dist/http/routes/diagnostics.js +1 -81
- package/dist/http/routes/fleet.js +9 -185
- package/dist/http/routes/images.js +14 -239
- package/dist/http/routes/leader.js +0 -13
- package/dist/http/routes/memory-bundle.js +1 -61
- package/dist/http/routes/memory-policy.js +9 -99
- package/dist/http/routes/notify-wake.js +3 -37
- package/dist/http/routes/observability.js +2 -19
- package/dist/http/routes/retention-ops.js +2 -34
- package/dist/http/routes/rules.js +1 -93
- package/dist/http/routes/runs.js +64 -873
- package/dist/http/routes/session-sync.js +19 -258
- package/dist/http/routes/sessions-list.js +17 -43
- package/dist/http/routes/sessions.js +34 -226
- package/dist/http/routes/shared-memory.js +5 -36
- package/dist/http/routes/side-query.js +1 -87
- package/dist/http/routes/tasks.js +52 -722
- package/dist/http/routes/trace-usage.js +32 -195
- package/dist/http/routes/workflows.js +19 -195
- package/dist/http/run-meta.js +0 -6
- package/dist/http/send.js +0 -32
- package/dist/http/server.js +92 -1597
- package/dist/http/sse-lifecycle.js +2 -13
- package/dist/http/sse-log.js +3 -48
- package/dist/http/tar.js +5 -21
- package/dist/http/verify-rounds.js +0 -5
- package/dist/http/wire-gate.js +0 -9
- package/dist/http/workspace-content.js +0 -10
- package/dist/images/bake-validate.js +1 -70
- package/dist/images/manifest.js +1 -6
- package/dist/index.js +0 -21
- package/dist/key-resolver.js +2 -17
- package/dist/leader/diffout.js +1 -20
- package/dist/leader/diffup.js +0 -47
- package/dist/leader/endpoint.js +2 -57
- package/dist/leader/fanout.js +3 -45
- package/dist/leader/grader-env-factory.js +3 -72
- package/dist/leader/leader.js +5 -156
- package/dist/leader/merge.js +8 -115
- package/dist/leader/planner.js +3 -54
- package/dist/leader/repair-oracle.js +1 -60
- package/dist/leader/repair-wire.js +2 -79
- package/dist/leader/wire.js +8 -307
- package/dist/lsp/e2b-bridge.js +4 -64
- package/dist/lsp/e2b-manager.js +6 -94
- package/dist/lsp/lsp-frames.js +0 -12
- package/dist/lsp/manager.js +4 -96
- package/dist/lsp/ws-transport.js +5 -55
- package/dist/lsp-evict.js +1 -15
- package/dist/main.js +57 -765
- package/dist/memory-bundle-engine.js +0 -55
- package/dist/memory-export.js +0 -4
- package/dist/memory-posture.js +1 -15
- package/dist/memory-scope.js +11 -148
- package/dist/memory-sync-client.js +2 -44
- package/dist/memory-sync.js +1 -80
- package/dist/model-select.js +3 -80
- package/dist/observability/cost-quota.js +1 -17
- package/dist/observability/cost-taxonomy.js +0 -34
- package/dist/observability/fail-open.js +7 -86
- package/dist/observability/logger.js +0 -6
- package/dist/observability/metrics.js +0 -94
- package/dist/observability/otel-exporter.js +3 -13
- package/dist/observability/principal-context.js +0 -9
- package/dist/observability/prompt-manifest.js +1 -37
- package/dist/observability/rate-limit.js +0 -4
- package/dist/observability/secret-env-scrub.js +2 -56
- package/dist/observability/tool-trace.js +1 -70
- package/dist/orchestration/hardened-vm-runner.js +4 -118
- package/dist/orchestration/hardened-vm-worker-runner.js +1 -26
- package/dist/orchestration/hardened-vm-worker.js +0 -27
- package/dist/orchestration/subagent-steer.js +1 -45
- package/dist/orchestration/workflow-agent-steer.js +1 -80
- package/dist/orchestration/workflow-completion-inbox.js +32 -285
- package/dist/orchestration/workflow-notify-journal.js +16 -259
- package/dist/org-memory-admission.js +3 -47
- package/dist/parent-watch.js +2 -48
- package/dist/parked-decide.js +1 -109
- package/dist/per-task-image.js +0 -57
- package/dist/plan-cache-probe.js +3 -27
- package/dist/plugins/adoption-log-sql.js +2 -119
- package/dist/plugins/approval-ask-store-memory.js +3 -38
- package/dist/plugins/approval-ask-store-sql.js +6 -188
- package/dist/plugins/approval-exemption-store.js +2 -28
- package/dist/plugins/background-agent-store-sql.js +4 -105
- package/dist/plugins/background-shell-support.js +14 -122
- package/dist/plugins/blob-backend.js +6 -169
- package/dist/plugins/breaker-state-sql.js +8 -46
- package/dist/plugins/caching-session-store.js +4 -106
- package/dist/plugins/checkpoint-store-sql.js +18 -505
- package/dist/plugins/e2b-orphan-reclaim.js +0 -45
- package/dist/plugins/file-outcome-sink.js +0 -9
- package/dist/plugins/file-resume-anchor-store.js +4 -43
- package/dist/plugins/file-run-store.js +26 -364
- package/dist/plugins/file-snapshot-store-sql.js +10 -181
- package/dist/plugins/fork-routing-session-store.js +8 -111
- package/dist/plugins/host-platform.js +2 -91
- package/dist/plugins/image-bake-store-sql.js +7 -250
- package/dist/plugins/image-index-sql.js +4 -123
- package/dist/plugins/k8s-bg-scripts.js +4 -88
- package/dist/plugins/k8s-exec-protocol.js +0 -41
- package/dist/plugins/leader-run-store-sql.js +0 -101
- package/dist/plugins/local-checkpoint-store.js +8 -128
- package/dist/plugins/local-session-store.js +34 -296
- package/dist/plugins/local-task-attachment-store.js +2 -16
- package/dist/plugins/mailbox-store-sql.js +8 -65
- package/dist/plugins/memory-embedder-fingerprint.js +5 -166
- package/dist/plugins/memory-embedder.js +4 -70
- package/dist/plugins/memory-engine-pg.js +6 -170
- package/dist/plugins/memory-engine-tidb.js +7 -155
- package/dist/plugins/memory-engine-vector-util.js +0 -10
- package/dist/plugins/memory-key-guards.js +0 -34
- package/dist/plugins/memory-origin-law.js +0 -187
- package/dist/plugins/memory-resume-anchor-store.js +0 -17
- package/dist/plugins/memory-run-store.js +12 -89
- package/dist/plugins/memory-session-policy-store.js +0 -17
- package/dist/plugins/memory-sync-store-pg.js +4 -49
- package/dist/plugins/memory-sync-store-tidb.js +3 -35
- package/dist/plugins/outcome-ledger-sql.js +3 -97
- package/dist/plugins/permission-rule-store-file.js +5 -133
- package/dist/plugins/permission-rule-store-sql.d.ts +3 -0
- package/dist/plugins/permission-rule-store-sql.js +50 -307
- package/dist/plugins/pg-cost-quota.js +0 -7
- package/dist/plugins/pg-pool.js +0 -92
- package/dist/plugins/pg-rate-limiter.js +2 -13
- package/dist/plugins/pg-safe-json.js +4 -40
- package/dist/plugins/pg-session-storage.js +25 -189
- package/dist/plugins/posix-shell-fs.js +1 -31
- package/dist/plugins/remote-env-adb.js +12 -101
- package/dist/plugins/remote-env-e2b.js +40 -371
- package/dist/plugins/remote-env-file-error.js +0 -37
- package/dist/plugins/remote-env-host.js +63 -483
- package/dist/plugins/remote-env-k8s.js +32 -326
- package/dist/plugins/remote-env-local-docker.js +24 -157
- package/dist/plugins/remote-env-ssh.js +20 -128
- package/dist/plugins/remote-scratchpad.js +2 -32
- package/dist/plugins/remote-shell.js +1 -32
- package/dist/plugins/resume-anchor-store-sql.js +0 -11
- package/dist/plugins/retention-lane-store-sql.js +0 -108
- package/dist/plugins/retention-store-sql.js +4 -383
- package/dist/plugins/roster-store-sql.js +0 -55
- package/dist/plugins/run-store-sql.js +14 -251
- package/dist/plugins/s3-presign.js +2 -49
- package/dist/plugins/scheduler-support.js +3 -80
- package/dist/plugins/send-file-ledger.js +4 -53
- package/dist/plugins/send-user-file.js +4 -94
- package/dist/plugins/session-placement.js +1 -89
- package/dist/plugins/session-policy-store-sql.js +3 -81
- package/dist/plugins/session-store.js +0 -57
- package/dist/plugins/shared-memory-store-sql.js +4 -167
- package/dist/plugins/sql-driver.js +0 -17
- package/dist/plugins/sql-errors.js +0 -7
- package/dist/plugins/sql-escape.js +0 -8
- package/dist/plugins/sql-row-helpers.js +0 -25
- package/dist/plugins/store-backend.js +42 -222
- package/dist/plugins/store-contracts.js +2 -46
- package/dist/plugins/task-attachment-store.js +3 -49
- package/dist/plugins/task-list-store-sql.js +0 -79
- package/dist/plugins/tidb-cost-quota.js +1 -4
- package/dist/plugins/tidb-pool.js +1 -207
- package/dist/plugins/tidb-rate-limiter.js +3 -9
- package/dist/plugins/tidb-session-storage.js +4 -70
- package/dist/plugins/tidb-session-store.js +19 -341
- package/dist/plugins/tool-result-store-sql.js +4 -179
- package/dist/plugins/usage-window-store-sql.js +0 -8
- package/dist/plugins/web-search.js +10 -132
- package/dist/plugins/workflow-journal-store-sql.js +2 -58
- package/dist/plugins/workflow-run-store-sql.js +6 -91
- package/dist/plugins/worktree-isolation.js +6 -126
- package/dist/plugins/write-behind-counter.js +16 -75
- package/dist/principal-jwt.js +5 -60
- package/dist/project-memory.js +15 -146
- package/dist/prompts-domain-validate.js +1 -51
- package/dist/question.js +2 -111
- package/dist/resource-suspend.js +0 -18
- package/dist/router/route-orchestration.js +0 -77
- package/dist/rules-consent.d.ts +44 -5
- package/dist/rules-consent.js +75 -215
- package/dist/run-local.js +14 -381
- package/dist/runs.js +29 -617
- package/dist/runtime-caps-resolver.js +6 -132
- package/dist/runtime-governance.js +1 -232
- package/dist/sandbox-pkg-source.js +0 -37
- package/dist/sealed-key.js +3 -68
- package/dist/security.js +6 -291
- package/dist/session-leaf-bus.js +0 -32
- package/dist/session-sync-content.js +1 -69
- package/dist/session-sync-kernel.js +3 -60
- package/dist/session-sync.js +3 -66
- package/dist/session-titler.js +7 -41
- package/dist/session-watch.js +9 -73
- package/dist/shared-memory-scope-authorizer.js +0 -18
- package/dist/sighup-idle.js +1 -12
- package/dist/spec-fields.js +4 -143
- package/dist/store-live-probe.js +3 -49
- package/dist/task-a2a.js +1 -126
- package/dist/task-cwd.js +1 -103
- package/dist/task-mcp.js +1 -89
- package/dist/task-settings.js +10 -300
- package/dist/task-workflow.js +8 -75
- package/dist/tool-approval.d.ts +28 -1
- package/dist/tool-approval.js +70 -1430
- package/dist/trace/artifacts.js +5 -20
- package/dist/trace/engine-notice-wire.js +6 -138
- package/dist/trace/ledger-sink.js +7 -96
- package/dist/trace/project.js +4 -448
- package/dist/trace/redact.js +9 -77
- package/dist/turn-activity.js +1 -27
- package/dist/usage-analytics.js +4 -34
- package/dist/wall-clock-jump-guard.js +1 -68
- package/package.json +3 -3
- package/dist/capabilities/scenario-alias.d.ts +0 -27
- package/dist/capabilities/scenario-alias.js +0 -61
package/dist/task-cwd.js
CHANGED
|
@@ -1,29 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TOC cwd seam — project the TOC client's launch directory (`TaskRequest.cwd`, SDK 0.0.36) onto the agent's
|
|
3
|
-
* HOST execution-env workspace, so `sema` run from a project dir operates on THAT project (CC-parity), instead of
|
|
4
|
-
* the persistent local engine's (default port 47362) fixed/ephemeral workspace (TOC adversarial review CRITICAL: the HTTP path conveyed NO
|
|
5
|
-
* project context — the agent always landed in an empty temp dir).
|
|
6
|
-
*
|
|
7
|
-
* 🔒 SECURITY (workflow): `cwd` is a HOST PATH supplied by the caller. Honoring it is a sandbox/
|
|
8
|
-
* filesystem-root choice, so it is gated HARD:
|
|
9
|
-
* - ONLY the `host` execution lane (run-on-this-machine, no container) reads it — every OTHER lane (k8s / e2b /
|
|
10
|
-
* ssh / adb / local-docker) has its own factory that NEVER consults the cwd registry, so cwd is ignored there
|
|
11
|
-
* by construction (a tenant can't point a shared/cloud worker at an arbitrary host path).
|
|
12
|
-
* - AND only a SINGLE-USER deployment (`requirePrincipal === false`) — a multi-tenant host lane must NOT let one
|
|
13
|
-
* caller's cwd steer the agent into another tenant's / the operator's files (cross-tenant host-path access).
|
|
14
|
-
* Same trust boundary as the deferred per-task `env` (TaskSpec deliberately has no per-task env for untrusted
|
|
15
|
-
* callers). When the gate is closed, a sent `cwd` is IGNORED (not honored) — advertised via capabilities so the
|
|
16
|
-
* shell never pretends it took effect.
|
|
17
|
-
*/
|
|
18
1
|
import path from "node:path";
|
|
19
|
-
/** Cap on a cwd path length (defensive — a row/path label bound; a real path is far shorter). */
|
|
20
2
|
export const MAX_CWD_CHARS = 4_096;
|
|
21
|
-
/** Is this a structurally-valid absolute host path? Rejects: non-strings, relative paths (TOC review #12 — a
|
|
22
|
-
* relative cwd would resolve against the SERVICE process cwd, not the user's project = silent wrong-dir), empty,
|
|
23
|
-
* over-long, and NUL-byte injection. NOT an existence check (the env surfaces a missing dir at first tool use).
|
|
24
|
-
* Defense-in-depth (double-review LOW): `path.isAbsolute` is SYNTACTIC — `/a/../../etc` is "absolute" yet contains
|
|
25
|
-
* `..` traversal that the host env would `path.resolve` away. Single-user host lane = the caller's own machine (no
|
|
26
|
-
* cross-tenant escape), but we reject any path with a `..` segment so the honored cwd is the literal path sent. */
|
|
27
3
|
export function isValidCwd(cwd) {
|
|
28
4
|
return (typeof cwd === "string" &&
|
|
29
5
|
cwd.length > 0 &&
|
|
@@ -32,67 +8,16 @@ export function isValidCwd(cwd) {
|
|
|
32
8
|
path.isAbsolute(cwd) &&
|
|
33
9
|
!cwd.split(/[/\\]/).includes(".."));
|
|
34
10
|
}
|
|
35
|
-
/**
|
|
36
|
-
* The deployment-level gate: does THIS deployment honor a caller-supplied `cwd`? TRUE only for the single-user
|
|
37
|
-
* `host` lane (see module header). All cloud/container lanes + any multi-tenant deployment → FALSE (cwd ignored).
|
|
38
|
-
*/
|
|
39
11
|
export function cwdHonored(config) {
|
|
40
12
|
return config.remoteExec?.provider === "host" && config.requirePrincipal !== true;
|
|
41
13
|
}
|
|
42
|
-
/**
|
|
43
|
-
* [851]P3a — the OTHER host-semantics lane: provider UNSET = the in-process single-user lane. It has NO shell
|
|
44
|
-
* hands (core prepare-task: no factory/executionEnv ⇒ StubExecutionEnv), so the perSession cwd/env registries
|
|
45
|
-
* have no consumer there — but PROCESS-level consumers (hooks commands, the C4 projectContext local read) still
|
|
46
|
-
* see the engine's own `process.cwd()`/`process.env`. When the shell spawned the engine in the caller's own
|
|
47
|
-
* dir/env, a caller override is often ALREADY satisfied by that process state, and a per-task "ignored" warn
|
|
48
|
-
* contradicts it (飞轮双平台观测). Signal-truth split: satisfied ⇒ debug, real mismatch ⇒ warn. True per-session
|
|
49
|
-
* honoring remains `REMOTE_EXEC=host`. Multi-tenant excluded for the same reason as {@link cwdHonored}.
|
|
50
|
-
*/
|
|
51
14
|
export function inProcessSingleUserLane(config) {
|
|
52
15
|
return config.remoteExec === undefined && config.requirePrincipal !== true;
|
|
53
16
|
}
|
|
54
|
-
/**
|
|
55
|
-
* #295(F-1,[4512] 修向 (b')):卡批「不再询问」落盘规则的 **project root** —— 「这次授权是在哪个
|
|
56
|
-
* 工作目录里点的」。取值与既有 cwd 语义同源,不新造坐标系:
|
|
57
|
-
* 1. session 显式注册的 cwd(cwd seam,host lane;与 {@link effectiveHostWorkspace} 第 1 优先级同源)
|
|
58
|
-
* —— **今天唯一真的会命中的那一臂**;⚠️ 它**不含 lane 判据**,lane 语义完全依赖「`perSessionCwd`
|
|
59
|
-
* 只在 `cwdHonored` 为真时被写」这条跨文件外部不变量(写侧唯一入口 boot/resolve-spec.ts)。这是
|
|
60
|
-
* 刻意的单写者惯用法,不是疏漏:在消费端补第二道闸 = 把一条不变量拆给两个属主(同族消费者
|
|
61
|
-
* {@link effectiveHostWorkspace} 形状完全相同)。机器背书 = test/task-cwd.test.ts 的 A-054.2 两格。
|
|
62
|
-
* 2. 🔴 **前瞻/防御臂,本仓当前装配下零命中**(A-054.21,2026-08-19 合并重扫 partial,存活断言):
|
|
63
|
-
* in-process 单用户 lane({@link inProcessSingleUserLane})取引擎自身 `process.cwd()`。它读起来像在
|
|
64
|
-
* 服务一个真部署形,其实到不了 —— 该 lane 的 `remoteExec` 未设 ⇒ boot/execution-env.ts 六条工厂臂全
|
|
65
|
-
* 不命中 ⇒ core 落 `StubExecutionEnv` ⇒ `handsEnabled=false` ⇒ 不挂 Bash ⇒ 未知工具在 agent-loop 走
|
|
66
|
-
* `tool.not_found`(**不进审批座**)⇒ 无 `ruleSuggestions` ⇒ 本函数在规则车道上根本不被调用;同 lane
|
|
67
|
-
* 第 1 臂也因写侧闸只在 `cwdHonored` 下开而恒空。危害口径按 refuter **降级**:死枝 ≡ 落第 3 臂
|
|
68
|
-
* `undefined` ≡ core global 缺省 ≡ #295 修前行为,**今天零用户可见伤害**,不是「恒不命中」类缺陷。
|
|
69
|
-
* 🚧 **给将来接手的人的红线**:这条 lane 若哪天真接上 hands,root 必须取 `executionEnv.cwd`(core 的
|
|
70
|
-
* `taskRootFinal` 就是它),**不是** `process.cwd()` —— 两者在静态 env 装配形下可以完全不同,照现注
|
|
71
|
-
* 直接接线会铸出一个真的歪 root。真正的本地开箱形(`CONFIG_PROVIDER=local`)被 config 默认成
|
|
72
|
-
* **host** lane,受益的是第 1 臂;本臂不是「#295 的本地形受益臂」。
|
|
73
|
-
* 3. 其余(远程沙箱 / REMOTE_EXEC=host 未注册 / 多租户)⇒ `undefined`:root 在 server 坐标系里
|
|
74
|
-
* 不可知,调用方**不铸 scope**,落 core 的 global 缺省(= #295 修前行为,恒不更宽;也绝不铸一个
|
|
75
|
-
* 与规则判定时 cwd 不同坐标系的 root —— 那会静默把「不再询问」变成恒不命中)。
|
|
76
|
-
*
|
|
77
|
-
* 🔴 出口 = `path.resolve(原字节)`,**禁 realpath**(A-054.F-A,2026-08-19 合并重扫 confirmed high):
|
|
78
|
-
* core 判定这条规则时喂进 `scopeCoversCwd` 的 cwd = `executionEnv.cwd` = host env 构造里的
|
|
79
|
-
* `path.resolve(同一条注册原字节)`(remote-env-host.ts),比较是**纯串**(`pathWithinRoot`,零
|
|
80
|
-
* realpath)。初版这里走 realpath(据 core `PersistedAllowRule.scope` JSDoc「root 由构造方
|
|
81
|
-
* canonicalize」)——但 JSDoc 说的是义务、实现行才是事实([3578] 宪法):core 自己喂进匹配的 cwd
|
|
82
|
-
* 恰恰**未** canonicalize,单侧规范化=两坐标系分叉,注册 cwd 含符号链接段时(macOS `/tmp`、
|
|
83
|
-
* `~/work→/mnt/...`)落盘规则**永不命中**,「不再询问」恒失效。正解=root 与判定坐标出自**同一条
|
|
84
|
-
* 串、同一种规范化**;将来 core 若把判定面改 canonicalize,这里必须同批跟(端到端钉在
|
|
85
|
-
* test/task-cwd.test.ts 的 A-054.F-A 格,靠真 `scopeCoversCwd` 咬住两侧任何一侧的单独漂移)。
|
|
86
|
-
* `path.resolve` 不抛 ⇒ 初版的 realpath 失败 F 类兜底臂(`rule-scope-root-unresolvable`)随之退役
|
|
87
|
-
* (census 行同批销,fail-open.ts)。
|
|
88
|
-
*/
|
|
89
17
|
export function cardRuleScopeRoot(registeredCwd, config, cwd = process.cwd) {
|
|
90
18
|
const raw = registeredCwd ?? (inProcessSingleUserLane(config) ? cwd() : undefined);
|
|
91
19
|
return raw === undefined ? undefined : path.resolve(raw);
|
|
92
20
|
}
|
|
93
|
-
/** Is a requested cwd ALREADY the engine process's working dir? realpath BOTH sides (macOS `/tmp` →
|
|
94
|
-
* `/private/tmp`-class symlinks); either side failing to resolve ⇒ treated as a mismatch (warn — never a
|
|
95
|
-
* false downgrade). `realpath`/`cwd` are parameters for testability; production passes `fs.realpathSync`. */
|
|
96
21
|
export function satisfiedByProcessCwd(requested, realpath, cwd = process.cwd) {
|
|
97
22
|
try {
|
|
98
23
|
return realpath(requested) === realpath(cwd());
|
|
@@ -101,24 +26,10 @@ export function satisfiedByProcessCwd(requested, realpath, cwd = process.cwd) {
|
|
|
101
26
|
return false;
|
|
102
27
|
}
|
|
103
28
|
}
|
|
104
|
-
/** How many requested shellEnv entries the engine process env does NOT already carry (value-exact compare).
|
|
105
|
-
* 0 ⇒ satisfied by the inherited process state (debug, not "ignored"). Callers must log only this COUNT —
|
|
106
|
-
* never env values (secret-class), and not key names either (a name can itself carry sensitive semantics). */
|
|
107
29
|
export function shellEnvMismatchCount(requested, procEnv) {
|
|
108
30
|
return Object.keys(requested).filter((k) => procEnv[k] !== requested[k]).length;
|
|
109
31
|
}
|
|
110
|
-
/** Cap on the number of `--add-dir` entries a caller may attach (bounds a pathological allowlist blast). */
|
|
111
32
|
export const MAX_ADDITIONAL_DIRS = 64;
|
|
112
|
-
/**
|
|
113
|
-
* design/119 (CC `--add-dir` parity): validate an untrusted `body.additionalDirectories` — extra host dirs the
|
|
114
|
-
* FILE tools may access beyond the containment root (core canonicalizes each into its allowlist + lists them in the
|
|
115
|
-
* `# Environment` block). Gated identically to {@link cwdHonored}: these are the caller's OWN-machine paths, so they
|
|
116
|
-
* only make sense — and are only safe — on the single-user host lane (on a cloud/container lane a file-tool root is
|
|
117
|
-
* the sandbox fs, and a multi-tenant lane must never let one caller widen containment onto operator/other-tenant
|
|
118
|
-
* host paths). Each element gets the SAME structural check as `cwd` (absolute, no `..` traversal, no NUL, capped);
|
|
119
|
-
* malformed entries are dropped (never throw), the count is bounded, and duplicates collapse. Returns undefined when
|
|
120
|
-
* nothing valid remains (so the spec field stays absent rather than an empty array). NOT an existence check.
|
|
121
|
-
*/
|
|
122
33
|
export function parseAdditionalDirectories(raw) {
|
|
123
34
|
if (!Array.isArray(raw))
|
|
124
35
|
return undefined;
|
|
@@ -128,25 +39,12 @@ export function parseAdditionalDirectories(raw) {
|
|
|
128
39
|
if (out.length >= MAX_ADDITIONAL_DIRS)
|
|
129
40
|
break;
|
|
130
41
|
if (!isValidCwd(entry) || seen.has(entry))
|
|
131
|
-
continue;
|
|
42
|
+
continue;
|
|
132
43
|
seen.add(entry);
|
|
133
44
|
out.push(entry);
|
|
134
45
|
}
|
|
135
46
|
return out.length > 0 ? out : undefined;
|
|
136
47
|
}
|
|
137
|
-
/**
|
|
138
|
-
* core 1.219 `ExecutionEnvFactoryContext.parentCwd` (dogfood: sub-agents landed in an EMPTY
|
|
139
|
-
* sandbox — "当前工作目录为空"): resolve the HOST lane's effective workspace for a task. Precedence:
|
|
140
|
-
* 1. the session's explicitly-registered `cwd` (the caller's own launch dir, the cwd seam) — an explicit
|
|
141
|
-
* per-session choice always wins;
|
|
142
|
-
* 2. the TRUSTED `ctx.parentCwd` (core threads the PARENT task's working root via `RunInternals` when this
|
|
143
|
-
* task is a delegated child — never a TaskSpec field), UNLESS the child asked for `isolation:"worktree"`
|
|
144
|
-
* (core contract: worktree wins — an isolated fan-out child must not share the parent's mutable dir);
|
|
145
|
-
* 3. undefined → the factory's ephemeral per-task dir (top-level task with no registered cwd).
|
|
146
|
-
* CC parity: a Task sub-agent inherits the main session's cwd. Trust: `parentCwd` comes from core's trusted
|
|
147
|
-
* run-internals channel (same posture as `isolation`), so no tenancy gate is needed here — but the HOST lane
|
|
148
|
-
* itself is single-user by deployment shape, and container lanes (k8s/e2b/local-docker) never consult this.
|
|
149
|
-
*/
|
|
150
48
|
export function effectiveHostWorkspace(sessionCwd, ctx) {
|
|
151
49
|
return sessionCwd ?? (ctx.isolation !== "worktree" ? ctx.parentCwd : undefined);
|
|
152
50
|
}
|
package/dist/task-mcp.js
CHANGED
|
@@ -1,52 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* [TOC MCP seam, R3] — project the TOC client's local
|
|
3
|
-
* `.mcp.json` (`TaskRequest.mcpServers`) into the engine, so a `sema` run honors the user's own MCP servers
|
|
4
|
-
* (CC-parity "配置即用" local-first), instead of ONLY the center-config MCP. Mirrors the `cwd` seam (task-cwd.ts).
|
|
5
|
-
*
|
|
6
|
-
* 🔒 SECURITY — per-request MCP is the constitutional "untrusted-client tool injection" red line, because an MCP
|
|
7
|
-
* server is a TOOL SOURCE and an stdio transport is **arbitrary command execution**. The decisive fact (verified):
|
|
8
|
-
* core materializes stdio MCP with `StdioClientTransport`, which spawns the command as a child of **the WORKER
|
|
9
|
-
* (core's process), NOT the execution env** — so an stdio MCP runs on the worker host REGARDLESS of the exec lane
|
|
10
|
-
* (host/e2b/docker). Therefore the trust boundary is NOT "the host execution lane" (that's where the agent's TOOL
|
|
11
|
-
* CALLS run, irrelevant to MCP) — it is **"is the worker single-user, i.e. is the requester the super-admin?"** =
|
|
12
|
-
* `requirePrincipal !== true`. core's ruling (R3): the SERVICE is core's caller-trust-root; body→`TaskSpec.mcp` is a
|
|
13
|
-
* trust decision the service makes, never a passthrough.
|
|
14
|
-
* - SINGLE-USER deployment (`requirePrincipal===false`): the requester IS the super-admin of their own worker, so
|
|
15
|
-
* their `.mcp.json` is authoritative — exactly what CC does on the user's machine. This holds across EVERY
|
|
16
|
-
* execution lane (host / E2B / k8s / local-docker), so a TOC user who switches execution local↔cloud keeps their
|
|
17
|
-
* MCP honored seamlessly (TOC↔cloud is a spectrum, not a wall — clay 2026-06-29: TOB = single-user + people-mgmt).
|
|
18
|
-
* The caller being the trust root, `toolAxes` (authoritative effect overrides) + `elicitation` are their own choices.
|
|
19
|
-
* - MULTI-TENANT deployment (`requirePrincipal===true`): a tenant must NOT make the SHARED worker run an arbitrary
|
|
20
|
-
* command (RCE) or connect to a body-chosen URL (SSRF). Gate CLOSED → body MCP ignored; the fleet gets MCP only
|
|
21
|
-
* through center config refs. Per-principal http-remote injection (a center `allowMcpInjection` entitlement via
|
|
22
|
-
* `runtimeCapsResolver`) is a DEFERRED v2.
|
|
23
|
-
* When the gate is closed, a sent `mcpServers` is IGNORED (advertised via `capabilities.mcpInjection`).
|
|
24
|
-
*/
|
|
25
1
|
import { resolveComplianceDenies } from "@sema-agent/core";
|
|
26
2
|
import { HttpError } from "./security.js";
|
|
27
|
-
/** Bound on caller-supplied servers (anti-DoS; a real local `.mcp.json` has a handful). */
|
|
28
3
|
export const MAX_REQUEST_MCP_SERVERS = 32;
|
|
29
|
-
/**
|
|
30
|
-
* Does THIS deployment honor caller-supplied per-request MCP servers? TRUE for a SINGLE-USER deployment
|
|
31
|
-
* (`requirePrincipal !== true`) — the requester is the super-admin of their own worker, so their `.mcp.json` is
|
|
32
|
-
* authoritative (CC-parity), on ANY execution lane (the stdio command runs on the worker, not the exec env, so the
|
|
33
|
-
* lane is irrelevant — see module header). FALSE on a multi-tenant deployment (a tenant can't make the shared worker
|
|
34
|
-
* run an arbitrary command / connect to an arbitrary URL).
|
|
35
|
-
*/
|
|
36
4
|
export function mcpInjectionHonored(config) {
|
|
37
|
-
// design/170 件C(codex 对抗复审 F2,验真后采纳):**锁也是这条轴的一票否决**。旧谓词只看租户轴,
|
|
38
|
-
// 于是「单用户 + `mcp` 锁」的部署会广告 `mcpInjection:true`,而每一个照此渲出 affordance 的调用方发过
|
|
39
|
-
// 来都吃 `config.locked_key` 400 —— 本仓 capabilities 面的立面承诺(「says yes ⟺ route works」)当场破。
|
|
40
|
-
// 判据合取在这里而不是在能力位那行,是因为这只谓词是**唯一**属主(能力位与请求腿都读它)。
|
|
41
5
|
if (config.lockedConfigKeys?.includes("mcp") === true)
|
|
42
6
|
return false;
|
|
43
|
-
// 件B 同族(R2-F2):合规档位禁了 `mcp_servers` 时,core 对**带 spec.mcp 的每一条腿**整拒 prepare
|
|
44
|
-
// (`config.compliance_denied`,亲核 prepare-task 的 compliance 段)。同样是「广告了却用不了」,同样一票否决。
|
|
45
|
-
//
|
|
46
|
-
// ⚠️ **刻意不 catch**(#191 门② SHAPE C 当场逮到的那一版已撤):`resolveComplianceDenies` 对闭集外的值
|
|
47
|
-
// 是 fail-loud 的,而这个档位在到这里之前已经被验过两遍(config 解析层 + boot 装配层),所以它在本站点
|
|
48
|
-
// 抛不出来。真抛了 = 有人绕过那两道门往 config 里塞了一个解析不了的档位 —— 那种时候**响亮**(路由 500)
|
|
49
|
-
// 才是对的方向,吞成一个布尔位等于让一台档位坏掉的部署继续对外广告能力位(安全轴禁静默兜底)。
|
|
50
7
|
if (config.compliancePosture !== undefined && resolveComplianceDenies(config.compliancePosture).has("mcp_servers"))
|
|
51
8
|
return false;
|
|
52
9
|
return config.requirePrincipal !== true;
|
|
@@ -54,7 +11,6 @@ export function mcpInjectionHonored(config) {
|
|
|
54
11
|
function isStringRecord(v) {
|
|
55
12
|
return !!v && typeof v === "object" && !Array.isArray(v) && Object.values(v).every((x) => typeof x === "string");
|
|
56
13
|
}
|
|
57
|
-
/** Validate + normalize ONE caller entry to a core `McpServerSpec`, or null if malformed (dropped, not fatal). */
|
|
58
14
|
function normalizeServer(e) {
|
|
59
15
|
if (!e || typeof e !== "object")
|
|
60
16
|
return null;
|
|
@@ -77,7 +33,6 @@ function normalizeServer(e) {
|
|
|
77
33
|
};
|
|
78
34
|
}
|
|
79
35
|
else if (tr.kind === "http") {
|
|
80
|
-
// http(s) only — never file://, never a bare host (a syntactic guard; cloud http injection is still gated off-lane).
|
|
81
36
|
if (typeof tr.url !== "string" || !/^https?:\/\//i.test(tr.url))
|
|
82
37
|
return null;
|
|
83
38
|
transport = {
|
|
@@ -91,27 +46,19 @@ function normalizeServer(e) {
|
|
|
91
46
|
return null;
|
|
92
47
|
}
|
|
93
48
|
const spec = { name: o.name, transport };
|
|
94
|
-
// #272(#269 车1 codex F1 的孪生修,2026-08-16):`allowTools` 是**收窄**字段,core 把缺席解释成
|
|
95
|
-
// 「不限制」——旧形「坏形丢键、server 照挂」= 调用方要求只挂一条,实际挂上远端全部工具(每条还可能
|
|
96
|
-
// 带 write 语义),收窄意图坏形时退化成放行。判据与 task-a2a.ts 同一句:**一个键在场就必须合法,
|
|
97
|
-
// 否则这条 server 整条不进**(null ⇒ 上层记 dropped 带名)。缺席仍合法=真「不限制」。
|
|
98
49
|
if (o.allowTools !== undefined) {
|
|
99
50
|
if (!Array.isArray(o.allowTools) || !o.allowTools.every((a) => typeof a === "string"))
|
|
100
51
|
return null;
|
|
101
52
|
spec.allowTools = o.allowTools;
|
|
102
53
|
}
|
|
103
|
-
// caller-trust-root (host-lane single-user): the user's own effect/elicitation choices are kept (CC-parity).
|
|
104
54
|
if (typeof o.elicitation === "boolean")
|
|
105
55
|
spec.elicitation = o.elicitation;
|
|
106
56
|
if (o.toolAxes && typeof o.toolAxes === "object" && !Array.isArray(o.toolAxes)) {
|
|
107
|
-
// 轴B #6(1.254):裸 cast 换 per-key 形状校验——单用户 caller-trust-root 姿势不变(值语义仍由 caller
|
|
108
|
-
// 定),只挡畸形值直达 core(非对象条目/未知枚举字段值静默剔除,诚实收窄不 400)。
|
|
109
57
|
const axes = {};
|
|
110
58
|
for (const [tool, ax] of Object.entries(o.toolAxes)) {
|
|
111
59
|
if (!ax || typeof ax !== "object" || Array.isArray(ax))
|
|
112
60
|
continue;
|
|
113
61
|
const a = ax;
|
|
114
|
-
// 真域对齐 core types(自查纠偏:egress 是 boolean、irreversibility 是 "always"|"never")
|
|
115
62
|
const entry = {
|
|
116
63
|
...(a.effect === "read" || a.effect === "write" || a.effect === "idempotent" ? { effect: a.effect } : {}),
|
|
117
64
|
...(typeof a.egress === "boolean" ? { egress: a.egress } : {}),
|
|
@@ -125,10 +72,6 @@ function normalizeServer(e) {
|
|
|
125
72
|
}
|
|
126
73
|
return spec;
|
|
127
74
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Shape-check the raw `body.mcpServers`. `null` → a non-array (caller error; the route may 400). Otherwise the
|
|
130
|
-
* valid subset + the names of dropped (malformed/over-cap) entries.
|
|
131
|
-
*/
|
|
132
75
|
export function validateRequestMcp(raw) {
|
|
133
76
|
if (raw === undefined || raw === null)
|
|
134
77
|
return { ok: [], dropped: [] };
|
|
@@ -147,23 +90,6 @@ export function validateRequestMcp(raw) {
|
|
|
147
90
|
dropped.push(`(+${raw.length - MAX_REQUEST_MCP_SERVERS} over cap of ${MAX_REQUEST_MCP_SERVERS})`);
|
|
148
91
|
return { ok, dropped };
|
|
149
92
|
}
|
|
150
|
-
/**
|
|
151
|
-
* design/170 件C §4.3 —— **同步**拒面:部署锁了 `mcp` 而请求仍带 `mcpServers` ⇒ 400 `config.locked_key`。
|
|
152
|
-
*
|
|
153
|
-
* 为什么在这里也拒一次(与 core 的 prepare 门不是「两处裁决」):设计稿把裁决点定在 server 治理层,
|
|
154
|
-
* core 的 preflight 执行的是**同一条**判据的引擎侧终局形。二者语义等价、位置不同 —— 一个请求根本不该
|
|
155
|
-
* 进 core 才发现自己被锁,而消费端拿到一条同步 4xx 比拿到一个跑起来又终态失败的任务可诊断得多。
|
|
156
|
-
*
|
|
157
|
-
* 判据是「请求**占位**」而不是「请求的值合不合法」:锁是两态的,占了就整拒,不静默丢(静默丢正是
|
|
158
|
-
* design/170 §2.3 讲的那种把判决变成探针的形)。键缺席 / 显式 `null` 都不是占位。
|
|
159
|
-
*
|
|
160
|
-
* ⚠️ **不看车道**:多租户腿本来就会忽略 body MCP(`mcpInjectionHonored` 关),但锁在场时忽略是错的
|
|
161
|
-
* 失败方向 —— operator 声明了「本部署不收任务自带 MCP」,那就该说出来,而不是安静地当没看见。
|
|
162
|
-
*
|
|
163
|
-
* ⚠️ **resume 腿同拒,这是刻意的**(与本仓「4xx 会砖存量 task」的一般姿势有意分歧):锁上之后,一条存量
|
|
164
|
-
* 任务的 body 里带着 mcpServers 就再也过不了 core 的 preflight —— 放它进去只会换来一个跑起来又终态失败的
|
|
165
|
-
* 任务。同样是失败,同步 400 至少是**立刻可诊断**的那一种,而且拒得出理由(锁在哪、怎么改)。
|
|
166
|
-
*/
|
|
167
93
|
export function assertRequestMcpUnlocked(bodyMcp, lockedKeys) {
|
|
168
94
|
if (!lockedKeys.has("mcp"))
|
|
169
95
|
return;
|
|
@@ -173,11 +99,6 @@ export function assertRequestMcpUnlocked(bodyMcp, lockedKeys) {
|
|
|
173
99
|
code: "config.locked_key",
|
|
174
100
|
});
|
|
175
101
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Merge GATED per-request MCP servers OVER the deployment baseline (center/config). The baseline WINS on a name
|
|
178
|
-
* clash — a caller can ADD servers but can never SHADOW a configured one (the security baseline is authoritative,
|
|
179
|
-
* same posture as `mergeUserSkills`). Returns the baseline unchanged when there is nothing to add.
|
|
180
|
-
*/
|
|
181
102
|
export function mergeRequestMcp(baseline, gated) {
|
|
182
103
|
if (gated.length === 0)
|
|
183
104
|
return baseline;
|
|
@@ -185,16 +106,7 @@ export function mergeRequestMcp(baseline, gated) {
|
|
|
185
106
|
const add = gated.filter((s) => !taken.has(s.name));
|
|
186
107
|
return add.length === 0 ? baseline : [...(baseline ?? []), ...add];
|
|
187
108
|
}
|
|
188
|
-
|
|
189
|
-
* The single entry point the spec-builder calls: compute the effective `TaskSpec.mcp` = deployment baseline + the
|
|
190
|
-
* caller's gated per-request servers. Off the honored lane (or with no caller servers) returns the baseline
|
|
191
|
-
* unchanged. Logs an `mcp_injection_ignored` when a caller SENT servers a closed gate dropped (so the shell never
|
|
192
|
-
* silently believes its `.mcp.json` took effect — it also reads `capabilities.mcpInjection`).
|
|
193
|
-
*/
|
|
194
|
-
export function resolveRequestMcp(baseline, bodyMcp,
|
|
195
|
-
// `lockedConfigKeys` 随 config 一并进(design/170 件C):`assertRequestMcpUnlocked` 已在腿首整拒,所以
|
|
196
|
-
// 这里的 honored 判据在锁形下不可达 —— 保留它是纵深(判据只有一只谓词,不许两处各判一半)。
|
|
197
|
-
config, logger) {
|
|
109
|
+
export function resolveRequestMcp(baseline, bodyMcp, config, logger) {
|
|
198
110
|
if (bodyMcp === undefined || bodyMcp === null)
|
|
199
111
|
return baseline;
|
|
200
112
|
const honored = mcpInjectionHonored(config);
|