@sema-agent/sdk 16.2.0 → 16.3.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/README.md +49 -0
- package/dist/errors.d.ts +5 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +5 -1
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +8 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/resources/runs.d.ts +6 -0
- package/dist/resources/runs.d.ts.map +1 -1
- package/dist/resources/runs.js +6 -0
- package/dist/resources/runs.js.map +1 -1
- package/dist/resources/tasks.d.ts +7 -1
- package/dist/resources/tasks.d.ts.map +1 -1
- package/dist/resources/tasks.js +7 -1
- package/dist/resources/tasks.js.map +1 -1
- package/dist/resources/tool-approvals.d.ts +68 -11
- package/dist/resources/tool-approvals.d.ts.map +1 -1
- package/dist/resources/tool-approvals.js +33 -1
- package/dist/resources/tool-approvals.js.map +1 -1
- package/dist/settings.d.ts +20 -10
- package/dist/settings.d.ts.map +1 -1
- package/dist/types.d.ts +41 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/openapi.yaml +158 -50
- package/package.json +1 -1
package/openapi.yaml
CHANGED
|
@@ -417,7 +417,7 @@ paths:
|
|
|
417
417
|
prepare-time refusal code that HAS a status in the server's per-code triage table (`resume_at.*` — `resume_at.not_found` is 404, the rest 422 —, governance codes,
|
|
418
418
|
`rewind.store_unconfigured` / `rewind.capture_disabled` / `rewind.child_scope_unsupported` / `rewind_snapshot.unresolvable`, the
|
|
419
419
|
registered `config.*` codes incl. the three roster-bound ones and — server >= 7.116.0 — `config.invalid_checkpoint_store` (400) and
|
|
420
|
-
`config.user_invoked_skill_unknown` (400: top-level `userInvokedSkills` named a skill this run does not carry), `corrupt_session`; codes outside the table, e.g. `rewind.invalid_spec`, stay
|
|
420
|
+
`config.user_invoked_skill_unknown` (400: top-level `userInvokedSkills` named a skill this run does not carry) and — server >= 7.117.0 — `config.image_invalid` (400: an inline image failed the engine's byte admission; `error` starts with `TaskSpec.images: `), `corrupt_session`; codes outside the table, e.g. `rewind.invalid_spec`, stay
|
|
421
421
|
200 with a failed body) answers its 4xx / 5xx ERROR BODY only when the whole submission did ZERO WORK (cumulative
|
|
422
422
|
`stats.turns === 0` AND `stats.tokens === 0` — the common case: nothing billed, not idempotency-cached). When a
|
|
423
423
|
`verify` / `cascade` run's earlier tier already ran turns and only the last tier is refused, the SAME code arrives
|
|
@@ -886,6 +886,13 @@ paths:
|
|
|
886
886
|
⚠️ Against a server 7.19.0–7.22.0 the OLD caveat applies verbatim: only the parked legs dedupe —
|
|
887
887
|
a lost 200 retried with the same key injects TWICE with byte-identical receipts; treat a lost 200
|
|
888
888
|
there as "outcome unknown", never "safe to retry".
|
|
889
|
+
🔴 server >= 7.117.0 — TWO MORE 409 answers on a TERMINAL run (the `parked_for_wake` leg), refused BEFORE the wake card is minted
|
|
890
|
+
(no card is minted; the row is untouched; on 7.116.x this was a 202 `parked_for_wake` followed by a refusal at `/wake`, i.e. a card that could
|
|
891
|
+
never be redeemed): when the stored submit body of this session is one this version no longer replays — errorCode
|
|
892
|
+
`checkpoint.unsupported_version` (`retriable: true` = the card is still pending / cancellable, NOT "a retry will succeed"; the stored body carries
|
|
893
|
+
`settings.permissions.allow` under an earlier reading — list or statement era) or errorCode `resume_blocked_by_policy` (`blockedBy: "request.field_invalid"`;
|
|
894
|
+
the stored skill `disallowedTools` carries an entry the engine now reads as nothing). Both answers are word-for-word the ones `POST /v1/sessions/{sessionId}/wake`
|
|
895
|
+
gives for the same body. Way out: cancel the task and resubmit as a new one (with the entry fixed). The SDK does not retry them (409 is not in the retry set).
|
|
889
896
|
content:
|
|
890
897
|
application/json:
|
|
891
898
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
@@ -7187,6 +7194,13 @@ components:
|
|
|
7187
7194
|
description: 'core 5.11.0: extra READ-ONLY absolute host paths — read fence only (classify read-boundary auto-allow + read_file/grep containment); writes to the same dirs are still refused. Same shape/400 rules as additionalDirectories; servers <6.6.0 silently ignore (harmless additive).'
|
|
7188
7195
|
images:
|
|
7189
7196
|
type: array
|
|
7197
|
+
description: >
|
|
7198
|
+
Image input: `{ data, mimeType }` (inline base64) or `{ url }`. 🔴 INLINE-ARM ADMISSION (server >= 7.117.0 / core 7.42.0): `mimeType` must be one of `image/png` /
|
|
7199
|
+
`image/jpeg` / `image/gif` / `image/webp` (the API's type word, not a file extension), the decoded bytes must carry the DECLARED type's file signature, and the decoded size must
|
|
7200
|
+
not exceed 5 MiB — otherwise the engine refuses BEFORE the first model call (after the UserPromptSubmit hook; not one model token spent) with 400 `config.image_invalid`, whose
|
|
7201
|
+
`error` starts with `TaskSpec.images: `. Before 7.117.0 such an image was sent as-is to the model provider and the whole first request failed there (no code to branch on).
|
|
7202
|
+
A base64 string longer than 5 242 880 characters (the model API's 5 MB image cap; the server reads the engine's exported constant) is NOT this code: the submit gate refuses it first
|
|
7203
|
+
with 413 `request.payload_too_large` (zero model calls, no submit hook, no run row). The `{ url }` arm is unchanged. The model must accept image input (`ModelInfo.vision`; absent = unknown, send anyway).
|
|
7190
7204
|
items:
|
|
7191
7205
|
oneOf:
|
|
7192
7206
|
- type: object
|
|
@@ -7330,9 +7344,20 @@ components:
|
|
|
7330
7344
|
the delivery lane, so raising it only helps a model whose declared window is below 200 000 tokens.
|
|
7331
7345
|
The engine's own twin code `config.skill_listing_budget_invalid` (400) is NOT reachable through this
|
|
7332
7346
|
submit leg today — it belongs to callers that build a `TaskSpec` directly.
|
|
7333
|
-
🔴 `permissions.allow`
|
|
7334
|
-
|
|
7335
|
-
|
|
7347
|
+
🔴 `permissions.allow` — THE READING DEPENDS ON THE SERVER GENERATION (probe `capabilities.settings.permissions`; an absent bit = the older generation).
|
|
7348
|
+
server >= 7.117.0 (`allowLayer === true`, core 7.42.0): the WHOLE list goes to the engine's allow layer and a listed call is NOT ASKED — the engine's ordinary and
|
|
7349
|
+
"nobody stated it" questions are cleared, built-in write gates and shell checks included (like the reference implementation's `permissions.allow`); content forms
|
|
7350
|
+
(`Bash(git:*)`, `Read(//dir/**)`) are accepted; entries the engine reads as nothing (`*`, write-path forms such as `Edit(src/**)`, domain forms, names with whitespace) are NOT
|
|
7351
|
+
refused — the run opens with an `engine_notice` `permission.allowed_tool_not_granted`. Any layer's deny / ask rule, operator `APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` /
|
|
7352
|
+
`MANUAL_MODE_SHELL_GATE=always`, write protection, governance, a hook's ask and plan-mode asks still ask (a matching `request` member then shows as `allowRuleShadowed` on the
|
|
7353
|
+
card). The submit gate judges only the shape (array of strings, at most 1000 entries => 400) and the NAMES (the same judge and the same sentence as `deny` / `ask`: a retired name,
|
|
7354
|
+
an unprefixed short name, or a protocol name whose server segment cannot be minted / is missing / is a wildcard (`mcp__*`) is a whole-request 422) — never the content.
|
|
7355
|
+
🔴 THE 422 SENTENCE (server >= 7.117.0): `error` starts with `request settings cannot be applied as written: ` (<= 7.116.x: a different sentence that said tighten-only — all three
|
|
7356
|
+
buckets share this exit, and the old head misled a caller writing a tightening rule and lied about the allow bucket). Do NOT dispatch on the sentence: it carries no code of its own, so
|
|
7357
|
+
`errorCode` is the status-derived coarse code `request.unprocessable`.
|
|
7358
|
+
The skill lists (`skills[].allowedTools`) read exactly like this bucket from 7.117.0 on.
|
|
7359
|
+
Server 7.115.0–7.116.x (`allowGrant` without `allowLayer`): `permissions.allow` IS A STATEMENT, NOT A WHITELIST — an absent `allowGrant` is a server <= 7.114.x that reads the bucket
|
|
7360
|
+
as a list, so put nothing in it there. The bucket is compiled by the SAME rule compiler as `deny` / `ask`: a hit is a
|
|
7336
7361
|
reasoned allow = "somebody stated it" (it answers an MCP / A2A server-tool call nobody stated; without it an
|
|
7337
7362
|
ask-class mode raises a card, and with no approval surface the call is refused); a miss states nothing and the call is
|
|
7338
7363
|
judged as usual — a tool off the list is NOT refused any more (<= 7.114.x refused it). It does NOT skip the question
|
|
@@ -9414,22 +9439,28 @@ components:
|
|
|
9414
9439
|
settings:
|
|
9415
9440
|
type: object
|
|
9416
9441
|
description: >
|
|
9417
|
-
🔴 server >= 7.115.0
|
|
9418
|
-
server give `settings.permissions.allow` on a task submit"
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
`
|
|
9425
|
-
(
|
|
9442
|
+
🔴 server >= 7.115.0, ALWAYS present: `{ permissions: { allowGrant: true } }`; server >= 7.117.0 adds `allowLayer: true` to `permissions` — the VERSION bits for
|
|
9443
|
+
"which reading does this server give `settings.permissions.allow` on a task submit" (both constant `true`, never vary with the deployment: the single-user
|
|
9444
|
+
and `REQUIRE_PRINCIPAL=true` forms carry the same value). Read three levels: `settings` -> `permissions` -> <bit>; an absent / non-boolean bit = a server without it.
|
|
9445
|
+
`permissions.allowGrant === true` (>= 7.115.0) = the `allow` bucket is read as allow RULES, not as a list (a tool off the list is no longer refused).
|
|
9446
|
+
`permissions.allowLayer === true` (>= 7.117.0, core 7.42.0) = the server hands the WHOLE `allow` list to the engine's allow layer: a listed call is NOT ASKED (the engine's
|
|
9447
|
+
ordinary and "nobody stated it" questions are cleared — built-in write gates / shell checks included, like the reference implementation's `permissions.allow`); content forms
|
|
9448
|
+
(`Bash(git:*)`, `Read(//dir/**)`) are accepted; entries the engine reads as nothing (`*`, write-path / domain forms, names with whitespace) are NOT refused — the run opens with an
|
|
9449
|
+
`engine_notice` `permission.allowed_tool_not_granted`; any layer's deny / ask rule, operator `APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` / shell floor / write protection /
|
|
9450
|
+
governance, a hook's ask and plan-mode asks still ask (a matching member then shows as `allowRuleShadowed` on the card). The submit gate judges only the shape and the NAMES (retired
|
|
9451
|
+
name / unprefixed short name / unmintable protocol server segment => 422, at most 1000 entries => 400) — never the content.
|
|
9452
|
+
🔴 ABSENT `allowLayer` with `allowGrant` present = a 7.115.0–7.116.x server: allow is a STATEMENT (it does not clear the engine's own write gate / shell checks; a content form
|
|
9453
|
+
is a whole-request 422). ABSENT KEY altogether (no `settings`) = an older server (<= 7.114.x), which read `allow` as a WHITELIST (everything off the list refused) — do not put
|
|
9454
|
+
anything in the allow bucket there. NOT the same bit as `taskSettings.permissions` (unchanged, still a boolean: "this server accepts the `settings.permissions` face"). The
|
|
9455
|
+
deployment-level "who stated what" (operator env `APPROVAL_GRANT`) is on the operator diagnostics face (`serverGates.approvalGrant`), not here.
|
|
9426
9456
|
additionalProperties: true
|
|
9427
9457
|
properties:
|
|
9428
9458
|
permissions:
|
|
9429
9459
|
type: object
|
|
9430
9460
|
additionalProperties: true
|
|
9431
9461
|
properties:
|
|
9432
|
-
allowGrant: { type: boolean, description: 'Constant `true` on server >= 7.115.0: `settings.permissions.allow` is read as allow RULES
|
|
9462
|
+
allowGrant: { type: boolean, description: 'Constant `true` on server >= 7.115.0: `settings.permissions.allow` is read as allow RULES, not as a list. The whole `settings` key being absent = an older server.' }
|
|
9463
|
+
allowLayer: { type: boolean, description: 'Constant `true` on server >= 7.117.0 (core 7.42.0): the whole `settings.permissions.allow` list goes to the engine allow layer (listed calls are not asked; content forms accepted; entries read as nothing get an `engine_notice` `permission.allowed_tool_not_granted`). Absent = a server without it (7.115.0–7.116.x: allow is a statement; older: a list).' }
|
|
9433
9464
|
memoryWrite:
|
|
9434
9465
|
type: boolean
|
|
9435
9466
|
description: >
|
|
@@ -10014,8 +10045,9 @@ components:
|
|
|
10014
10045
|
🔴 server >= 7.116.0 (core 7.41.0): a skill carries two TOOL LISTS, `allowedTools` / `disallowedTools` — the
|
|
10015
10046
|
run-scoped ALLOW-RULE and DENY-RULE source of the skill once it is activated. NOT a fence (<= 7.115.x the engine read
|
|
10016
10047
|
the skill's tool list as "only these"): unlisted tools are judged as usual, listed ones are not asked about for the rest
|
|
10017
|
-
of the run
|
|
10018
|
-
release the engine's own write gate / shell ordinary asks on built-in tools).
|
|
10048
|
+
of the run. On server 7.116.x that made it WIDER than `settings.permissions.allow` (then a statement that did not
|
|
10049
|
+
release the engine's own write gate / shell ordinary asks on built-in tools); server >= 7.117.0 reads the two request-level
|
|
10050
|
+
allow sources the SAME way (see `capabilities.settings.permissions.allowLayer`). Probe `capabilities.skillToolLists`
|
|
10019
10051
|
(absent = an old server that accepts the keys on a top-level skill and silently ignores them). The skill's `manifest`
|
|
10020
10052
|
key is RETIRED: any value on a top-level skill is a 400 `request.field_invalid` ("skill.manifest was retired in core
|
|
10021
10053
|
7.41.0 — …"; rewrite `manifest.allowTools` to `allowedTools`; `allowPaths` has no replacement), and on a delegated
|
|
@@ -10032,21 +10064,28 @@ components:
|
|
|
10032
10064
|
server >= 7.116.0. The skill's run-scoped ALLOW-RULE source (permission-rule spellings: a tool name,
|
|
10033
10065
|
`mcp__<server>` / `mcp__<server>__*`; `*`, write paths and domain forms grant nothing). Once the skill is activated
|
|
10034
10066
|
(named in top-level `userInvokedSkills` — no `Skill` card — or activated by the model and the card approved) the
|
|
10035
|
-
listed tools are not asked about for the rest of the run: it clears the engine's ordinary and "nobody stated it" asks
|
|
10036
|
-
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
|
|
10067
|
+
listed tools are not asked about for the rest of the run: it clears the engine's ordinary and "nobody stated it" asks;
|
|
10068
|
+
deny / ask rules, `APPROVAL_REQUIRE`, `APPROVAL_NEVER_AUTO`, the shell floor, write protection and plan-mode asks are not cleared.
|
|
10069
|
+
NOT a fence: unlisted tools are judged as usual. Versus `settings.permissions.allow`: on server 7.116.x this list was WIDER (that bucket
|
|
10070
|
+
was then only a statement); server >= 7.117.0 reads the two the SAME way, entry for entry (entries the engine reads as nothing get an
|
|
10071
|
+
`engine_notice` `permission.allowed_tool_not_granted`). A non-string-array is a 400 `request.field_invalid`; a protocol name whose server
|
|
10072
|
+
segment cannot be minted / is missing / is a wildcard (`mcp__*`) is a 400 too, and from 7.117.0 so is a retired name / unprefixed short
|
|
10073
|
+
name (the name layer is judged by the same judge as the allow bucket) and a list of more than 1000 entries (top-level `skills[]` and
|
|
10074
|
+
`agents[].skills[]` judge identically). Probe `capabilities.skillToolLists`.
|
|
10040
10075
|
disallowedTools:
|
|
10041
10076
|
type: array
|
|
10042
10077
|
items: { type: string }
|
|
10043
10078
|
description: >
|
|
10044
10079
|
server >= 7.116.0. The skill's run-scoped DENY-RULE source (same grammar / gates / probe as `allowedTools`): once the skill
|
|
10045
10080
|
is activated these tools are refused for the run (no execution, no card; `tool_end.gate.disposition` is
|
|
10046
|
-
`{ kind: "denied", deniedBy: "policy" }`)
|
|
10047
|
-
|
|
10048
|
-
|
|
10049
|
-
|
|
10081
|
+
`{ kind: "denied", deniedBy: "policy" }`); write-path forms and command rules compile into deny rows too.
|
|
10082
|
+
🔴 server >= 7.117.0: an entry the engine reads as nothing (`*`, a domain form `WebFetch(domain:…)`, a protocol name with a wildcard, a name with
|
|
10083
|
+
whitespace or malformed) is refused AT SUBMIT — 400 `request.field_invalid`, `error` = `skill.disallowedTools entry "<entry>" reads as nothing (<reason>): <how to write it>`
|
|
10084
|
+
(delegated level: prefix `agents[<i>]: skills[<j>]: `), top-level `skills[]` and `agents[].skills[]` alike — because an entry that looks like a refusal but refuses nothing is
|
|
10085
|
+
worse than none (<= 7.116.x accepted it with only an operator-audience notice that was not sent to the session stream; that code is now `permission.allowed_tool_not_granted`,
|
|
10086
|
+
user audience, on the session stream). 🔴 The resume legs judge the stored body the same way: a parked task whose stored skill `disallowedTools` carries such an entry answers
|
|
10087
|
+
409 `resume_blocked_by_policy` (`blockedBy: "request.field_invalid"`, same sentence) BEFORE the claim — row and card untouched; a terminal run's `POST /v1/runs/{taskId}/steer`
|
|
10088
|
+
answers it before minting the wake card. Why: engine 7.41 trimmed whitespace (`"Bash "` was a working deny), engine 7.42 reads verbatim (reads as nothing). The allow side does not refuse.
|
|
10050
10089
|
|
|
10051
10090
|
McpServerSpec:
|
|
10052
10091
|
type: object
|
|
@@ -10788,16 +10827,17 @@ components:
|
|
|
10788
10827
|
baseUrl/apiKey/headers (the service strips them).
|
|
10789
10828
|
# 🔴 封闭 + required 补铸造点(census 批2 第三段,2026-07-30):铸造点 `routes/capabilities.ts`
|
|
10790
10829
|
# 是逐键字面量投影(白名单,不是透传——「open set」旧注不成立,新键要先过这道 spec)。core Model 类型
|
|
10791
|
-
# 里 id/provider/reasoning
|
|
10792
|
-
#
|
|
10793
|
-
|
|
10830
|
+
# 里 id/provider/reasoning 都是必填 ⇒ 四键无条件;contextWindow/maxOutputTokens 0/缺省即省略,
|
|
10831
|
+
# supportedEffortLevels 仅 reasoning 模型。🔴 server 7.117.0 起 `vision` 是三态(收 / 不收 / 没声明 `input`),
|
|
10832
|
+
# 没声明 ⇒ 键缺席 ⇒ 不再是必有键(此前由 `input` 恒算成布尔,对没声明的条目报 false)。
|
|
10833
|
+
required: [name, id, provider, reasoning]
|
|
10794
10834
|
additionalProperties: false
|
|
10795
10835
|
properties:
|
|
10796
10836
|
name: { type: string, description: 'the @mention handle (user-pickable model name).' }
|
|
10797
10837
|
id: { type: string, description: 'underlying model id (display, e.g. deepseek-v4-pro).' }
|
|
10798
10838
|
provider: { type: string }
|
|
10799
10839
|
reasoning: { type: boolean, description: 'a reasoning-tier model (picker can badge it).' }
|
|
10800
|
-
vision: { type: boolean, description: 'accepts image input.' }
|
|
10840
|
+
vision: { type: boolean, description: 'Whether this catalog row accepts image input — THREE states (server >= 7.117.0; before it a row that declared no `input` reported `false`): `true` = the row declares `input` and it contains "image"; `false` = declares `input` without it; ABSENT = the row declared no `input` (a hand-written catalog entry; the env lane and the config-center lane always declare it). ABSENT means UNKNOWN, not false: treat it as "send the image anyway and tell the user", do not read it as `false` and block the image locally — the server hands the image to the model for that same row at run time. Only an explicit `false` justifies "this model does not take images".' }
|
|
10801
10841
|
contextWindow: { type: integer, description: 'E4 (SHIPPED) — context-window token DENOMINATOR for the %-used gauge; omitted when unknown.' }
|
|
10802
10842
|
maxOutputTokens: { type: integer, description: 'E4 (SHIPPED) — single-call max output tokens; omitted when unknown.' }
|
|
10803
10843
|
supportedEffortLevels:
|
|
@@ -12260,6 +12300,16 @@ components:
|
|
|
12260
12300
|
toolName: { type: string }
|
|
12261
12301
|
summary: { type: string }
|
|
12262
12302
|
touchedPaths: {}
|
|
12303
|
+
allowRuleShadowed:
|
|
12304
|
+
type: array
|
|
12305
|
+
items: { $ref: '#/components/schemas/AllowRuleShadow' }
|
|
12306
|
+
description: >
|
|
12307
|
+
server >= 7.117.0 (core 7.42.0): the DURABLE dual of `ToolApprovalFrame.allowRuleShadowed` — the allow-layer members that matched this call
|
|
12308
|
+
and could not clear its ask (same shape and semantics; entries are secret-redacted again at the server's read boundary). Passed through whole
|
|
12309
|
+
on `GET /v1/approvals` and `/v1/approvals/stream`. Absent != "you have no rule". 🔴 The old key `shadowedRule` (a string, server <= 7.116.x)
|
|
12310
|
+
is RETIRED: the SQL backend rewrote its parked rows once at the 7.117.0 boot to `[{ member: "persisted", entries: [<old value>] }]`, but the
|
|
12311
|
+
file backend's pre-upgrade parked rows and run results already on disk (`checkpointGate.riskDescriptor`) keep the old key verbatim
|
|
12312
|
+
(text still redacted, no structured disclosure) — a consumer reading those must still tolerate the old string.
|
|
12263
12313
|
# server 7.16.0 [3684]② — durable 队列行归因两键(与活卡 tool_approval 帧的同名键语义同族、判据不同源;
|
|
12264
12314
|
# 两条腿对同一只 ask 的在场性可以不一致,两侧都只认在场、都禁把缺席读成否定)。
|
|
12265
12315
|
ruleSuggestions:
|
|
@@ -13628,6 +13678,8 @@ components:
|
|
|
13628
13678
|
`not_found.resource` / `request.unprocessable` / `capability.unavailable` …). ALWAYS PRESENT on server >= 7.104.0
|
|
13629
13679
|
(S-607); before that it was absent when the original refusal carried no code. SDK:
|
|
13630
13680
|
`ResumeBlockedByPolicyError.blockedBy` (`undefined` when the key is absent or not a string — never defaulted).
|
|
13681
|
+
server >= 7.117.0 adds a third fold source: a stored skill `disallowedTools` entry the engine now reads as nothing (the submit leg's 400 `request.field_invalid` sentence)
|
|
13682
|
+
⇒ `blockedBy: "request.field_invalid"`, refused before the claim; the terminal-run steer leg answers it before minting the wake card.
|
|
13631
13683
|
|
|
13632
13684
|
ResumeLegConflictError:
|
|
13633
13685
|
description: >
|
|
@@ -15905,29 +15957,45 @@ components:
|
|
|
15905
15957
|
requiresRealApproval / shadowed / hook-produced / inherited-unresolved / ancestor-resolved /
|
|
15906
15958
|
anonymous asks. Absence reads as "THIS CARD has no such option", never as "this deployment has no
|
|
15907
15959
|
rule lane" (that is `capabilities.permissionRules`) and never as "your rule broke" (that is
|
|
15908
|
-
`persistedRuleShadowed`).
|
|
15960
|
+
`allowRuleShadowed`; `persistedRuleShadowed` on a server <= 7.116.x).
|
|
15909
15961
|
|
|
15910
15962
|
⚠️ REDEMPTION SCOPE is the live respond leg keyed by this frame's `approvalId` only; a replayed
|
|
15911
15963
|
offer on another replica is not a promise that it is still redeemable.
|
|
15912
15964
|
persistedRuleShadowed:
|
|
15913
15965
|
type: string
|
|
15966
|
+
deprecated: true
|
|
15914
15967
|
description: >
|
|
15915
|
-
server
|
|
15968
|
+
🔴 RETIRED by server 7.117.0 (core 7.42.0) — replaced by `allowRuleShadowed`, no alias. A server >= 7.117.0 never mints this key
|
|
15969
|
+
(its strict card schema even refuses a stored card carrying it); only a server <= 7.116.x still does, and the SDK keeps the declaration
|
|
15970
|
+
for those servers (the supported floor is far below 7.117.0). Slated for deletion in the next major.
|
|
15971
|
+
|
|
15972
|
+
For those older servers (server >= 7.13.0 / core 5.25.0 #144, ADDITIVE, "tool_approval" only): this ask MATCHED one of the
|
|
15916
15973
|
caller's persisted allow rules and that rule COULD NOT silence it. The value is the shadowed rule's
|
|
15917
15974
|
VERBATIM text (secret-redacted + length-bounded). UNTRUSTED for display, same treatment as `message`.
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
|
|
15922
|
-
|
|
15923
|
-
|
|
15924
|
-
|
|
15925
|
-
|
|
15926
|
-
|
|
15927
|
-
|
|
15928
|
-
|
|
15929
|
-
|
|
15930
|
-
|
|
15975
|
+
🔴 ABSENT != "you have no rule": present only when a rule matched AND could not clear the ask. 🔴 Deliberately SEPARATE
|
|
15976
|
+
from `governanceForced` and not derivable from it: that key answers "who imposed the gate", this one answers "what
|
|
15977
|
+
happened to YOUR rule". The durable dual on those servers is `gate.riskDescriptor.shadowedRule` on the parked row.
|
|
15978
|
+
allowRuleShadowed:
|
|
15979
|
+
type: array
|
|
15980
|
+
items: { $ref: '#/components/schemas/AllowRuleShadow' }
|
|
15981
|
+
description: >
|
|
15982
|
+
server >= 7.117.0 (core 7.42.0), ADDITIVE, "tool_approval" only — BREAKING RENAME, replacing the retired string `persistedRuleShadowed`
|
|
15983
|
+
(no alias): the allow-layer members that MATCHED this call and could NOT clear this ask, one `{ member, entries, omitted? }` record per
|
|
15984
|
+
matching member (see AllowRuleShadow). `member` is one of `hook` / `deployment` / `persisted` / `skill` / `request`; `entries` are the
|
|
15985
|
+
entries that member matched, as their source spells them (UNTRUSTED for display like `message`, secret-redacted, <= 512 chars each,
|
|
15986
|
+
<= 32 listed; a `hook` record's `entries` is always the empty list); `omitted` counts the entries not listed.
|
|
15987
|
+
|
|
15988
|
+
The explaining sentence ("... matches this call but does not clear the ask — <reason>") is IN `message` (the engine writes it where it builds
|
|
15989
|
+
the card); this key is the structured twin of the same fact. Render a line from it ("your rule matched, but this call must be confirmed each
|
|
15990
|
+
time"): without it the only conclusion a user can draw is "my rule broke".
|
|
15991
|
+
|
|
15992
|
+
🔴 ABSENT != "you have no rule": present only when a member matched AND could not clear the ask; a match that cleared never becomes an ask.
|
|
15993
|
+
🔴 `member: "hook"` does not say whose hook (a deployment PreToolUse hook and, on the single-user lane, the request's own `settings.hooks`
|
|
15994
|
+
share one member). 🔴 Deliberately SEPARATE from `governanceForced` (that one: "who imposed the gate"; this one: "what happened to YOUR
|
|
15995
|
+
rule"). What the allow layer can NOT clear: any layer's deny / ask rule, operator `APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` /
|
|
15996
|
+
`MANUAL_MODE_SHELL_GATE=always`, write protection, sensitive-path writes, governance, a hook's ask, plan-mode asks. The durable dual is
|
|
15997
|
+
`gate.riskDescriptor.allowRuleShadowed` on the parked row (PendingCheckpoint.riskDescriptor). Rolling-upgrade caveat: a card stored by a
|
|
15998
|
+
<= 7.116.x replica (`card_json` carrying `persistedRuleShadowed`) cannot be read by a >= 7.117.0 replica — the replay skips it.
|
|
15931
15999
|
probeCause:
|
|
15932
16000
|
type: object
|
|
15933
16001
|
description: >
|
|
@@ -16320,12 +16388,21 @@ components:
|
|
|
16320
16388
|
promise and the per-leg index rules are stated verbatim on ToolApprovalFrame.ruleOffers.
|
|
16321
16389
|
persistedRuleShadowed:
|
|
16322
16390
|
type: string
|
|
16391
|
+
deprecated: true
|
|
16392
|
+
description: >
|
|
16393
|
+
🔴 RETIRED by server 7.117.0 (core 7.42.0) — replaced by `allowRuleShadowed`, no alias (a server >= 7.117.0 never mints it; the strict card
|
|
16394
|
+
schema refuses a stored card carrying it). Only a server <= 7.116.x still does; slated for deletion in the next major. For those servers
|
|
16395
|
+
(ADDITIVE, server >= 7.13.0 / core 5.25.0 #144): the VERBATIM text of the persisted rule this ask matched but which could not silence it
|
|
16396
|
+
(secret-redacted + length-bounded). UNTRUSTED for display. Semantics, the ABSENT != "you have no rule" clause and the deliberate separation
|
|
16397
|
+
from `governanceForced` are stated verbatim on ToolApprovalFrame.persistedRuleShadowed.
|
|
16398
|
+
allowRuleShadowed:
|
|
16399
|
+
type: array
|
|
16400
|
+
items: { $ref: '#/components/schemas/AllowRuleShadow' }
|
|
16323
16401
|
description: >
|
|
16324
|
-
ADDITIVE (server >= 7.
|
|
16325
|
-
|
|
16326
|
-
|
|
16327
|
-
`
|
|
16328
|
-
the stored `card_json` and the replayed frame carry the SAME material.
|
|
16402
|
+
ADDITIVE (server >= 7.117.0 / core 7.42.0, BREAKING RENAME of the retired `persistedRuleShadowed`): the allow-layer members that matched this
|
|
16403
|
+
call and could not clear this ask. Semantics, the five members, the always-empty `hook` entries, the explaining sentence living in `message`,
|
|
16404
|
+
the ABSENT != "you have no rule" clause and the separation from `governanceForced` are stated verbatim on ToolApprovalFrame.allowRuleShadowed
|
|
16405
|
+
— the live frame, the stored `card_json`, the replayed frame and the `approval_request` card carry the SAME material.
|
|
16329
16406
|
fromSubagent: { type: boolean, enum: [true], description: 'Present ⇔ the ask comes from a DELEGATED child — the explicit discriminator (a worker cannot forge it).' }
|
|
16330
16407
|
sourceTaskId: { type: string, description: 'The child''s core session id — row-join value + fallback discriminator.' }
|
|
16331
16408
|
sourceAgentName: { type: string, description: 'The child agent''s display name, redacted. UNTRUSTED.' }
|
|
@@ -16450,6 +16527,37 @@ components:
|
|
|
16450
16527
|
`.strict()`). The eleven known words are exported at runtime as the SDK's `ASK_ORIGINS` (core 7.32.1
|
|
16451
16528
|
`ASK_ORIGINS`, verbatim and in order) — known words, NOT an enforcement table.
|
|
16452
16529
|
|
|
16530
|
+
AllowRuleMember:
|
|
16531
|
+
type: string
|
|
16532
|
+
enum: [hook, deployment, persisted, skill, request]
|
|
16533
|
+
description: >
|
|
16534
|
+
The closed five-word vocabulary of `AllowRuleShadow.member` (server >= 7.117.0 / core 7.42.0 `ALLOW_RULE_MEMBERS`, verbatim and in the order the engine reads the members). The SDK exports
|
|
16535
|
+
it at runtime as `ALLOW_RULE_MEMBERS`. Owner = core; read it as an open string with a default arm (core may add a member and the server follows).
|
|
16536
|
+
|
|
16537
|
+
AllowRuleShadow:
|
|
16538
|
+
type: object
|
|
16539
|
+
additionalProperties: false
|
|
16540
|
+
required: [member, entries]
|
|
16541
|
+
description: >
|
|
16542
|
+
One allow-layer DISCLOSURE record (`ToolApprovalFrame.allowRuleShadowed` / `ApprovalCard.allowRuleShadowed` / the durable
|
|
16543
|
+
`PendingCheckpoint.riskDescriptor.allowRuleShadowed`; server >= 7.117.0 / core 7.42.0 `AllowRuleShadow`): one member of the allow layer that
|
|
16544
|
+
MATCHED the call and could NOT clear its ask. At most one record per member, at most five per ask. The vocabulary owner is core; the server
|
|
16545
|
+
drops the whole key on a member outside the five words, so a >= 7.117.0 server only ever sends these five — still read `member` as an open
|
|
16546
|
+
string with a default arm (core may add members and the server follows).
|
|
16547
|
+
properties:
|
|
16548
|
+
member:
|
|
16549
|
+
$ref: '#/components/schemas/AllowRuleMember'
|
|
16550
|
+
description: >
|
|
16551
|
+
Which allow-layer member matched, in the order the engine reads them: `hook` = a PreToolUse hook's explicit `allow` (a deployment hook or,
|
|
16552
|
+
on the single-user lane, the request's own `settings.hooks` — the key cannot say which) · `deployment` = the operator's `APPROVAL_GRANT` ·
|
|
16553
|
+
`persisted` = a person's stored allow rules · `skill` = an activated skill's `allowedTools` · `request` = the request's `settings.permissions.allow`.
|
|
16554
|
+
entries:
|
|
16555
|
+
type: array
|
|
16556
|
+
maxItems: 32
|
|
16557
|
+
items: { type: string, maxLength: 512 }
|
|
16558
|
+
description: 'The entries that member matched, as their source spells them (UNTRUSTED for display, secret-redacted, <= 512 chars each, <= 32 listed). Always the empty list for `hook` — its word is about the call, not about an entry.'
|
|
16559
|
+
omitted: { type: integer, minimum: 1, description: 'How many matched entries were not listed (beyond the cap). Absent = none omitted.' }
|
|
16560
|
+
|
|
16453
16561
|
RuleOffersAbsence:
|
|
16454
16562
|
type: string
|
|
16455
16563
|
enum: [mandated, shadowed, lane_cannot_speak]
|
|
@@ -16458,7 +16566,7 @@ components:
|
|
|
16458
16566
|
`ApprovalCard.ruleOffersAbsence`; server >= 7.55.0 / core #490 fix ②, S-15). The engine names which
|
|
16459
16567
|
door is shut: `mandated` = this ask must be confirmed every time (🔴 this arm must NOT point the user
|
|
16460
16568
|
at writing a rule — a rule would not silence it, and saying so sends them into a loop); `shadowed` = a
|
|
16461
|
-
|
|
16569
|
+
an allow-layer member matched but could not clear it (the machine-readable twin of `allowRuleShadowed`; `persistedRuleShadowed` on a server <= 7.116.x);
|
|
16462
16570
|
`lane_cannot_speak` = the engine could mint no coverable form for this command.
|
|
16463
16571
|
|
|
16464
16572
|
Engine-side MUTUALLY EXCLUSIVE with `ruleOffers`. 🔴 ABSENCE IS NOT AN ASSERTION — it covers both
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/sdk",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.3.0",
|
|
4
4
|
"description": "Typed, zero-runtime-dependency SDK for the Sema agent fleet usage plane. The shared substrate for all doors (CC/Codex MCP façade + web). Server-side only — tokens never enter the browser.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|