@sema-agent/server 7.137.0 → 7.138.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/MIGRATION.md +328 -139
- package/README.md +1 -0
- package/README.zh-CN.md +1 -0
- package/USAGE.md +67 -20
- package/dist/approval-card.d.ts +21 -14
- package/dist/approval-card.js +1 -0
- package/dist/audit.js +1 -0
- package/dist/background-agent-name.d.ts +5 -0
- package/dist/background-agent-name.js +5 -0
- package/dist/boot/budget-tracing.d.ts +1 -12
- package/dist/boot/deployment-mods.d.ts +46 -16
- package/dist/boot/deployment-mods.js +82 -6
- package/dist/boot/governance-seams.d.ts +10 -17
- package/dist/boot/governance-seams.js +5 -17
- package/dist/boot/leader.d.ts +3 -0
- package/dist/boot/leader.js +1 -0
- package/dist/boot/org-delivery.js +15 -2
- package/dist/boot/resolve-spec.d.ts +3 -0
- package/dist/boot/resolve-spec.js +23 -12
- package/dist/boot/retention-lane.d.ts +11 -5
- package/dist/boot/retention-lane.js +2 -2
- package/dist/boot/runner-deps.d.ts +7 -3
- package/dist/boot/runner-deps.js +1 -0
- package/dist/boot/stage-04-stores.d.ts +1 -12
- package/dist/boot/stage-05-execution-env.d.ts +3 -12
- package/dist/boot/stage-05-execution-env.js +7 -4
- package/dist/boot/stage-06-runners.d.ts +3 -12
- package/dist/boot/stage-06-runners.js +5 -2
- package/dist/boot/stage-07-capability-layer.d.ts +3 -12
- package/dist/boot/stage-07-capability-layer.js +2 -2
- package/dist/boot/stage-08-reapers.d.ts +3 -12
- package/dist/boot/stage-09-leader.d.ts +3 -12
- package/dist/boot/stage-09-leader.js +2 -2
- package/dist/boot/stage-10-http-server.d.ts +3 -12
- package/dist/boot/stage-10-http-server.js +4 -2
- package/dist/boot/web-admin.d.ts +5 -2
- package/dist/boot/web-admin.js +3 -3
- package/dist/brain.js +5 -5
- package/dist/budget.d.ts +17 -15
- package/dist/budget.js +2 -2
- package/dist/capabilities/mcp-probe.d.ts +36 -11
- package/dist/capabilities/mcp-probe.js +44 -5
- package/dist/capability-facts.d.ts +6 -0
- package/dist/capability-facts.js +5 -0
- package/dist/checkpoint-identity.d.ts +13 -6
- package/dist/config-catalog.js +7 -1
- package/dist/config-types.d.ts +15 -7
- package/dist/config.js +8 -5
- package/dist/deployment-shape.d.ts +6 -6
- package/dist/gate-settlement.d.ts +71 -0
- package/dist/gate-settlement.js +40 -0
- package/dist/hooks/classic-stations.d.ts +1 -0
- package/dist/hooks/classic-stations.js +1 -0
- package/dist/hooks/command-spawn.d.ts +2 -2
- package/dist/hooks/hook-runner.js +14 -14
- package/dist/http/admission.js +4 -2
- package/dist/http/dispatch.d.ts +4 -0
- package/dist/http/dispatch.js +3 -0
- package/dist/http/durable-run-leg.js +4 -2
- package/dist/http/memory-compliance-failure-reply.js +3 -0
- package/dist/http/resume-legs.d.ts +5 -11
- package/dist/http/resume-legs.js +136 -91
- package/dist/http/route-ctx.d.ts +30 -51
- package/dist/http/route-ctx.js +2 -5
- package/dist/http/routes/a2a-serve.js +10 -4
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +5 -1
- package/dist/http/routes/approvals-assistant.js +6 -6
- package/dist/http/routes/capabilities.js +12 -10
- package/dist/http/routes/mcp-reconnect.d.ts +3 -2
- package/dist/http/routes/mcp-reconnect.js +7 -5
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/rules.js +3 -3
- package/dist/http/routes/runs.js +11 -7
- package/dist/http/routes/sessions.js +6 -4
- package/dist/http/routes/side-query.js +2 -3
- package/dist/http/routes/tasks.js +792 -780
- package/dist/http/server.d.ts +31 -25
- package/dist/http/wire-types.d.ts +14 -6
- package/dist/identity-source.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/leader/wire.d.ts +7 -0
- package/dist/leader/wire.js +5 -4
- package/dist/mcp-assertion-header.d.ts +51 -40
- package/dist/mcp-assertion-header.js +10 -11
- package/dist/mcp-authorization-face.d.ts +27 -0
- package/dist/mcp-authorization-face.js +15 -0
- package/dist/memory-operator-faces.d.ts +13 -4
- package/dist/memory-operator-faces.js +1 -17
- package/dist/memory-sync-client.js +72 -57
- package/dist/memory-sync.d.ts +1 -1
- package/dist/model-route-gap.d.ts +6 -22
- package/dist/model-route-gap.js +7 -5
- package/dist/mods-declaration.d.ts +110 -0
- package/dist/mods-declaration.js +109 -0
- package/dist/observability/err-text.d.ts +5 -0
- package/dist/observability/err-text.js +9 -0
- package/dist/observability/fail-open.d.ts +5 -1
- package/dist/observability/fail-open.js +5 -1
- package/dist/observability/secret-env-scrub.d.ts +1 -1
- package/dist/observability/secret-env-scrub.js +1 -1
- package/dist/parked-decide.d.ts +15 -2
- package/dist/parked-decide.js +14 -8
- package/dist/peer-seat.d.ts +150 -0
- package/dist/peer-seat.js +239 -0
- package/dist/permission-rule-vocab.d.ts +7 -7
- package/dist/permission-rule-vocab.js +3 -3
- package/dist/plain-string-record.d.ts +38 -0
- package/dist/plain-string-record.js +38 -0
- package/dist/plugins/background-agent-store-sql.js +6 -3
- package/dist/plugins/caching-session-store.d.ts +5 -0
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +15 -20
- package/dist/plugins/checkpoint-store-sql.js +8 -8
- package/dist/plugins/file-history-store-sql.js +3 -2
- package/dist/plugins/k8s-pod-reaper.d.ts +2 -8
- package/dist/plugins/k8s-pod-reaper.js +3 -3
- package/dist/plugins/local-checkpoint-store.d.ts +1 -11
- package/dist/plugins/local-checkpoint-store.js +0 -1
- package/dist/plugins/local-session-store.d.ts +66 -27
- package/dist/plugins/local-session-store.js +60 -28
- package/dist/plugins/mailbox-store-sql.d.ts +11 -3
- package/dist/plugins/mailbox-store-sql.js +103 -15
- package/dist/plugins/memory-sync-store-pg.d.ts +16 -5
- package/dist/plugins/memory-sync-store-tidb.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +6 -3
- package/dist/plugins/one-time-migrations.js +3 -4
- package/dist/plugins/permission-rule-store-sql.js +21 -13
- package/dist/plugins/pg-session-storage.d.ts +10 -2
- package/dist/plugins/pg-session-storage.js +18 -5
- package/dist/plugins/remote-env-adb.d.ts +3 -1
- package/dist/plugins/remote-env-adb.js +1 -1
- package/dist/plugins/remote-env-device.d.ts +3 -1
- package/dist/plugins/remote-env-device.js +1 -1
- package/dist/plugins/remote-env-e2b.d.ts +2 -0
- package/dist/plugins/remote-env-e2b.js +1 -1
- package/dist/plugins/remote-env-host.d.ts +3 -1
- package/dist/plugins/remote-env-host.js +1 -1
- package/dist/plugins/remote-env-k8s.d.ts +3 -1
- package/dist/plugins/remote-env-k8s.js +1 -1
- package/dist/plugins/remote-env-local-docker.d.ts +2 -0
- package/dist/plugins/remote-env-local-docker.js +1 -1
- package/dist/plugins/remote-env-ssh.d.ts +3 -1
- package/dist/plugins/remote-env-ssh.js +1 -1
- package/dist/plugins/retention-store-sql.d.ts +14 -2
- package/dist/plugins/retention-store-sql.js +6 -0
- package/dist/plugins/session-fork.d.ts +10 -13
- package/dist/plugins/session-fork.js +5 -25
- package/dist/plugins/session-ownership.d.ts +7 -0
- package/dist/plugins/session-ownership.js +5 -0
- package/dist/plugins/session-workspace-cell.d.ts +17 -0
- package/dist/plugins/session-workspace-cell.js +38 -0
- package/dist/plugins/store-backend.js +7 -7
- package/dist/plugins/tidb-pool.js +6 -0
- package/dist/plugins/tidb-session-store.d.ts +17 -2
- package/dist/plugins/tidb-session-store.js +16 -5
- package/dist/plugins/tool-result-store-sql.d.ts +13 -6
- package/dist/plugins/tool-result-store-sql.js +8 -7
- package/dist/plugins/worktree-isolation.d.ts +3 -2
- package/dist/plugins/worktree-isolation.js +1 -7
- package/dist/project-identity.d.ts +1 -14
- package/dist/project-identity.js +0 -4
- package/dist/rules-consent.js +6 -4
- package/dist/run-local.js +12 -6
- package/dist/runs.d.ts +7 -1
- package/dist/runs.js +6 -1
- package/dist/sandbox-git-plane.d.ts +2 -2
- package/dist/server-secret-env.d.ts +6 -3
- package/dist/server-secret-env.js +4 -2
- package/dist/session-incarnation.d.ts +4 -5
- package/dist/session-incarnation.js +2 -2
- package/dist/session-workspace.d.ts +130 -0
- package/dist/session-workspace.js +83 -0
- package/dist/spec-fields.d.ts +1 -1
- package/dist/standing-answer-grant.d.ts +2 -13
- package/dist/standing-answer-grant.js +0 -7
- package/dist/task-a2a.d.ts +44 -14
- package/dist/task-a2a.js +46 -20
- package/dist/task-mcp.d.ts +33 -20
- package/dist/task-mcp.js +46 -22
- package/dist/tool-approval.d.ts +32 -8
- package/dist/tool-approval.js +49 -12
- package/dist/trace/core-keyset-guard.d.ts +33 -18
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +20 -1
- package/dist/trace/exit-seat.js +3 -0
- package/dist/trace/extension-call-face.d.ts +33 -0
- package/dist/trace/extension-call-face.js +39 -0
- package/dist/trace/project.d.ts +25 -7
- package/dist/trace/project.js +29 -3
- package/dist/trace/redact.js +42 -13
- package/dist/trace/self-minted-wire.d.ts +129 -10
- package/dist/trace/self-minted-wire.js +62 -3
- package/dist/trace/wire-projection-faces.d.ts +6 -6
- package/dist/trace/wire-projection-faces.js +6 -5
- package/dist/user-authored-text.d.ts +2 -2
- package/dist/user-authored-text.js +16 -1
- package/dist/web-admin-client/center-request.d.ts +3 -2
- package/dist/web-admin-client/center-request.js +2 -3
- package/dist/web-admin-client/skills-mcp.d.ts +8 -4
- package/dist/web-admin-client/skills-mcp.js +31 -18
- package/dist/web-admin-client/types.d.ts +5 -0
- package/package.json +3 -3
- package/wire-changes/server@7.138.0.json +446 -0
- package/dist/http/mcp-remote-text.d.ts +0 -5
- package/dist/http/mcp-remote-text.js +0 -7
package/README.md
CHANGED
|
@@ -199,6 +199,7 @@ The server is configured entirely through environment variables. The most import
|
|
|
199
199
|
| `REMOTE_EXEC` | unset | Sandbox execution lane: `host` / `local-docker` / `e2b` / `k8s` / `ssh` / `adb`; unset = in-process stub (with `CONFIG_PROVIDER=local` the default becomes `host`). Naming a lane without its required env (e.g. `e2b` without `E2B_API_KEY`) or an unrecognized value **refuses to start** — no silent downgrade to the host/in-process lane (fail-closed). Under `CONFIG_PROVIDER=local` a `config.d/remote-exec.json` **wins over** this env (deliberate: the file is the single-machine source of truth). Since 7.57.0 that preemption is **loud** — `remote_exec_lane_preempted_by_file` names the preempted lane, the effective one, and whether it is an **isolation downgrade** (an isolated lane replaced by a non-isolated one); a file naming a not-yet-wired isolated lane (`e2b`/`k8s`/`ssh`/`adb`) leaves the env lane in force and says so |
|
|
200
200
|
| `SSH_HOST_FINGERPRINT` / `SSH_KNOWN_HOSTS` | unset | **SSH lane host-key verification** (`REMOTE_EXEC=ssh` only). `SSH_HOST_FINGERPRINT` = the host key's SHA256 base64 fingerprint (`SHA256:` prefix and `=` padding both optional); `SSH_KNOWN_HOSTS` = a path to a `known_hosts` file, matched literally on `host` / `[host]:port`. **Either one present ⇒ strict verification, a mismatch REFUSES the connection** (the error carries both fingerprints plus an `ssh-keyscan` line); both set ⇒ both must pass. **Both unset ⇒ a loud per-connection warning (`ssh_host_key_unverified`, man-in-the-middle risk) and the connection proceeds** — the deliberate posture for the batch-deploy lane, registered as a P-DEBT fail-open (`docs/FAIL-OPEN-CENSUS.md`). A malformed fingerprint or an unreadable `known_hosts` path **refuses to start**. Not supported in `known_hosts`, on purpose: hashed (`\|1\|…`) lines, wildcard patterns, `@cert-authority` — all skipped, so a host whose only entries are those is REFUSED (`@revoked` is honored and wins over any plain line, whatever the order) |
|
|
201
201
|
| `HOOKS_TIMEOUT_MS` | unset (600000) | Time budget of each handler of the request `settings.hooks` registration (one event's run of the request's hook entries). Unset = 600000 ms — this is the engine's `budgetMs` for the registration (each handler's own time, one event's run of the request's hook entries); when the budget is spent, or the task is cancelled, the command hooks still running in that handler are stopped (SIGTERM, a short grace, then SIGKILL) — they no longer run on to their own `timeout`; the engine's default for an extension (10 s) is not used. `0` is honored as written (a zero budget). The server's own two observer registrations (deny meter, tool trace) do not read it. A non-integer, negative, or above-`setTimeout`-ceiling (2147483647) value **refuses to start** |
|
|
202
|
+
| `MODS_ROOT` / `MODS_PACKAGES` | unset | **Deployment mod packages** loaded into the deployment seat. `MODS_PACKAGES` = a JSON array of `{ "name", "dir", "tier", "options"? }`: `name` is the package's own name (its `.claude-plugin/plugin.json` `name`, spelled exactly); `dir` an absolute path whose real path must sit strictly under the real path of `MODS_ROOT` (an absolute path; compared by path components — a symlink out of the root, a look-alike sibling such as `/mods-evil`, a `..` traversal, or the root itself all refuse to start); `tier` is required (`prepend` / `user` / `append` — the host declares it, a package never does); `options` is handed to the package's `register` as is. The engine's package reader is the only reader of the package files; this server never reads them. Every declared package is loaded once at boot and the whole list goes through the engine's admission: any failure (bad declaration, outside the root, the reader refuses the package, a name mismatch, the admission refuses) **refuses to start** with one single-line sentence naming the slot or the package — the server's own sentence never echoes declared values (paths, `options`); the reader's / admission's own words are passed through (credential shapes redacted, control characters stripped) and may name the package directory. Loaded ⇒ one `mods_package_loaded` log line per package (carrying the engine reader's `digest` — a digest of the bytes of the three package files it read, which tells you which bytes were loaded and is not a code-integrity credential: code the module loads on its own is not in it), `/health.mods.deploymentPackages` and the capability `modsDeploymentPackages: true`; unset (or `[]`) ⇒ both faces stay exactly as without these knobs. A package is **trusted deployment code** — it runs in this process with access to every tenant and the process credentials, the admission is not a sandbox — so install it only from a read-only artifact tree you control. Changing the declaration or a package needs a restart (no automatic restart signal). The config catalog shows `MODS_PACKAGES` as present / length only. `options` is not a credential channel: this server does not withhold package credentials — `MODS_PACKAGES` itself and any variable a package reads are inherited by the model's child processes on the host lane under `inheritEnv: "all"` (only this server's declared own credentials are withheld), so deliver package credentials through a channel the host-lane model shell cannot read |
|
|
202
203
|
| `CONFIG_PROVIDER` | unset | Config source: `local` (file-backed `config.d/`, single machine) / `remote` (registry control plane). Closed set, matched exactly (7.104.0+): any other value (wrong case, surrounding spaces) refuses to boot; empty = unset |
|
|
203
204
|
| `DEFAULT_SCENARIO` | `code` | Default scenario when the request body names none; must be a scenario this deployment has (boot refuses otherwise) |
|
|
204
205
|
| `SANDBOX_PKG_SOURCE` | `global` | Package sources inside sandboxes: `global` (official upstreams) / `cn` (China mirrors) / `custom` / `none` |
|
package/README.zh-CN.md
CHANGED
|
@@ -169,6 +169,7 @@ curl -s localhost:8090/v1/tasks -H "Authorization: Bearer <SERVICE_AUTH_TOKEN>"
|
|
|
169
169
|
| `REMOTE_EXEC` | 未设 | 沙箱执行通道:`host` / `local-docker` / `e2b` / `k8s` / `ssh` / `adb`;未设 = 进程内 stub(`CONFIG_PROVIDER=local` 时缺省转 `host`)。点名了通道但必需 env 不全(如 `e2b` 缺 `E2B_API_KEY`)或值不在闭集内 ⇒ **启动即拒**——不再静默降级到 host/进程内通道(fail-closed)。`CONFIG_PROVIDER=local` 下 `config.d/remote-exec.json` **压过**本 env(刻意:单机形的真源是那份文件);7.57.0 起这次抢占**响亮**——`remote_exec_lane_preempted_by_file` 点名被抢占的 lane、最终生效的 lane,以及它是不是一次**隔离降级**(隔离 lane 被换成不隔离的);文件点了尚未接线的隔离 lane(`e2b`/`k8s`/`ssh`/`adb`)时 env 腿照旧生效并说明 |
|
|
170
170
|
| `SSH_HOST_FINGERPRINT` / `SSH_KNOWN_HOSTS` | 未设 | **SSH 通道主机密钥校验**(仅 `REMOTE_EXEC=ssh`)。前者 = 主机公钥的 SHA256 base64 指纹(`SHA256:` 前缀与 `=` 填充都可选);后者 = `known_hosts` 文件路径,按 `host` / `[host]:port` **逐字**匹配行。**任一在场 ⇒ 严格校验,不符即拒连**(拒因带两半指纹 + `ssh-keyscan` 取指纹指路一行);两只同时在场 ⇒ 合取(都要过)。**两只全缺席 ⇒ 每连接一条响亮 warn(`ssh_host_key_unverified`,中间人风险)后照常连** —— 批量部署通道的既定姿态,已登记为 P-DEBT fail-open(`docs/FAIL-OPEN-CENSUS.md`)。指纹拼错 / `known_hosts` 路径读不到 ⇒ **启动即拒**。`known_hosts` 里**刻意不支持**:hashed(`\|1\|…`)行、通配符 pattern、`@cert-authority` —— 一律跳过,于是只有这些条目的主机会被**拒连**(`@revoked` 照常生效,且无论写在哪一行都优先于普通匹配行) |
|
|
171
171
|
| `HOOKS_TIMEOUT_MS` | 未设(600000) | 请求 `settings.hooks` 那张扩展注册**每个 handler** 的时间预算(一个事件跑一遍本请求的钩子条目)。未设 = 600000 ms —— 这是引擎对这张注册的 `budgetMs`(每个 handler 自己的时间:一个事件跑一遍本请求的钩子条目);预算到、或任务被取消,这个 handler 里还在跑的命令钩子会被叫停(SIGTERM → 短宽限 → SIGKILL),不再跑到自己的 `timeout`;不用引擎给扩展的缺省(10 s)。`0` **按字面生效**(零预算)。本服务自己的两张观察注册(拒绝计量 / 工具追踪)不读它。非整数 / 负数 / 超 `setTimeout` 上限(2147483647)⇒ **启动即拒** |
|
|
172
|
+
| `MODS_ROOT` / `MODS_PACKAGES` | 未设 | **部署座装载的 mod 包**。`MODS_PACKAGES` = JSON 数组,每项 `{ "name", "dir", "tier", "options"? }`:`name` = 包自己的名(`.claude-plugin/plugin.json` 的 `name`,逐字同);`dir` 绝对路径,真实路径须严格落在 `MODS_ROOT`(绝对路径)的真实路径之下(按路径分量判 —— 符号链接出根、`/mods-evil` 这类前缀相似的兄弟目录、`..` 遍历、根本身都拒启);`tier` 必填(`prepend` / `user` / `append`,宿主声明,包不自报);`options` 原样交包的 `register`。包里的文件只有引擎的读包者一只读者,本服务不读。每只声明的包起服装一次、整列交引擎准入:任一失败(声明坏、越根、读包者拒包、名不同、准入拒)⇒ **拒启**,一行拒句点名哪一席或哪只包 —— 本服务自己写的句子不回显声明的值(路径、`options`);读包者 / 准入交回的话原样透传(凭据形换记号、剥控制字符),其中可能点名包目录。装上了 ⇒ 每包一行 `mods_package_loaded` 日志(带引擎读包者交回的 `digest` —— 装载件三件字节摘要,认得出装的是哪几份字节,非完整性凭据:模块自己再加载的代码不在其内)、`/health.mods.deploymentPackages` 与能力位 `modsDeploymentPackages: true`;未设(或 `[]`)⇒ 两面与没有这两根旋钮时逐字节同。包是**受信的部署代码** —— 在本进程里跑、可触全部租户与进程凭据,准入不是沙箱 —— 只从你控制的只读物料树装。改声明或换包要重启(没有自动重启信号)。配置目录对 `MODS_PACKAGES` 只回在场位与长度。`options` 不是凭据通道:本服务不替包扣凭据 —— `MODS_PACKAGES` 本身与包自己读的任何变量,在宿主车道 `inheritEnv: "all"` 下都会被模型的子进程继承(只有本服务声明的自有凭据被扣),包要的凭据请经宿主车道模型 shell 读不到的渠道交付 |
|
|
172
173
|
| `CONFIG_PROVIDER` | 未设 | 配置来源:`local`(单机文件 `config.d/`)/ `remote`(registry 控制面)。闭集、逐字比较(7.104.0 起):其余任何值(大小写不同、带首尾空白)拒启;空串 = 未设 |
|
|
173
174
|
| `DEFAULT_SCENARIO` | `code` | 请求体未指定场景时的缺省场景;必须是本部署在册的场景名,否则拒启 |
|
|
174
175
|
| `SANDBOX_PKG_SOURCE` | `global` | 沙箱内装包源:`global`(官方源)/ `cn`(国内镜像)/ `custom` / `none` |
|
package/USAGE.md
CHANGED
|
@@ -130,6 +130,12 @@ ANTHROPIC_API_KEY=sk-ant-… # 可选:ANTHROPIC_BASE_URL / ANTHROPIC_VERSION /
|
|
|
130
130
|
目录条目**自己的**凭据(`apiKeyEnv` 点名的变量、`sealedApiKey`)跟着中心 / config.d 的模型面热应用走,不用重启:新起的任务与调用
|
|
131
131
|
用新的一代(在跑的任务用它起跑时那一代)。两处例外:降级壳焊住的目标连凭据身份一起按 `degrade-route` 重启片走;**记忆整理席**的模型在启动时定
|
|
132
132
|
(重启生效),它的凭据却跟着热应用 —— 同名条目把端点和凭据一起换掉时,重启之前整理请求会带**新**凭据打**旧**端点,这种换法之后请重启本服务。
|
|
133
|
+
- **`agents[].model` 写成内联 Model 对象时,这一只模型的请求带哪条凭据**:本服务只验 `id` 非空,引擎对内联对象原样信任、不查目录;每次请求只发**一条**凭据 —— 凭据词头与部署钥互斥,只发赢家。
|
|
134
|
+
优先序:这次调用的 per-model 钥(本服务按内联对象的 `name` 去目录找同名条目的 `apiKeyEnv` / `sealedApiKey`)> 内联对象自己 `headers` 里的凭据词头 > 部署网关钥(`MODEL_API_KEY`)。三种构造:
|
|
135
|
+
① 内联对象声明了凭据词头(如 `x-team-token`)、没有同名目录条目带自己的钥、部署只有网关钥 ⇒ 内联头赢:这只子代的请求带 `x-team-token`、**不带** `authorization`(网关钥不发,所以要求 `authorization` 的上游会拒这条请求);
|
|
136
|
+
② 同名目录条目带 `apiKeyEnv`(或 `sealedApiKey`)⇒ 条目的钥赢:请求带 `authorization`,内联对象上的 `x-team-token` **不发**;
|
|
137
|
+
③ 内联对象没有凭据词头、也没有同名条目的钥 ⇒ 部署网关钥(`authorization`)—— 且只在内联对象的 `baseUrl` 与网关根配对时;配不上的由引擎的配对律响亮拒(`route.credential_mismatch`),不静默发。
|
|
138
|
+
哪些头名算「凭据词头」归引擎的词表(读口 `hasAuthCarrier`:`x-team-token` · `helicone-auth` 算,`x-team-id` · `x-request-id` 不算)。
|
|
133
139
|
- **模型端点回重定向 ⇒ 不跟、该次调用响亮失败**(引擎 7.51.0 起的模型请求;hook 直连腿 —— 会话标题器等 —— 与记忆 embedder 同一条):请求只去被判过的那个根,
|
|
134
140
|
句子 `endpoint answered with a redirect (HTTP <n>); it was not followed and no credential was sent anywhere else — …`。出路:把最终端点写进 base URL
|
|
135
141
|
(`http` 根被重定向到 `https`、网关搬家、尾斜杠重定向都是这一形)。
|
|
@@ -147,6 +153,10 @@ ANTHROPIC_API_KEY=sk-ant-… # 可选:ANTHROPIC_BASE_URL / ANTHROPIC_VERSION /
|
|
|
147
153
|
- **会话自动标题与 hooks 的 `prompt` / `agent` 条目走哪条线路,和主请求读同一只判据**:`provider="anthropic"` 的模型只在 anthropic 路由装上(配了 `ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN`)时走云 `/v1/messages`;
|
|
148
154
|
没装(如 `MODEL_PROVIDER=anthropic` 却只配了 `MODEL_GATEWAY_BASEURL` + `MODEL_API_KEY`)时主请求落网关,这两个面的廉价直连调用同样落网关的 openai 兼容线路(`/chat/completions`),
|
|
149
155
|
端点与凭据照网关的来 —— 此前它们按 `provider` 字面去找一条没装的 anthropic 路由而整条拒发,会话列表没有自动标题。网关端点也解析不到才拒(`config.model_route_endpoint_missing`)。
|
|
156
|
+
- **预览与自动标题只读你自己写的那段文字**:会话列表的 `objectivePreview`、run / leader 行的 `objective_preview`、自动标题取材、收件箱 `objective` 与任务视图 `name` 读同一张闭集 ——
|
|
157
|
+
引擎注入的 `<system-reminder>` / `<task-notification>` / `<attachment>` 块,以及壳铸进用户轮的**本地命令回显**(`<command-name>` / `<command-message>` / `<command-args>`、`<local-command-stdout>` / `<local-command-stderr>` / `<local-command-caveat>`、
|
|
158
|
+
`<bash-input>` / `<bash-stdout>` / `<bash-stderr>` / `<bash-exit-code>`、`<user-memory-input>`)都不算你写的:`/compact` 一类本地命令之后的下一条提交,预览与标题取的是随后那句话,不再是回显;只有回显、没有你的话 ⇒ run / leader 行的预览是空串(任务名折成 `(notification turn)`),会话列表的预览回落到更早的一句、都没有则缺席(`null`)。
|
|
159
|
+
代价:正文里真的写了这些开标签字面的那一段在预览 / 标题里被剥(只是**提到**这些词的原样保留),原文在会话历史读面完整可见。
|
|
150
160
|
- **缺省推断**:`MODEL_PROVIDER` **未设**、但显式配了 Anthropic 协议 base URL(`ANTHROPIC_BASE_URL`)**和**对应凭证(`ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN`)时,缺省自动判 `anthropic` 并打一行启动 warn(`model_provider_inferred`)——纯净机直连 Anthropic 兼容上游不再需要显式第七个键。显式 `MODEL_PROVIDER` 恒赢;只给 base URL 或只给凭证不推断;两者皆无 = `gateway`,与以前逐字节一致。
|
|
151
161
|
- 启动日志的 `brain` 字段会回显当前组合(`failover` / `anthropicRoute` / `anthropicCacheBreakpoints`)。
|
|
152
162
|
- **在服务进程之外读同一套 env 路由**(子路径 `@sema-agent/server/model-route-env`;纯数据 + 纯函数,import 无副作用,值依赖只有 `@sema-agent/core` 与 `@sema-agent/settings-schema`):
|
|
@@ -171,7 +181,13 @@ MODEL_FIRST_TOKEN_TIMEOUT_MS=30000 # 响应头之后迟迟不吐第一个 delt
|
|
|
171
181
|
MODEL_IDLE_TIMEOUT_MS=20000 # (1.40.1)出过 token 后中途卡死:每个 delta 重置,静默超时→中止(补 first-token 只管首字);缺省 300000
|
|
172
182
|
# ④ 断路器:主网关连败 N 次即"开路"→ 快速失败,让 failover 立刻切备(不再逐个等超时)
|
|
173
183
|
MODEL_CIRCUIT_BREAKER=true MODEL_CB_FAILURE_THRESHOLD=5 MODEL_CB_COOLDOWN_MS=30000
|
|
174
|
-
# ⑤ 每次调用的重试上限(0–20)
|
|
184
|
+
# ⑤ 每次调用的重试上限(0–20)。显式设了**恒赢**:原样传给引擎,并遮蔽引擎自己的 `SEMA_MAX_RETRIES` 环境变量。
|
|
185
|
+
# **不设**时按拓扑分两态(启动日志 `brain` 字段里的 `gatewayRetryCap` 回显是哪一态):
|
|
186
|
+
# · 外层有快切层 —— 配了备用网关(`MODEL_GATEWAY_FALLBACK_URLS`)、开了断路器(`MODEL_CIRCUIT_BREAKER`;单路网关上断路器自己不生效,这一条照算)、
|
|
187
|
+
# 或开了反应式降级(`MODEL_DEGRADE_REACTIVE`,须配着降级目标 `MODEL_DEGRADE_TO`;只设前者不装配降级、不算快切层)⇒ openai 兼容腿 server **传 2**(`fast-fail:2`):走共享长阶梯的瞬时失败(网络 / 5xx / 429)按引擎默认的 10 次递增退避要耗上百秒才把错误交给外层,切备 / 断路器 / 降级全看不见错误(确定性的拒连另有短阶梯,默认 2 次,不在此列);
|
|
188
|
+
# 这一态下 `SEMA_MAX_RETRIES` 被遮蔽(server 传了值),要别的次数就显式设 GATEWAY_MAX_RETRIES;
|
|
189
|
+
# · 没有快切层(单路网关,限流 provider 的形)⇒ 不传(`engine-default`),引擎默认当家:读 `SEMA_MAX_RETRIES`(上限 15),没设就是 10。
|
|
190
|
+
# 云 Anthropic 腿(ANTHROPIC_MAX_RETRIES)没有这条收窄:不设就是引擎 / SDK 默认;降级兜底腿也只吃显式的 GATEWAY_MAX_RETRIES(它是最外层,按引擎默认耐心重试)。
|
|
175
191
|
GATEWAY_MAX_RETRIES=10 # openai 兼容腿(第三方限流 provider 走的就是这条)
|
|
176
192
|
ANTHROPIC_MAX_RETRIES=10 # 云 Anthropic 腿
|
|
177
193
|
# ⑥ 慢后端上开 auto 模式(permissionMode:"auto"):分类器那一级也在等同一个排队 + prefill 的后端,到点没裁 ⇒ 这次工具调用被拒。
|
|
@@ -180,7 +196,7 @@ AUTO_MODE_CLASSIFIER_TIMEOUT_MS=180000
|
|
|
180
196
|
```
|
|
181
197
|
- **全部默认关**(超时=0、断路器=false)→ 不设就和以前**逐字节一致**。
|
|
182
198
|
- 断路器**只在配了 `MODEL_GATEWAY_FALLBACK_URLS`(≥2 路)时才有意义**——它的价值是"开路即快速失败 → failover 立刻切备";单网关下它是 no-op(启动日志 `circuitBreakerNoop` 会提示)。只 `network/server/rate_limit` 计入连败,`auth`/`invalid_request` 不计(坏 key 熔断整网关无意义)。备用网关(最后一路)不套断路器。
|
|
183
|
-
- **重试上限**(2026-07-31)
|
|
199
|
+
- **重试上限**(2026-07-31 起不再硬编码):`ANTHROPIC_MAX_RETRIES` **不设就不传给引擎**(引擎 / SDK 默认当家);`GATEWAY_MAX_RETRIES` 不设时按拓扑分两态(上面 ⑤ 段:外层有快切层 ⇒ 网关各路 server 传 2 并遮蔽 `SEMA_MAX_RETRIES`,没有快切层 ⇒ 不传、引擎默认当家),降级兜底腿只吃显式值。以前这里是 server 侧硬编码 `2`(openai 腿甚至零配置出口),而**显式传参压过引擎默认**,于是引擎抬默认对 server 部署毫无效果;第三方限流 provider 下"重试两次就放弃"正是由此而来。现在:单路网关不设=继承引擎默认(抬默认那天自动跟上),设了=按设的走。钉在 `test/brain.test.ts` 的「网关腿重试次数」两条上。
|
|
184
200
|
- 断路器状态:配了 `SESSION_BACKEND=mysql` 时自动用**跨副本共享态**(SQL `breaker_state` 表,写穿+刷新最终一致),否则进程内 Map。启动日志 `breakerState` 字段回显 `shared(mysql)`/`in-process`/`off`。
|
|
185
201
|
断路器键 = `<provider>:<模型>@<路由身份摘要>`(摘要 24 hex;整只键 ≤ 190 字节,`<provider>:<模型>` 过长时截成前缀 + `~` + 摘要;键里不带 URL —— 它进共享表 `breaker_state`、追踪事件与开路错误文本 `circuit open for <键>`;7.132.x 及以前的表 `circuit_breaker` 由起服迁移删掉)。摘要对应哪条路由读启动日志 `brain.circuitBreakerRoutes`(每条带断路器的路由一行:展示串 + 摘要)。
|
|
186
202
|
|
|
@@ -1886,7 +1902,7 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
1886
1902
|
| `GET /v1/sessions/<id>` | 审计回溯:当前上下文 + 摘要(owner 校验);消息里模型 / 工具产出的文本与 live 帧、账本帧同一只脱敏(密钥形换占位,其余字节不变);Read 图像 / PDF 的媒体卡(工具结果消息的 `details`)的 `file.base64` 是字节编码,逐字。**委派子代的转录**也走这一口:`<id>` = 子代帧 / fleet 子代行上的 `transcriptId`(未压缩过的子代首条用户消息是委派 prompt;子代跑过的工具是 assistant 消息里的 `toolCall` 段 + 同 `toolCallId` 的 `toolResult` 行;整段逐字条目走 `…/sync/entries`)。体顶层加性键 `agent: { id?, parentSessionId?, rootSessionId? }`(**7.133.0+**)说这是哪只子代:只投影会话行上存下来的委派元组,`id` 与 fleet 行的 `id`、`GET /v1/agents/roster` 的 `handle` 同一个串;键缺席 = 普通会话 / 老 server / 会话店不存元组(local 后端),读作「没存」、回落 fleet 行 / 名册上的 id。子代会话的属主是铸行那一刻它所在委派树的根会话的属主(**7.133.0+**,写下那一行时按当时读到的写入;此前 SQL 后端上子代会话无主、谁都读得到)⇒ 用发起子代的那位主体读;别的主体与不存在的 id 同一个 `404 not_found.session`。属主为空的委派子代行(根会话本就无主,或升级前写下、还没回填)只有 fleet 调用方读得到(出示 service 凭据、不带主体头;dev-open 部署不钉人),任何具名主体、没有 service 凭据的无身份调用方同样 404(存量无主会话互认臂 —— 单用户形下 `default` 主对无主的普通会话放行,fork / 删除 / `/sync/*`(同步族自 7.134.0 起)同走这一只 —— 对这些 placed 行同样不放行,审批豁免、notify 同样不放行;fork / 删除 / `/sync/*` 的 fleet 调用方与此处同一个判据:出示 service 凭据、不带主体头,带主体头的 service 凭据请求是那位主体,7.134.0 起);SQL 后端每次起服回填这些行(起服读数行 `placedSessionOwnersRemaining` 非零 = 还有没定下的,再起直到为 0,或等它们下一次停驻)。推不出属主的子代写成属主 `_orphan:<id>`,只有 fleet-wide / operator 读得到:SQL 后端的子代行根会话已删时按它记录的父会话,父也删了才是 `_orphan:`;停驻时拷进宿主店的那一份(local 后端)只按根判,根会话已删 ⇒ `_orphan:`;子代被派出 / 批准之后、再次停驻读根之前根会话被删并由别人以同一 id 重新登记 ⇒ 其下的子代再次停驻被否决(读过根之后才换的,写进去的仍是读根那一刻的属主) |
|
|
1887
1903
|
| `GET /v1/approvals?owner=user:42` | 高危写审批(durable,需 `DURABLE_APPROVAL=true`):**operator** 看待办队列(可按 owner 过滤);非 operator 只看自己的。队列里某一行的存储体读不出来、重试不会好时,答 `500` + `errorCode:"approvals.read_corrupt"`(**7.134.0+**;与订阅流同码、同一只判官;运维处置那一行后再读,别原样重试);此刻读不出队列(连接 / 超时 / 店抖动)⇒ `503` + `errorCode:"approvals.read_unavailable"`(**7.135.0+**,此前 500 `internal.error`;稍后重发,这一答不表示队列为空)。`GET /v1/assistant/inbox` / `GET /v1/assistant/tasks` 读同一个队列,两种读失败同码同状态(**7.135.0+**)。停驻的**技能卡**(对引擎 `Skill` 工具的调用)的行带 `boundGrantDigest` / `boundGrants`(批准它还授予的东西:技能名 + 两只工具清单;清单只在哈希等于摘要时才有,是部署文本,渲染要按上下文转义),分类器没给判词的卡带 `classifierNoRuling`(`error` / `timeout` / `parse_error`)—— **7.136.0+**,与 `GET /v1/assistant/inbox` 行逐字同值(此前只有收件箱行与活卡帧带);普通卡三位都缺席。`GET /v1/assistant/inbox` 行的 `objective` 是门所属 run 的**目标预览**(写入时已脱敏、截到约 120 字符,与 `GET /v1/assistant/tasks` 读同一列;委派子代的门读派它的那条 run;没有 run 账本 ⇒ `null`;**7.136.0+**,此前原样回显存着的任务目标,运维 `?owner=` 跨看也是原文) |
|
|
1888
1904
|
| `GET /v1/approvals/stream` | 同一队列的 SSE 推送(范围同上):首拍快照 → `pending` / `resolved` 增量(开了工具审批时另有 `live_pending` / `live_resolved`),空闲时心跳,15 分钟上限(`STREAM_MAX_DURATION` 帧后重连)。**心跳只表示流活着,不表示这一拍读过队列**:队列读不出时每次读失败发一帧 `error`(`approvals.read_unavailable`,流留着、下一拍再读,恢复后同一条流继续);某一行的存储体读不出来、重试不会好时发 `approvals.read_corrupt` 并收流(运维处置那一行后再重连)。15 分钟上限对读失败的拍同样算数。`pending` 帧带的行与 `GET /v1/approvals` 同一只投影(含上面的技能卡三位,**7.136.0+**) |
|
|
1889
|
-
| `POST /v1/approvals/<sessionId>/decide` `{"decision":"approve"|"deny","reason":"…"}` | 批/否并恢复挂起任务(CAS,重复决议 409);**仅 operator**(非 operator → 403)。5.0.0 起旧轮询腿 `POST /v1/approvals/<id>` 已退役。停驻的后台子代**复活不了**(
|
|
1905
|
+
| `POST /v1/approvals/<sessionId>/decide` `{"decision":"approve"|"deny","reason":"…"}` | 批/否并恢复挂起任务(CAS,重复决议 409);**仅 operator**(非 operator → 403)。5.0.0 起旧轮询腿 `POST /v1/approvals/<id>` 已退役。停驻的后台子代**复活不了**(行上没有根会话锚;未起名的后台子代不在此列 —— 引擎 7.57.0 起每只子代都有名字,升级前的无名行读作派生名,照常复活)⇒ `deny` 作废这张卡:`200 {taskId, status:"failed", decision:"deny"}`,卡离开待决队列、子代终局 `failed`;`approve` 答 `409 decide.row_unrevivable`、拒句指路 deny(**7.136.0+**;此前两个决定都 409,卡处理不掉) |
|
|
1890
1906
|
| `GET /v1/tool-approvals/<approvalId>` | 按问读口(**7.133.0+**;与 `POST …/respond` 同门同身份,不是你的 ask 与查无同形 404;**7.136.0+** 两扇决议口 —— `POST …/respond` 与耐久决断口 `POST /v1/tasks/<taskId>/asks/<askId>/decision` —— 与本口同一只属主判据:有行的问读行上当下的属主,收编之后新属主三口都认、前属主三口都 404;本口在店读不出时只对本副本自己铸的活登记回落登记(登记属主认你 ⇒ `pending`),起服接管的登记不回落、答 404 —— 与同一刻的应答口同答,此前本副本上的活卡读的是铸卡那一刻记下的属主):一只审批问此刻在哪一态,`state` ∈ `pending` / `decided` / `parked` / `void`(闭集)。停驻卡被答过 ⇒ `decided`、停驻 run 被取消 ⇒ `void`(**7.134.0+**;7.133.x 恒答 `parked`);停驻行的门已结算却读不出可用的决议(含坏行:状态词 / 种类 / 当事方不在闭集、结算记录过不了引擎的不变量筛、缺必填成员、时刻 / 方向读不出)⇒ 404 `tool_approval.not_pending`,运维日志一行 error(`defect` 首条缺陷句 · `defectCount`)。停驻行的 `decided` 可回到 `parked`:续跑腿在被批准的动作开跑前失败时,引擎重开同一张门 —— 读口答 `parked` + `decidePath` 并另带 `reopened`(**7.135.0+**):`reason` 是引擎的重开因由词(`env_failed` 按原决议经 `decidePath` 再交一次 —— 本副本还留着首次受理回执时(缺省 1 小时内)`…/respond` 回放那张回执、不驱续跑;`tool_unavailable` / `constraint_rejected` 重新决;`config_refused` 改好配置再交或重新决),`decision` / `decidedAtMs` / `decisionNote?` 是重开之前的那次决议(读不出 ⇒ 只带 `reason`);再决之后回到 `decided`。续跑被取消 ⇒ 重开的门被收掉,读作 `void`。全文见契约 §4a-bis-read |
|
|
1891
1907
|
| `GET /v1/agents/roster` | 后台 agent **名册**(7.29 起,需 durable background-agent store,否则 501 `capability.background_agent_store_required`):调用方自己 scope 的 `a…` 行,新→旧。行只带 `handle`/`name`/`agentType`/`status`/`spawnedAt`/`updatedAt`/`settledAt`(content-free;子代产物正文走 `GET /v1/runs/<id>/subagents/<handle>/output`)。查询:`?limit=`(1..100,默认 20)、`?before=`(上一页的 `nextBefore` 游标)、`?status=`(running\|parked\|completed\|failed\|killed)、`?session=`(按会话树窄化)、`?scope=`(**仅** fleet 调用方:不带主体头的 service 凭据 / 只读 `TRACE_TOKEN`(只在没配 service 凭据的部署上够得着这一口)/ dev-open;带主体头的调用方 —— 含带 service 凭据的 —— 锁定自己)。回体 `{agents,total,nextBefore?,truncated?}`;`truncated:true` = 租户行数超过名册窗(500),`total` 此时是窗内数。非属主的行**不出现也不计数**(无存在性 oracle) |
|
|
1892
1908
|
| `GET /v1/capabilities/scenarios/<name>` | 单个场景的只读详情:工具面、提示词概览、**本部署现在跑不跑得动**、附件供给、**技能清单**(见下) |
|
|
@@ -1931,7 +1947,7 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
1931
1947
|
>
|
|
1932
1948
|
> **部署治理三声明(7.21.0 起)**——三根都是**配置期**旋钮,「谁能改它们」≡「谁能改
|
|
1933
1949
|
> 部署配置」,不引入新鉴权面;三根**都不设 = 现行为逐字不变**,坏值一律**拒启**(安全轴上的旋钮不静默失效)。
|
|
1934
|
-
> - `COMPLIANCE_PROFILE=hipaa|zdr`(+ 可选 `COMPLIANCE_ADDITIONAL_DENIES=mcp_servers,workflows,web_fetch,org_memory_mount`,
|
|
1950
|
+
> - `COMPLIANCE_PROFILE=hipaa|zdr`(+ 可选 `COMPLIANCE_ADDITIONAL_DENIES=mcp_servers,workflows,web_fetch,org_memory_mount,a2a_peers`,
|
|
1935
1951
|
> **只能在档位内建 floor 上加禁,不能减**):合规档位否决。档位在场时被禁能力不挂载,任务**显式请求**被禁能力
|
|
1936
1952
|
> ⇒ 响亮拒(prepare 期终态 `config.compliance_denied`)。hipaa 内建禁 `web_fetch`+`org_memory_mount`,zdr 内建禁
|
|
1937
1953
|
> `org_memory_mount`。⚠️ 档位是**部署级**(对本部署所有 principal 同一份)——per-principal 档位需要中心侧下发面,
|
|
@@ -1941,8 +1957,8 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
1941
1957
|
> ②禁 `web_fetch`(**`hipaa` 的内建 floor 就含它**)而本部署是**单用户**形——单用户花名册恒挂 WebFetch
|
|
1942
1958
|
> (多租户形才会把它摘掉)。也就是说 **`COMPLIANCE_PROFILE=hipaa` 目前只能跑在 `REQUIRE_PRINCIPAL=true`
|
|
1943
1959
|
> 的部署上**;拒启文案会逐条说明改法。
|
|
1944
|
-
> - `LOCKED_CONFIG_KEYS=mcp,compliancePosture,retentionPolicy`(
|
|
1945
|
-
> 管理员锁定层。锁了 `mcp` ⇒ 任务自带 `mcpServers` 被**同步 400 整拒**(`errorCode:"config.locked_key"`,不静默丢)。
|
|
1960
|
+
> - `LOCKED_CONFIG_KEYS=mcp,compliancePosture,retentionPolicy`(闭集 = 引擎的锁注册表:`mcp`/`a2a`/`toolPolicy`/`compliancePosture`/`retentionPolicy`;`a2a` 自引擎 7.59.0 起在册):
|
|
1961
|
+
> 管理员锁定层。锁了 `mcp` ⇒ 任务自带 `mcpServers` 被**同步 400 整拒**(`errorCode:"config.locked_key"`,不静默丢)。锁了 `a2a` ⇒ 任务自带的 `a2aPeers`(键在场且不是 `null`,空数组也算)同样被**同步 400 整拒**(`errorCode:"config.locked_key"`,与 `mcpServers` 同码同状态);`GET /v1/capabilities` 的 `a2aInjection` 为 false。续跑重放存体带 `a2aPeers` 的停驻任务在这样的部署上同拒,折成 `409 resume_blocked_by_policy`(`blockedBy:"config.locked_key"`)。
|
|
1946
1962
|
> ⚠️ **本服务拒绝两把装不上的锁**:①`toolPolicy`——本服务每条腿都自铸有效工具策略(部署审批基线 + tighten-only
|
|
1947
1963
|
> 治理拍),锁上会让**每一条**任务在引擎门口被拒,而那把锁本就无物可守(策略已是部署所有、请求放松不了);
|
|
1948
1964
|
> ②`mcp` + 部署自己配了 MCP 服务器——部署的服务器走同一个字段,锁上同样每条腿必拒。两者都在**启动期**点名拒,
|
|
@@ -2277,8 +2293,8 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
2277
2293
|
| HTTP `400` + `errorCode:"request.field_invalid"`(`PATCH /v1/sessions/:id` / 2c 导入的 `title`) | 标题不合形:1–120 个 Unicode 字符、**首尾不得有空白**(服务端不代为 trim,先于 C0 判)、不得含 C0 控制字符、**至少有一个可见字符**(只由零宽 / 方向控制符等不可见码点构成的串被拒,句子 `title must contain at least one visible character`;夹在可见字符之间的照收);`title: null` 清回自动标题;空串是 `request.body_shape` | 客户端送出前自行 trim、拒空显示的标题;按 `errorCode` 分支,句子只作展示 |
|
|
2278
2294
|
| HTTP `400` + `errorCode:"request.field_invalid"`(撞 413 的帽见 `request.payload_too_large`)+ `reason:"over_cap"` / `"too_long"` / `"bad_entry"`(7.132.0 起:工具名清单、子代定义、两张宿主路径清单;7.133.0 起提交体上其余的帽同样带:`jobId` · `systemPrompt` · `appendSystemPrompt` · `settings.outputStyle` · `settings.env` · `clientContext.*` · `sandboxImageProfile` · `outputSchema` · `resumeAt` · 顶层技能 `content` / `baseDir`;子代定义里技能自己的 `content` / `baseDir` 同样带,坐标 `agents[i].skills[j].content`,句子仍是形句) | 撞了帽:`field` = 撞帽那一处的体内坐标(`skills[1].allowedTools` · `agents[0].denyTools[3]` · `agents` · `additionalDirectories` · `systemPrompt` · `settings.env.<变量名>` …),`count` = 送来的条数(`over_cap`)或字符数(`too_long`),`cap` = 帽;`bad_entry` = 清单第 `index` 条坏了(`field` = 那张清单)。7.132.0 起覆盖的面句子头一句恒为 `<field> has <count> entries\|characters — at most <cap> are accepted`;7.133.0 起补上的面句子不变、只加这一组键。同一个字段的形错(不是串、空串)只有句子 | 按 `field` 改那一处(合并 / 拆小条目、缩短文字、修那一条路径);句子只作展示 |
|
|
2279
2295
|
| HTTP `400` + `errorCode:"request.field_conflict"`(7.133.0 起带 `detail`;`requireExistingSession` 缺 `sessionId` 一处是 422) | 请求里的字段互斥或互为前置(`verify` × `cascade`、`capabilitiesNeeded` 没有 `sandboxImageProfile`、`disableSkills` 同体带技能、决定口的 `remember` / `answer` / `editedPlan` 错门 …)。体带 `detail: { kind, fields }`:`kind` 是闭集词(`cascade_verify` · `image_profile` · `resume_anchor` · `system_prompt_fold` · `file_history_restore` · `skills_disabled` · `existing_session` · `scratchpad_root` · `ask_answer` · `policy_person_ask` · `plan_edit` · `plan_mode_after` · `bound_call_door` · `remember_decision`,全表见契约附录 A),`fields` = 冲突涉及的请求体坐标(句子主语在前;互斥的类只点请求里真带了的键,「X 要求 Y」的类 Y 是缺席的前置、也在里面);`system_prompt_fold` 另带 `count` / `cap`(折叠后的字符数与帽) | 按 `detail.kind` 分支(例:`cascade_verify` ⇒ 去掉 `verify` / `cascade` 重提),按 `detail.fields` 定位到那几个键;句子只作展示、别锚文案 |
|
|
2280
|
-
| HTTP `400` + `errorCode:"config.tool_face_control"`(7.126.0 起;流式 / 后台腿的引擎侧拒是 `failed` 终局带同码,受理口拒三条腿都是提交时 400) | 请求的 `allowTools` / `excludeTools` 里有一个**读成空**的条目:任何工具名都不可能有的拼法(空白、括号不配、空名)、`allowTools` 写了 `mcp__*`(引擎拒)、`excludeTools`
|
|
2281
|
-
| HTTP `400` + `errorCode:"config.agent.unknown_tool"`(7.131.0 起) | 请求 `agents[i].denyTools`(限制侧)里有读成空的条目:近似名(`BASH`)、退役名(`bash`)
|
|
2296
|
+
| HTTP `400` + `errorCode:"config.tool_face_control"`(7.126.0 起;流式 / 后台腿的引擎侧拒是 `failed` 终局带同码,受理口拒三条腿都是提交时 400) | 请求的 `allowTools` / `excludeTools` 里有一个**读成空**的条目:任何工具名都不可能有的拼法(空白、括号不配、空名)、`allowTools` 写了 `mcp__*`(引擎拒)、`excludeTools` 够着了这一腿依赖的协议工具(`*` / 前缀 glob / 直接点名都算,原因词 `protocol_denied`;`excludeTools` 写 `*` 本身不拒 —— 7.137.0 起限制侧名内的 `*` 是整名 glob,卸每一只工具),或(7.131.0 起,受理口拒)**近似名**(大小写孪生 `BASH`;放行侧 `allowTools` 与限制侧 `excludeTools` 都拒 —— 想放的什么也没放 / 想禁的照用)与**限制侧的退役名**(`excludeTools: ["Task"]`)。放行侧 `allowTools` 的**内容形**(`Agent(Explore)`)与没有后继的退役名(`MultiEdit`)照 7.130.0 受理、交引擎既有通告(运维行 `runner_config_advisory`);**有后继的退役名**(`Task` · `bash`)7.132.0 起由引擎开跑前拒(`config.tool_face_control`,同步腿 400)。**真未知名**(拼写合法、这台部署没有工具叫它,懒挂载的合法形)7.129.0 起照跑:条目原样留在表里,运维行告知一次。选择器只取工具名那一段判名字(限制侧 `Bash(echo $HOME)` 不拒),`allowTools:["*"]` 与限制侧 `mcp__*` / `a2a__*`(整个协议)合法。清单超 1000 条 ⇒ 整只 `400 request.field_invalid`(`count` / `cap`),帽内拒句只点名前 5 条 + `; and K more`。拒时:主模型零调用、标题器零调用(7.127.0 起;7.126.x 上标题器仍会为这次提交调一次模型)。这次提交留下的会话无标题、零消息 | 改成句子里 `write` 后的现名(或删掉条目);只列这台部署挂得出的工具名 |
|
|
2297
|
+
| HTTP `400` + `errorCode:"config.agent.unknown_tool"`(7.131.0 起) | 请求 `agents[i].denyTools`(限制侧)里有读成空的条目:近似名(`BASH`)、退役名(`bash`)、任何工具名都不可能有的拼法;`agents[i].allowTools`(放行侧)里的**近似名**。开跑前拒、主模型零调用、一个 token 没烧,句子点名条目、原因词与现名。限制侧 `Tool(content)` 的内容不读(读成整只工具)、名内的 `*` 是整名 glob(7.137.0 起,孤 `*` = 每一只工具)、限制侧整个协议的拒 `mcp__*` / `a2a__*`、真未知名(`NotMounted`,照跑、告运维一次)不拒;放行侧的内容形(`Agent(Explore)`)与没有后继的退役名(`MultiEdit`)照 7.130.0 受理、交引擎既有通告,选择器清单里**有后继的退役名**(`Task` · `bash`)7.132.0 起由引擎开跑前拒;文法读不出的放行条目授不出去 = 收窄而不是放行:规则表(`permissions.allow` / 技能 `allowedTools`)上受理口不拒、引擎开跑时告运维;选择器清单(根 / 子代 `allowTools`)上受理口不拒、引擎开跑前自己拒(子代 ⇒ `config.agent.unknown_tool`、根 ⇒ `config.tool_face_control`,同步腿都是 `400`〔7.132.0 起;此前子代这一形答 HTTP 200 + failed 终局体〕;异步 / 活流腿 HTTP 2xx、同码落在终态 run 行) | 改成句子里 `write` 后的现名,或删掉条目 |
|
|
2282
2298
|
| HTTP `400` + `errorCode:"prompt.assembled_role_refused"`(7.132.0 起;流式 / 后台腿是 `failed` 终局带同码) | 请求的 `systemPrompt` / `appendSystemPrompt`(含 `settings.outputStyle`)逐字含引擎提示里的一段锁定文本(宪法、安全段、`# Harness` 这样的标题行)—— 一份已组装的提示。开跑前拒、零调用,句子点名字段与命中段 | 只写角色层:删掉抄进来的引擎段(引擎自己组宪法与行为段;追加段恒排在宪法之后) |
|
|
2283
2299
|
| HTTP `400`(`request.field_invalid` · `config.agent.unknown_tool` · `config.tool_face_control`)· HTTP `422`(设置规则桶)· HTTP `409` `resume_blocked_by_policy` 的拒体另带 `field` + `detail`(7.133.0 起;additive,句子与码不变) | 工具名清单与设置规则里**读成空**的条目被拒时,句子仍只点名先撞上的那一张清单(前 5 条 + `; and K more`);机读位把这一遍判下来的**全部**问题一次列全:`detail.problems` 每条 `{ code, field, entry, reason }`(`code` = 这一条所在清单被拒时的码,`field` = 清单的体内坐标,`entry` = 条目的脱敏原值,`reason` = 原因词),`detail.total` = 问题总数(`problems` 至多 1000 条),顶层 `field` = 第一条问题的坐标(句子点名的那张清单),体的 `errorCode` = 第一条问题的 `code`;只有一条问题就是长度 1 的列表,不是另一种形。超帽的清单整只拒、不逐条读,不在列表里(第一处命中就是它时体只带撞帽的 `field` / `reason` / `count` / `cap`)。同步提交腿上引擎开跑前拒这两张工具名清单(`config.agent.unknown_tool` / `config.tool_face_control`:有后继的退役名、文法读不出的放行条目)的 400 体同形:句子是引擎的,只点名它先撞上的一条,`detail.problems` 是受理口对放行侧选择器清单的读数(只列与体的码同码的那一族清单,所以第一条问题的 `code` 恒等于 `errorCode`) | 按 `detail.problems` 逐条提示 / 改;不要解析句子;`total` 大于 `problems` 的条数 ⇒ 列表被截 |
|
|
2284
2300
|
| HTTP `200` / `202` 应答里的 `warnings`(7.133.0 起;同步腿 200 体 · 流式腿 `meta` 帧 · 异步腿 202 回执;**有话说才在场**) | 请求的放行侧选择器清单(根 `allowTools`、子代定义的 `allowTools`)里有什么也不放的条目,而受理口没拒(放行侧只拒近似名,其余交引擎):`reason` 是引擎条目读法的原因词(`tool_name` · `grammar` · …)或 `not_in_roster`(读得出、却不在名册 —— 引擎目录 ∪ 本服务自铸工具 ∪ 本请求挂的调用方工具(主名 · 别名 · 子代工具池);协议命名空间名 `mcp__*` / `a2a__*` 懒挂载、`*` 是「不设名单」,都不判)。每条 `{ code, field, entry, reason }`,形同上一行。这不是拒:请求照常受理、照跑,引擎对这些条目的既有处置不变 | 把 `warnings` 当提示给用户看(「这几条什么也没放」);同一 `Idempotency-Key` 的重放从 run 记录答,不重判、不带;在飞合流回放的是首发那一腿铸的应答 |
|
|
@@ -2849,7 +2865,7 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
2849
2865
|
- 被采纳的 `settings.hooks`(单用户车道)在引擎里是**一张**扩展注册,名字 `settings.hooks`(`wiring_manifest.mods[]` 里看得到它;
|
|
2850
2866
|
审批卡 `allowRuleShadowed` 的 `hook` 成员、钩子失败时模型读到的拒句都点名它)。本部署自己另挂两张只观察的注册:恒挂的拒绝计量
|
|
2851
2867
|
`server.permission-denied-meter`,`TOOL_TRACE=true` 时的 `server.tool-trace`(品牌部署另有一张提示装配站上的 `server.brand-identity`,只答品牌行 overlay,不在工具门上)。观察者的判词不采纳,链里唯一的答者是请求的钩子。
|
|
2852
|
-
- 每个事件的语义与此前相同:`Stop` 条目在主任务结束与委派子代结束时都跑;`PermissionDenied` / `SubagentStop` / 两个 model-switch 事件属壳,服务端不跑。
|
|
2868
|
+
- 每个事件的语义与此前相同:`Stop` 条目在主任务结束与委派子代结束时都跑;`PermissionDenied` / `SubagentStart` / `SubagentStop` / 两个 model-switch 事件属壳,服务端不跑。
|
|
2853
2869
|
- **`HOOKS_TIMEOUT_MS`** = 这张注册的 `budgetMs`。引擎对它的定义是 "Each handler's own time" —— 每个 handler 自己的时间(一个事件跑一遍本请求的钩子条目;
|
|
2854
2870
|
引擎的钟,handler 等 `next` / `$` 调用的那段暂停),**不是**钩子子进程的墙钟。**未设 = 600000 ms**(= 单条命令超时的上限;引擎的钟在 handler 起跑时就开始走,
|
|
2855
2871
|
命令的 `timeout` 钟要等 shell 解析和起进程之后,所以 `timeout` 配到 600 s 的命令跑满时,预算会先到);`0` 按字面(零预算)。超预算:`PreToolUse` 上该调用被拒(fail-closed,拒句点名 `extension "settings.hooks"`)、
|
|
@@ -2873,16 +2889,16 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
2873
2889
|
|
|
2874
2890
|
`mcpServers[].transport`(`kind:"http"`)上有两个「用哪个头送身份」的可选键,**只能设一个**:`principalHeader`(runner 把该任务已认证的终端用户 principal 注入这个头)与 `assertionHeader`(托管连接器断言所用的头**名**)。
|
|
2875
2891
|
- 请求体(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`)与部署声明(中心下发 / 本地 `config.d/mcp.json`)判据相同:两键同设 ⇒ 请求体新提交腿 `400 request.body_shape`(拒句点名条目与两键,与契约包解析期的拒句逐字相同);`assertionHeader` 不是字符串 ⇒ `400 request.field_invalid`;部署声明里同设的那一条不进。耐久 resume 腿重放存量请求体时不拒、也不摘 server:server 照挂,`principalHeader` 胜、`assertionHeader` 不生效,一行 warn `mcp_assertion_header_ignored`(`server` / `reason` / `note`)。
|
|
2876
|
-
- `assertionHeader` 的**值**是头名,本服务不铸、也不校验具体词(只判是字符串且与 `principalHeader` 互斥)
|
|
2877
|
-
-
|
|
2878
|
-
**发不发有一位可读**:`GET /v1/capabilities` 的 `mcpAssertionHeaderSent`(布尔,今天恒 `false`)—— 它与剥键、那行 info、探测口的那一拒读同一只开关,**互斥**:位 `false` ⇒ 三者都在(别指望断言头会发出去);位 `true`
|
|
2892
|
+
- `assertionHeader` 的**值**是头名,本服务不铸、也不校验具体词(只判是字符串且与 `principalHeader` 互斥);引擎的断言头是固定的名 **`connector-assertion`**(无 `x-` 前缀),值由部署的对端座对 `assertion` 种类的引用作答 —— 本部署没有断言来源,座对这一种恒拒(9.5i),所以这里写的头名**不发送**(下一条)。
|
|
2893
|
+
- 本版只承载、不发送断言(对端座没有断言来源):声明了 `assertionHeader` 的 server 照常挂载,但不带断言头;每台这样的 server 一行 info `mcp_assertion_header_not_sent`(`server` / `note`)。探测口 `POST /v1/capabilities/mcp/probe` 对声明了该键的条目整条拒 `400 request.field_invalid`(探测不拨一份少了断言头的配置)。
|
|
2894
|
+
**发不发有一位可读**:`GET /v1/capabilities` 的 `mcpAssertionHeaderSent`(布尔,今天恒 `false`)—— 它与剥键、那行 info、探测口的那一拒读同一只开关,**互斥**:位 `false` ⇒ 三者都在(别指望断言头会发出去);位 `true`(座有了断言来源之后)⇒ 三者都不再出现、声明的头名随规格交给引擎。按位分支,不要匹配 info 文字;键缺席 = 老 server,按「不发送」读。
|
|
2879
2895
|
|
|
2880
2896
|
### 9.5e 请求体 `mcpServers` 的列表与条目键:写坏,整份新提交 400(7.131.0 起;列表级与词表外的键 7.132.0 起;`startupTimeoutMs` 与 `toolFaces` 的引擎判官 7.134.0 起;`transport.url` 带凭据 7.135.0 起)
|
|
2881
2897
|
|
|
2882
|
-
条目的受理键 = `name` · `transport` · `allowTools` · `toolAxes` · `toolFaces` · `contentOrigin` · `elicitation` · `source` · `startupTimeoutMs`(7.132.0 起)(`transport` 的子键:`kind` · `command` · `args` · `env`(stdio),`kind` · `url` · `headers` · `principalHeader` · `assertionHeader`(http))。**新提交上每个键只有一只判官,判官在受理口,写坏的答案只有一种**(下面第一条:400)。`startupTimeoutMs`(这一只 server 自己的启动界,毫秒整数,范围与引擎 env 旋钮 `MCP_TIMEOUT` 同一段)7.134.0 起同样在受理口判 —— 判官是引擎包根导出的 `mcpStartupTimeoutMs`(启动界的唯一读者):数字串 / 小数 / 越界 / `null` ⇒ `400 request.field_invalid`,原因句是引擎的那一句(7.132.0–7.133.x:受理口不判、请求照常 200,引擎拨号时只拒这一只 server);耐久 resume 重放存量请求不判(原样交引擎,坏值在拨号时只拒这一只 server —— `config.mcp_startup_timeout_invalid`,兄弟照挂)
|
|
2898
|
+
条目的受理键 = `name` · `transport` · `allowTools` · `toolAxes` · `toolFaces` · `contentOrigin` · `elicitation` · `source` · `startupTimeoutMs`(7.132.0 起)· `sessionMetaKey`(7.138.0 起)(`transport` 的子键:`kind` · `command` · `args` · `env`(stdio),`kind` · `url` · `headers` · `principalHeader` · `assertionHeader`(http))。**新提交上每个键只有一只判官,判官在受理口,写坏的答案只有一种**(下面第一条:400)。`startupTimeoutMs`(这一只 server 自己的启动界,毫秒整数,范围与引擎 env 旋钮 `MCP_TIMEOUT` 同一段)7.134.0 起同样在受理口判 —— 判官是引擎包根导出的 `mcpStartupTimeoutMs`(启动界的唯一读者):数字串 / 小数 / 越界 / `null` ⇒ `400 request.field_invalid`,原因句是引擎的那一句(7.132.0–7.133.x:受理口不判、请求照常 200,引擎拨号时只拒这一只 server);耐久 resume 重放存量请求不判(原样交引擎,坏值在拨号时只拒这一只 server —— `config.mcp_startup_timeout_invalid`,兄弟照挂)。`sessionMetaKey`(声明了它的服务器在每次 `tools/call` 的 `_meta` 下收这条腿的会话 id)7.138.0 起同样在受理口判 —— 判官是引擎包根导出的 `judgeSessionMetaKey`(键名格式、保留前缀、上界都是它的):坏形 ⇒ `400 request.field_invalid`,原因句是引擎的那一句;耐久 resume 重放存量请求时坏形让这一条 server 整条不进。
|
|
2883
2899
|
- **新提交**(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`):键在场却判不出形 ⇒ `400 request.field_invalid`,拒句形如 `mcpServers[2].allowTools (server "crm") is not a usable declaration — must be an array of strings (omit the key to leave the server's tools unrestricted) — got a string of 4 characters. …`:点名 `mcpServers[i].<键路径>`、server 名与该键判官的原因句,**整份请求不收** —— 不挂一半、不丢声明、不默认。原因句不回显声明的值,有几处例外,回显只有一只口径(剥控制与双向字符、截到 64 字、超出加 `…`):server 名(含写坏的 `name` 值,另报送来的原长度)、`contentOrigin` 词表外的值;`toolAxes` / `toolFaces` 的原因句是引擎写的(7.134.0 起 `toolFaces` 的判官也是引擎包根导出的 `readToolFaces`):点名工具名(引擎截 80 字)与成员,`toolFaces` 还会点名闭词表拒的那个词,整句详情由引擎截到 240 字、本服务再剥控制与双向字符 —— 不回显显示文本、不回显合规的列表;`transport.url` 的值从不回显(带凭据的 url 被拒时,原因句只点名命中的那一段与凭据名表里的那个词)。可选键**缺席**永远合法(真「没声明」),必填的 `name` / `transport` 缺席同样 400;在场的 `null` 不是缺席。与单用户 / 多租户无关。列表本身同一条律(7.132.0 起,先于条目判):`mcpServers` 在场却不是数组、超过 32 条(整份拒,不挂前 32 条)、某一条不是对象 ⇒ `400 request.field_invalid`,拒句点名 `mcpServers` 或 `mcpServers[i]` 与形的种类;条目层或 `transport` 层出现词表外的键 ⇒ `400 request.body_shape`,拒体带 `unknownKeys`(全路径、至多 20 条)。`mcpServers` 缺席或为 `null` = 没声明,照常受理。
|
|
2884
2900
|
- **`transport.url` 不得带凭据(7.135.0 起)**:http 传输的 `url` 带 userinfo(`https://user:pass@host/mcp`,只有用户名也算),或带名字在凭据名表里的 query / fragment 参数(`?api_key=` · `?key=` · `?token=` · `#access_token=` …;表 = 本服务日志脱敏器认作凭据名的那一张,全表见契约附录 A `request.field_invalid` 行;名字大小写不敏感,按解一次百分号编码读)⇒ 新提交 `400 request.field_invalid`,体另带 `field: "mcpServers[i].transport.url"` 与 `reason`(`url_userinfo` | `url_credential_param`),原因句点名出路:**凭据改写进 `transport.headers`**(如 `"Authorization": "Bearer …"`)。为什么:任务停驻时提交体整份进续跑上下文,`transport.headers` 的值在那里只以封签存在,`url` 照原样存(日志与读面同理)。值从不回显;解析不了的 url 不在这一问里判(拨号时失败)。7.134.x 及以前照收、原样落停驻上下文;带 userinfo 的 url 本就连不上(fetch 对带凭据的 URL 构造即抛),带名表参数的升级后要改。同一条规则在 A2A 对端 / http 钩子 / 搜索后端 / 图片 URL 上的几座见 9.5g。
|
|
2885
|
-
- **耐久 resume 重放存量请求**:不拒(拒会把升级前 park 的任务永久卡死;`transport.url` 带凭据的存量条目照挂、url 逐字交引擎)。写坏的 `name` · `transport` 的 `kind`/`command`/`url` · `allowTools` · `toolAxes` · `toolFaces` ⇒ 这一条 server 整条不进,运维 warn `mcp_injection_dropped`(`reason: malformed_entry`,`field` 点名)并投用户面通告 `mcp.injection_dropped`(其中 `toolAxes` 在一次性迁移 M19 的窗开着时先按升级前读法重读一次,过了就挂,见上文 `toolAxes` 一节);写坏的 `contentOrigin` · `elicitation` · `source` · `transport` 的 `args`/`principalHeader` 与词表外的键 ⇒ 丢掉那一个键、server 照挂;`transport` 的 `env`/`headers`(名 → 串记录)对 JSON 存体按 7.131.x 的读法交:有值不是串的成员 ⇒ 整键不交,只有 `__proto__` 名的成员坏 ⇒ 剔掉它、其余照交;server 照挂,一行运维 warn `mcp_transport_members_dropped` 点名(见 9.5c-bis 同段);条目不是对象 ⇒ 这一条不进(`malformed_entry`);超过 32 条 ⇒ 第 33 条起只记 `over_cap`;整只不是数组 ⇒ 整只忽略 + 运维 warn `mcp_injection_ignored`。
|
|
2901
|
+
- **耐久 resume 重放存量请求**:不拒(拒会把升级前 park 的任务永久卡死;`transport.url` 带凭据的存量条目照挂、url 逐字交引擎)。写坏的 `name` · `transport` 的 `kind`/`command`/`url` · `allowTools` · `toolAxes` · `toolFaces` · `sessionMetaKey` ⇒ 这一条 server 整条不进,运维 warn `mcp_injection_dropped`(`reason: malformed_entry`,`field` 点名)并投用户面通告 `mcp.injection_dropped`(其中 `toolAxes` 在一次性迁移 M19 的窗开着时先按升级前读法重读一次,过了就挂,见上文 `toolAxes` 一节);写坏的 `contentOrigin` · `elicitation` · `source` · `transport` 的 `args`/`principalHeader` 与词表外的键 ⇒ 丢掉那一个键、server 照挂;`transport` 的 `env`/`headers`(名 → 串记录)对 JSON 存体按 7.131.x 的读法交:有值不是串的成员 ⇒ 整键不交,只有 `__proto__` 名的成员坏 ⇒ 剔掉它、其余照交;server 照挂,一行运维 warn `mcp_transport_members_dropped` 点名(见 9.5c-bis 同段);条目不是对象 ⇒ 这一条不进(`malformed_entry`);超过 32 条 ⇒ 第 33 条起只记 `over_cap`;整只不是数组 ⇒ 整只忽略 + 运维 warn `mcp_injection_ignored`。
|
|
2886
2902
|
- `POST /v1/capabilities/mcp/probe` 问的是新提交那**同一只判官**:上面每一形同码同句(含 `unknownKeys`,与 url 带凭据那一形的 `field` / `reason`),拒之前零拨号;判官受理的申报,探测口拨的就是一条任务提交会交给引擎的那一份(判官的合法归一照收)。它多出的两形:本口的体就是这份列表,`mcpServers` 缺席或为 `null` ⇒ `400 request.body_shape`(缺必需字段);声明了 `transport.assertionHeader` 的条目 ⇒ `400 request.field_invalid`(见 9.5d:本版承载、不发送,新提交照挂,探测不拨一份少了断言头的配置 —— 同一只谓词,后果按门分)。7.131.x 上本口另有一只判法(申报原文与读器产物逐字比),列表不是数组 / 条目不是对象答 `request.body_shape`。
|
|
2887
2903
|
- **`toolFaces` 的判官是引擎的 `readToolFaces`(7.134.0 起;此前本服务自带一只只判 JSON 形的读器)**:它在门口就判声明本身能说的一切 —— 成员与类型、五张闭词表、上界、跨成员律 ——
|
|
2888
2904
|
所以下面几形 7.133.x 受理、7.134.0 起 400(重放腿整条 server 不进、中心 / `config.d` 腿跳过该 server 并点名 warn):空工具名;保留审批卡(`renderHints.approvalCard: "question"` / `"plan"`);
|
|
@@ -2944,7 +2960,33 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
2944
2960
|
- 判序:先列表、后条目;条目里先词表外的键、后键值(`name` → `url` → `cardUrl` → `headers` → `principalHeader` → `allowSkills` → `toolAxes`),第一处坏形即答。纯值域、与租户车道无关(多租户部署整只 `a2aPeers` 本会被忽略,告诉调用方「这样写不行」只多不少)。
|
|
2945
2961
|
- **耐久 resume 重放存量请求**不拒(拒会把升级前 park 的任务永久卡死):写坏的条目不挂、运维 warn `a2a_injection_dropped` 点名 —— `dropped` 的每个条目是 `{ peer, reason, field }`:`reason` 是上面判官对那个键的原因句(与受理口 400 拒句里的同一句,不回显值;只有一臂例外:一次性迁移的重读入参克隆不了 —— 访问器成员 / BigInt / Proxy / 环 / 非纯数据 —— 时带前缀 `declaration not cloneable (<because>) — the one-time migration re-reads the stored declaration as plain JSON data and this one is not; `,**其后**才是判官的那一句),`field` 是 `a2aPeers[i].<键路径>`(与 MCP 面 `mcp_injection_dropped` 的条目同键名,名字键 `server` ↔ `peer` 除外);整只不是数组 ⇒ 整只忽略 + `a2a_injection_ignored`。
|
|
2946
2962
|
- 7.135.0 及以前:这些形全部 200 —— 坏形的对端悄悄不挂(只在运维 warn 里点名)、词表外的键悄悄不读(`allowSkills` 拼成 `allowSkill` 的对端照样挂上远端卡声明的全部技能)。升级后这些请求变 400:改对那个键(或删掉它)、把列表改成数组、删掉第 33 条起的条目。
|
|
2947
|
-
- A2A
|
|
2963
|
+
- A2A 的运维锁与合规位(引擎 7.59.0 起在册):`LOCKED_CONFIG_KEYS` 可写 `a2a`、合规档位可禁 `a2a_peers`(`COMPLIANCE_ADDITIONAL_DENIES` 的闭集多这一词)。请求自带的 `a2aPeers` 与 `mcpServers` 同一条合取才兑现:单用户 ∧ `a2a` 未锁 ∧ 合规档位不禁 `a2a_peers`,`GET /v1/capabilities` 的 `a2aInjection` 为这条合取的值。否决的后果按种类分:锁了 `a2a` 而请求仍带 `a2aPeers` ⇒ 同步 `400 config.locked_key`(与 `mcpServers` 的锁同形;续跑重放腿折成 `409 resume_blocked_by_policy`);没锁 `a2a` 而多租户或合规档位禁了 `a2a_peers` ⇒ 忽略(请求照常 200,运维 warn `a2a_injection_ignored`);锁先判,与是否多租户 / 合规禁项无关。条目与列表的形判(本节上面各条)与这道闸无关,照拒。
|
|
2964
|
+
|
|
2965
|
+
### 9.5i MCP / A2A 的凭据件只经部署的对端座作答(7.138.0 起)
|
|
2966
|
+
|
|
2967
|
+
对端的「件」—— http MCP 请求的凭据头(`mcpServers[].transport.headers`、名册的 `headerRefs`)、stdio MCP 子进程的环境变量(`transport.env`、名册的 `envRefs`)、A2A 发送的头(`a2aPeers[].headers`、名册的 `headerRefs`)——
|
|
2968
|
+
本版起**不再写进交给引擎的声明**:本服务的对端座在起子进程 / 发请求的那一刻按原字节作答,声明里只剩一只不透明引用。**请求体的形不变**(仍收 `headers` / `env`,不收引用位;`credentials` 是词表外的键 ⇒ `400 request.body_shape`),
|
|
2969
|
+
名册声明的写法不变(`envRefs` / `headerRefs` 仍在起服时从本进程环境读一次,缺任一变量整条跳过;改变量要重启)。契约 §0.10 成文了同一件事的 wire 面。
|
|
2970
|
+
|
|
2971
|
+
**谁需要读这一节**:用 `.mcp.json` 带凭据头 / 子进程环境的单用户壳,带 `a2aPeers[].headers` 的调用方,名册里用 `envRefs` / `headerRefs` 的部署,自建 `createHttpServer` 的嵌入方(MIGRATION 7.138.0 节第 24 条)。
|
|
2972
|
+
|
|
2973
|
+
- **件的形由引擎在作答处判,比此前严**。下列形读器拒 —— 那一台 `credential_unavailable`(提交照收、兄弟照挂、运行期才见):stdio 件名不是标识符形(含 `.` / `-`,如 `MY-VAR`)· 任一件值含 CR / LF / NUL(多行 PEM、Secret 文件的尾换行;http 头值首尾的换行此前被发送时的头规范化吞掉,现被拒)·
|
|
2974
|
+
http / A2A 头名不是 HTTP token · 两个头名只差大小写 · MCP http 的件头名是传输自己写的头(`content-type` · `accept` · `mcp-session-id` · `mcp-protocol-version` · `last-event-id`;A2A 没有这张表)·
|
|
2975
|
+
stdio 的秘密形件(变量名被引擎认作凭据名)的值恰等于一只每个子进程都会继承的变量(`PATH` / `HOME` 一类)的值。
|
|
2976
|
+
- **在哪看见**:MCP 的连接期 `wiring_manifest.mcp[]` 行(`status:"failed"`、`errorCode:"credential_unavailable"`、`delivered:"no"`)与调用期 `tool_end.errorCode`;`GET /v1/sessions/:id/mcp` 面板的那一台 `failed`。A2A 这一侧只有文本:会话 A2A 面板 `peers[].cardFetched:false` + `error`,run 内是工具结果的错误文本(没有机读码)。
|
|
2977
|
+
运维日志:本服务的座自己拒时(引用不在表里 / 绑定不符 / 引用种类座不答)一行 warn `peer_seat_refused { protocol, peer, reason }`(`reason` ∈ `handle_not_held` · `binding_mismatch` · `kind_env` · `kind_vault` · `kind_assertion` · `kind_unknown`),不带件值、不带引用 id;因件的形被引擎读器拒的那一台没有这一行,看上面的码 / 文本。
|
|
2978
|
+
- **扣留次序**:引擎把座答里认作凭据的 http 头值与 stdio 秘密形件值记为自己持有的凭据值 —— 服务进程环境里同值的变量不再交给模型可驱动的 host shell(Bash)子进程(MCP stdio 子进程只继承 MCP SDK 的少数默认变量〔`HOME` · `LOGNAME` · `PATH` · `SHELL` · `TERM` · `USER`〕与座给的件,拿不到服务进程环境的其余变量)。座的答案先过读器、放行了才记:
|
|
2979
|
+
被读器拒的形(件值含 CR / LF / NUL、头名不是 HTTP token、两个头名只差大小写、变量名不是标识符形)的值**不进扣留表**,那一台失败而环境里同值的变量照旧交给 host shell 子进程(上一发布版先记后判);MCP 传输自己写的头名在读器之后的协议层才拒,值此时已在表里。名册 `headerRefs` 指向的变量值带尾换行时尤其要去掉那个换行。
|
|
2980
|
+
- **`/metrics` 两只读数**:`peer_registry_entries`(登记表现有条目数)· `peer_registry_holders`(各条目的宿主租约数之和 —— 条目的持有者只有宿主租约;一只租约持有三个条目记三次)。没有过期、没有上限;在飞腿全落定后两只回到名册基线(名册里带件条目的条数)。基线之上持续不回落 = 有作用域没放。
|
|
2981
|
+
- **`principalHeader` 的名**:MCP 条目 `transport.principalHeader` 取传输自己写的头名(上面五个,任何大小写)或引擎的断言头 `connector-assertion`,A2A 条目 `principalHeader` 取 `connector-assertion` ⇒ **新提交 `400 request.field_invalid`**
|
|
2982
|
+
(点名 `mcpServers[i].transport.principalHeader` / `a2aPeers[i].principalHeader`,不回显写的串)。耐久 resume 重放存量体不 4xx:MCP 那一台由引擎在拨号时拒,A2A 那一条对端整条不进(warn `a2a_injection_dropped`)。
|
|
2983
|
+
- **断言头不发送**:引擎的断言头是固定的名 `connector-assertion`、值由对端座作答;本部署没有断言来源,座对这一种恒拒(9.5d)。这说的是 `assertionHeader` 声明本身不产生断言头:调用方自己写在 `headers` 里、名字恰为 `connector-assertion` 的头仍按普通件处理(引擎只在它作 `principalHeader` 时保留这个名)。
|
|
2984
|
+
- **探测口与面板**:`POST /v1/capabilities/mcp/probe` 带 `headers` / `env` 的申报与任务提交走同一条路(件在这次走查的租约下登记,拨号落地即放;同样的件形判;缓存键含件);`GET /v1/capabilities/mcp` 与两张会话面板拨名册声明,递同一只座。
|
|
2985
|
+
- **补偿**:多行值改 base64 或改传文件路径,Secret 文件去掉尾换行;变量名改标识符形;件头名改非协议名;`principalHeader` 换成非协议、非引擎自有的名(例 `x-agent-principal`);秘密形变量别设成与 `PATH` / `HOME` 之类同值。
|
|
2986
|
+
|
|
2987
|
+
**已知缺口(本版披露不修):会话级子代在父腿作用域结束之后首拨 http / stdio、或再发 http 会被座拒。** 引擎持有引用的计数那一半本版不在,座只认宿主租约:一个会话级(后台)子代继承父的、请求体自带的 http / stdio MCP 声明,在父腿结束之后再问 ⇒ 该次发送 / 那一台的挂载 `credential_unavailable`
|
|
2988
|
+
(响亮拒:一行不带值的 `peer_seat_refused`,`reason: handle_not_held`;http 在首次连接与每次发送时问座,stdio 在起子进程时问座 —— 父腿作用域结束之后才首拨的 stdio 子代同样被拒);父腿很快收尾时,子代连自己的挂载都会被座拒。同一腿内(含 cascade 各级、同步腿)、名册声明的服务器(名册件由进程寿命的名册租约持有)与父腿作用域之内已起的 stdio 子进程不受影响;A2A 没有这个形(委派子代不继承父的 A2A 对端)。
|
|
2989
|
+
补偿:请求体带件 http / stdio MCP 的任务别依赖「父腿先结束、子代后调用」,让父腿等子代收尾,或把这类服务器改成名册声明;缺口在引擎持有那一半到货后翻绿。
|
|
2948
2990
|
|
|
2949
2991
|
### 9.6 trace 脱敏的射程:与出站请求体无关
|
|
2950
2992
|
|
|
@@ -3173,7 +3215,9 @@ web-admin 拉取 / fleet 公告 / 凭证续签、WebSearch、对象存储、OTLP
|
|
|
3173
3215
|
(安装树 `node_modules/@sema-agent/core` 不再接受)。命中的处置写进**随版认领表** `docs/core-consumption/ACK-core@<目标>.json`(维护者文件,不随包):
|
|
3174
3216
|
门按 `section` + `key` 整串全等逐键放行被人核过的命中,条目的 `where` 须把这一命中现在的读点列全,读数行 `acked=` 如实带出放行条数;
|
|
3175
3217
|
表里有而读数里没有的条目、读点变了的条目按过期红(`stale=`),表自报的版本或区间下界与本次不符、形坏都是 exit 2;
|
|
3176
|
-
没有通配、没有全局放行旗标,放行面只此一张表(细则在门脚本头注)
|
|
3218
|
+
没有通配、没有全局放行旗标,放行面只此一张表(细则在门脚本头注)。一个发布版本的区间里提了不止一次货时,每次提货各带一份认领表、**首尾相接**:目标那一份的 `from` 指向前一份的版本,
|
|
3219
|
+
最前一份的 `from` 是区间下界;门沿 `from` 从目标那一份逐份往下读,命中按它来自的 core 版本归到那一段的那一份认领,中间缺一份 ⇒ exit 2 点名缺的文件与那一段(缺段 = 这一段的命中谁也没核过);
|
|
3220
|
+
不合并成一份、也不手改 `from`(每一份都是当时人核过的陈述)。
|
|
3177
3221
|
- **core RC 探针**(维护者裁定,2026-09-28):core 出 RC tarball 时直讯本仓(`npm pack` 产物路径 + shasum + `wire-changes/core@<ver>.json` 的 commit),
|
|
3178
3222
|
当拍跑:
|
|
3179
3223
|
```bash
|
|
@@ -3248,13 +3292,16 @@ web-admin 拉取 / fleet 公告 / 凭证续签、WebSearch、对象存储、OTLP
|
|
|
3248
3292
|
十一键老形、手跑的 `chain=-` 行都不是本轮的 —— 没等到本轮的行 ⇒ 退出码 1 并说没出现,不转述别轮的读数。手跑 `release.sh` / `post-publish-gates.sh` 不给标识 = `chain=-`。之后转述门 3.5 的 `PUBLISH` 行;release.sh 红而 tag 已在 ⇒ 立即收尾并指路 `publish-local.sh` + `post-publish-gates.sh`;
|
|
3249
3293
|
绿 ⇒ 等 `GATES456`(窗 = `GATE4_WINDOW_SEC` + 20 min)后转述 `GATE2` / `PUBLISH` / 判决行。退出码见脚本头注(0 = 全绿)。
|
|
3250
3294
|
- **wire 变更机器清单**(7.105.0 起):`node scripts/wire-changes-server.mjs <version>` 生成 `wire-changes/server@<version>.json`
|
|
3251
|
-
(形照 core 的 `wire-changes/core@<ver>.json`:`added` / `removed` / `changed` / `narrowed` + `closedSetMembers` + `breaking`
|
|
3295
|
+
(形照 core 的 `wire-changes/core@<ver>.json`:`added` / `removed` / `changed` / `narrowed` + `closedSetMembers` + `breaking`;另有 `registered` ——
|
|
3296
|
+
早于本版就在 wire 上、本版只是补登记的成员 —— 与 7.138.0 起的 `excluded` 桶〔见下〕)。源 = 契约附录
|
|
3252
3297
|
A.1 ∪ A.1b 错误码(属性 = 状态码)、B.1 能力位 / B.2 `taskSettings` 子键(属性 = 谓词类)、D.3 `engine_notice` 白名单(属性 = `detail`)、
|
|
3253
3298
|
`src/trace/wire-projection-faces.ts` 的 `WIRE_PROJECTION_FACES`;对比上一 tag 与本版(tag 在读 tag,不在读工作树)。源读不懂 ⇒ exit 2
|
|
3254
3299
|
(不产出「零变更」清单)。面表里带 `keys` 声明的面(7.133.0 起:`prompt_assembled` 清单行的十二层,账本行 / turns 块 / trace 帧同一形)
|
|
3255
3300
|
做**键级**比较,与面的增删用同一张表、同一只比较器:删一个键或改了键的值形 / 容器 / 嵌套面 / 由必选变可选 ⇒ `removed` / `narrowed`(`breaking`),
|
|
3256
3301
|
新增键 ⇒ `added`,由可选变必选 ⇒ `changed`;该面此前没有键声明(首次登记)时既有的键进 `registered`,不当本版新上 wire。其余帧面的键集仍由 `coreType`
|
|
3257
|
-
在安装态 core
|
|
3302
|
+
在安装态 core 里展开,生成器看不见它们的键级删改(由提货批的读面 × core 清单求交门与各面的 `_Guard*` 编译钉盯);**core 新长出来的顶层键**(7.138.0 起)改读 core 的随包清单
|
|
3303
|
+
(`node_modules/@sema-agent/core/wire-changes/core@<ver>.json` 的 `typeKeys[].added`,区间 = 上一 tag 的 core 钉到本版的钉):TaskEvent 臂与裸型名面上的新键没登记进 `excluded` ⇒ `added`(默认上 wire);
|
|
3304
|
+
登记进了 `excluded` ⇒ 新的 `excluded` 桶(这个键从未上过 wire,不是收窄,不计 `breaking`);此前被记成 `narrowed` 的就是这一类。嵌套在已有顶层键之下的新成员不在这一源的射程,由自铸登记表登记。随 release commit 提交;查账门(门 1.6)第三腿 `--check` 核它在仓且与生成输出逐字节同,缺席 / 陈旧 ⇒ 红。
|
|
3258
3305
|
`wire-changes/server@7.104.0.json` 是回填的第一份。7.136.0 起 `wire-changes/` 随 npm 包出:装包的人在包内 `wire-changes/server@<ver>.json` 就能读到每一版的清单(生成时清单里的 `text` 过发布面内部编号词表,命中的编号换成 `[ref]`;`sources` 里点名的契约文档不随包)。
|
|
3259
3306
|
- **台账 `refs:` 列建议**:`node scripts/ledger-refs.mjs [--comms-dir <dir>] [--json]` 只读 sema-comms 的 `debts/DEBTS-server.md` /
|
|
3260
3307
|
`PLANS.md`(server 段)/ `bugs/B-*.md`(文件头 `owner:` 格),按「一方点了另一方的号」双向互链,输出每行的 `refs:` 建议值(号按数值认,
|
|
@@ -3424,8 +3471,8 @@ UPDATE session_policy_rev_mark SET rev = 0, gen = gen + 1 WHERE policy_key = '<w
|
|
|
3424
3471
|
下一次工具调用起生效;收不回 operator 写下的那一部分(两边都写过的条目也算):`403 loosen_forbidden`,句子 `a non-operator session-rule write may not loosen what an operator wrote; …`
|
|
3425
3472
|
(7.134.x 及以前的句子是 `… may only tighten …`,按句子匹配的脚本改读码)。operator 写一次就把整行变成 operator 的。`operatorRules` 由引擎铸,客户端改规则时**不要**回传它。
|
|
3426
3473
|
|
|
3427
|
-
**行自带文法戳。** 7.129.0 起每一行会话规则自带规则文法戳 `grammar`(写口判官盖引擎当前的文法:7.129.0–7.131.x 写下的行是 `1`,7.132.0–7.134.x 写下的行是 `2`,7.135.0–7.136.x 写下的行是 `4`,7.137.0 起写下的行是 `
|
|
3428
|
-
早先写下的行保留自己的戳、引擎按它的戳读;店整只存、读回原样交出;7.134.x 及更早的引擎读不了戳 3 / 4 的行、7.136.x 及更早的读不了戳 5 的行 —— 整行拒、那条会话每一次调用都拒,升级序见 MIGRATION
|
|
3474
|
+
**行自带文法戳。** 7.129.0 起每一行会话规则自带规则文法戳 `grammar`(写口判官盖引擎当前的文法:7.129.0–7.131.x 写下的行是 `1`,7.132.0–7.134.x 写下的行是 `2`,7.135.0–7.136.x 写下的行是 `4`,7.137.x 写下的行是 `5`,钉引擎 7.57.0 起写下的行是 `6`(裸工具名成为整工具规则);
|
|
3475
|
+
早先写下的行保留自己的戳、引擎按它的戳读;店整只存、读回原样交出;7.134.x 及更早的引擎读不了戳 3 / 4 的行、7.136.x 及更早的读不了戳 5 的行、7.137.x 及更早的读不了戳 6 的行 —— 整行拒、那条会话每一次调用都拒,升级序见 MIGRATION(先升读者、再升写者))—— `GET` / `PUT` 回包的 `rules` 与同步导出的
|
|
3429
3476
|
记录里多这一个键。客户端改规则时只写三只桶,不要把读回的 `rev` / `gen` / `grammar` / `operatorRules` 一起回传:带着 `rev` 却没有 `grammar` 的值引擎按存量行的文法(0)读,括号形 allow 条目答
|
|
3430
3477
|
`400 rules.inert_entry`(`reason: "earlier_grammar"`;出路在句子里);`grammar` 坏或比引擎新 ⇒ `400 rules.invalid_shape`(`field: "grammar"`)。
|
|
3431
3478
|
|
package/dist/approval-card.d.ts
CHANGED
|
@@ -84,6 +84,7 @@ export declare const RuleOfferSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
84
84
|
rule: z.ZodString;
|
|
85
85
|
match: z.ZodEnum<{
|
|
86
86
|
name: "name";
|
|
87
|
+
tool: "tool";
|
|
87
88
|
host: "host";
|
|
88
89
|
path: "path";
|
|
89
90
|
exact: "exact";
|
|
@@ -102,6 +103,7 @@ export declare const RuleOfferSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
102
103
|
rule: z.ZodString;
|
|
103
104
|
match: z.ZodEnum<{
|
|
104
105
|
name: "name";
|
|
106
|
+
tool: "tool";
|
|
105
107
|
host: "host";
|
|
106
108
|
path: "path";
|
|
107
109
|
exact: "exact";
|
|
@@ -552,21 +554,21 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
552
554
|
rememberRefused: z.ZodOptional<z.ZodLiteral<true>>;
|
|
553
555
|
approvalCard: z.ZodOptional<z.ZodEnum<{
|
|
554
556
|
question: "question";
|
|
555
|
-
plan: "plan";
|
|
556
557
|
skill: "skill";
|
|
558
|
+
plan: "plan";
|
|
557
559
|
shell: "shell";
|
|
558
560
|
workflow: "workflow";
|
|
559
|
-
|
|
561
|
+
fetch: "fetch";
|
|
560
562
|
"file-write": "file-write";
|
|
563
|
+
"file-edit": "file-edit";
|
|
561
564
|
"notebook-edit": "notebook-edit";
|
|
562
|
-
fetch: "fetch";
|
|
563
565
|
generic: "generic";
|
|
564
566
|
}>>;
|
|
565
567
|
inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
|
|
566
568
|
allowRuleShadowed: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
567
569
|
member: z.ZodEnum<{
|
|
568
|
-
hook: "hook";
|
|
569
570
|
skill: "skill";
|
|
571
|
+
hook: "hook";
|
|
570
572
|
deployment: "deployment";
|
|
571
573
|
request: "request";
|
|
572
574
|
persisted: "persisted";
|
|
@@ -579,6 +581,7 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
579
581
|
rule: z.ZodString;
|
|
580
582
|
match: z.ZodEnum<{
|
|
581
583
|
name: "name";
|
|
584
|
+
tool: "tool";
|
|
582
585
|
host: "host";
|
|
583
586
|
path: "path";
|
|
584
587
|
exact: "exact";
|
|
@@ -597,6 +600,7 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
597
600
|
rule: z.ZodString;
|
|
598
601
|
match: z.ZodEnum<{
|
|
599
602
|
name: "name";
|
|
603
|
+
tool: "tool";
|
|
600
604
|
host: "host";
|
|
601
605
|
path: "path";
|
|
602
606
|
exact: "exact";
|
|
@@ -665,8 +669,8 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
665
669
|
}, z.core.$strict>>>;
|
|
666
670
|
personalRuleDotsAbsent: z.ZodOptional<z.ZodCustom<AskEvidenceAbsence, AskEvidenceAbsence>>;
|
|
667
671
|
}, z.core.$strict>>;
|
|
668
|
-
askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "
|
|
669
|
-
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "
|
|
672
|
+
askClass: z.ZodOptional<z.ZodCustom<"probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
|
|
673
|
+
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
|
|
670
674
|
fromSubagent: z.ZodOptional<z.ZodLiteral<true>>;
|
|
671
675
|
sourceTaskId: z.ZodOptional<z.ZodString>;
|
|
672
676
|
sourceAgentName: z.ZodOptional<z.ZodString>;
|
|
@@ -704,21 +708,21 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
704
708
|
rememberRefused: z.ZodOptional<z.ZodLiteral<true>>;
|
|
705
709
|
approvalCard: z.ZodOptional<z.ZodEnum<{
|
|
706
710
|
question: "question";
|
|
707
|
-
plan: "plan";
|
|
708
711
|
skill: "skill";
|
|
712
|
+
plan: "plan";
|
|
709
713
|
shell: "shell";
|
|
710
714
|
workflow: "workflow";
|
|
711
|
-
|
|
715
|
+
fetch: "fetch";
|
|
712
716
|
"file-write": "file-write";
|
|
717
|
+
"file-edit": "file-edit";
|
|
713
718
|
"notebook-edit": "notebook-edit";
|
|
714
|
-
fetch: "fetch";
|
|
715
719
|
generic: "generic";
|
|
716
720
|
}>>;
|
|
717
721
|
inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
|
|
718
722
|
allowRuleShadowed: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
719
723
|
member: z.ZodEnum<{
|
|
720
|
-
hook: "hook";
|
|
721
724
|
skill: "skill";
|
|
725
|
+
hook: "hook";
|
|
722
726
|
deployment: "deployment";
|
|
723
727
|
request: "request";
|
|
724
728
|
persisted: "persisted";
|
|
@@ -731,6 +735,7 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
731
735
|
rule: z.ZodString;
|
|
732
736
|
match: z.ZodEnum<{
|
|
733
737
|
name: "name";
|
|
738
|
+
tool: "tool";
|
|
734
739
|
host: "host";
|
|
735
740
|
path: "path";
|
|
736
741
|
exact: "exact";
|
|
@@ -749,6 +754,7 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
749
754
|
rule: z.ZodString;
|
|
750
755
|
match: z.ZodEnum<{
|
|
751
756
|
name: "name";
|
|
757
|
+
tool: "tool";
|
|
752
758
|
host: "host";
|
|
753
759
|
path: "path";
|
|
754
760
|
exact: "exact";
|
|
@@ -817,8 +823,8 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
817
823
|
}, z.core.$strict>>>;
|
|
818
824
|
personalRuleDotsAbsent: z.ZodOptional<z.ZodCustom<AskEvidenceAbsence, AskEvidenceAbsence>>;
|
|
819
825
|
}, z.core.$strict>>;
|
|
820
|
-
askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "
|
|
821
|
-
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "
|
|
826
|
+
askClass: z.ZodOptional<z.ZodCustom<"probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
|
|
827
|
+
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "probe" | "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
|
|
822
828
|
fromSubagent: z.ZodOptional<z.ZodLiteral<true>>;
|
|
823
829
|
sourceTaskId: z.ZodOptional<z.ZodString>;
|
|
824
830
|
sourceAgentName: z.ZodOptional<z.ZodString>;
|
|
@@ -933,7 +939,8 @@ export declare function buildApprovalRequestFrame(input: {
|
|
|
933
939
|
/**
|
|
934
940
|
* 🔴 **呈卡帧的活面事实座**(呈卡腿上旧族退役之后,开卡帧的全部事实都由本族承载)。
|
|
935
941
|
*
|
|
936
|
-
*
|
|
942
|
+
* 这十一个座是活卡帧 `tool_approval` 上有、而卡(`ApprovalCardSchema`,`card_json` 的耐久信封)上**没有**的那几位(`approvalCard` 7.136.0 起也在卡上,见本注末段;
|
|
943
|
+
* `requestedBy` = 扩展经 `$.tool.call` 自己发起的调用是谁要的,部署座装运维声明的 mod 包之后可达):
|
|
937
944
|
* 卡外的事实此前只骑活卡帧,呈卡腿的消费方靠「两帧按 approvalId 合读」拿到它们。呈卡腿自此只发本族帧 ⇒ 它们挪到**活铸**的
|
|
938
945
|
* 呈卡帧顶层,同名同型同值 —— 值取自同一只帧对象(活卡帧的那一次铸定,`tool-approval.ts` 的 `askBroadcast`),本仓不另算一遍。
|
|
939
946
|
*
|
|
@@ -946,7 +953,7 @@ export declare function buildApprovalRequestFrame(input: {
|
|
|
946
953
|
* 同一次读定、同值)。按上一句的规矩它该离表(活铸帧顶层这一份退役 —— wire BREAKING,下游 sdk 的孪生表同改),本版按 additive 交付、未退役:
|
|
947
954
|
* 一个事实两处读,登记为待收的债,收法 = 离表 + 消费方改读 `card.approvalCard`,不是在这里加第三处。
|
|
948
955
|
*/
|
|
949
|
-
export declare const APPROVAL_REQUEST_LIVE_FACT_KEYS: readonly ["mandated", "mandate", "origin", "boundGrantDigest", "boundGrants", "classifierNoRuling", "boundGrantAbsence", "approvalCard", "readRootCandidate", "probeReason"];
|
|
956
|
+
export declare const APPROVAL_REQUEST_LIVE_FACT_KEYS: readonly ["mandated", "mandate", "origin", "boundGrantDigest", "boundGrants", "classifierNoRuling", "boundGrantAbsence", "approvalCard", "readRootCandidate", "probeReason", "requestedBy"];
|
|
950
957
|
/** 呈卡帧活面事实座的类型面 = 活卡帧同名座的 `Pick`(同型由构造保证,不手抄)。 */
|
|
951
958
|
export type ApprovalRequestLiveFacts = Pick<ToolApprovalFrame, (typeof APPROVAL_REQUEST_LIVE_FACT_KEYS)[number]>;
|
|
952
959
|
/**
|
package/dist/approval-card.js
CHANGED
package/dist/audit.js
CHANGED
|
@@ -126,6 +126,7 @@ const MESSAGE_READ_TREATMENT = {
|
|
|
126
126
|
user: {
|
|
127
127
|
role: "verbatim", content: "verbatim", timestamp: "verbatim", enginePrefixChars: "verbatim", engineSegments: "verbatim",
|
|
128
128
|
engineMinted: "verbatim", engineNoteKey: "verbatim", provenance: "verbatim", actor: "verbatim",
|
|
129
|
+
runOrigin: "verbatim",
|
|
129
130
|
taskId: "verbatim",
|
|
130
131
|
attachment: "verbatim",
|
|
131
132
|
},
|
|
@@ -28,18 +28,7 @@ export declare function createBudgetAndTracing(ctx: BudgetTracingCtx): {
|
|
|
28
28
|
fleetUsage: import("../fleet-client.js").FleetUsageBins | undefined;
|
|
29
29
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
30
30
|
tracer: import("@sema-agent/core").TracerHook;
|
|
31
|
-
sideQueryAccounting: (
|
|
32
|
-
model: string;
|
|
33
|
-
usage?: {
|
|
34
|
-
input?: number;
|
|
35
|
-
output?: number;
|
|
36
|
-
cacheRead?: number;
|
|
37
|
-
cacheWrite?: number;
|
|
38
|
-
cost?: {
|
|
39
|
-
total?: number;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
}) => void;
|
|
31
|
+
sideQueryAccounting: import("../budget.js").SideQueryAccounting;
|
|
43
32
|
toolResultStore: import("../plugins/store-backend.js").ToolResultStoreFull | undefined;
|
|
44
33
|
sessionPolicyStore: import("@sema-agent/core").SessionPolicyStore | undefined;
|
|
45
34
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|