@sema-agent/sdk 12.0.0 โ 13.0.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 +110 -0
- package/dist/control-types.d.ts +2 -1
- package/dist/control-types.d.ts.map +1 -1
- package/dist/control-types.js.map +1 -1
- package/dist/errors.d.ts +121 -9
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +112 -14
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +21 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/health.d.ts +3 -1
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +7 -0
- package/dist/health.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/registry/client.d.ts +1 -0
- package/dist/registry/client.d.ts.map +1 -1
- package/dist/registry/client.js +3 -3
- package/dist/registry/client.js.map +1 -1
- package/dist/registry/errors.d.ts +27 -4
- package/dist/registry/errors.d.ts.map +1 -1
- package/dist/registry/errors.js +41 -1
- package/dist/registry/errors.js.map +1 -1
- package/dist/registry/index.d.ts +7 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +7 -1
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/me-config.d.ts +5 -2
- package/dist/registry/me-config.d.ts.map +1 -1
- package/dist/registry/me-config.js +21 -14
- package/dist/registry/me-config.js.map +1 -1
- package/dist/registry/scope-config-feedback.d.ts +6 -2
- package/dist/registry/scope-config-feedback.d.ts.map +1 -1
- package/dist/registry/scope-config-feedback.js +18 -9
- package/dist/registry/scope-config-feedback.js.map +1 -1
- package/dist/registry/scopes-effective.d.ts.map +1 -1
- package/dist/registry/scopes-effective.js +2 -3
- package/dist/registry/scopes-effective.js.map +1 -1
- package/dist/registry-conflict.d.ts +32 -0
- package/dist/registry-conflict.d.ts.map +1 -0
- package/dist/registry-conflict.js +37 -0
- package/dist/registry-conflict.js.map +1 -0
- package/dist/resources/control/config.d.ts +12 -6
- package/dist/resources/control/config.d.ts.map +1 -1
- package/dist/resources/control/config.js +10 -4
- package/dist/resources/control/config.js.map +1 -1
- package/dist/resources/control/versioning.d.ts +6 -2
- package/dist/resources/control/versioning.d.ts.map +1 -1
- package/dist/resources/control/versioning.js +4 -1
- package/dist/resources/control/versioning.js.map +1 -1
- package/dist/resources/session-sync.d.ts +9 -0
- package/dist/resources/session-sync.d.ts.map +1 -1
- package/dist/resources/session-sync.js.map +1 -1
- package/dist/resources/sessions.d.ts +11 -1
- package/dist/resources/sessions.d.ts.map +1 -1
- package/dist/resources/sessions.js +11 -1
- package/dist/resources/sessions.js.map +1 -1
- package/dist/resources/tasks.d.ts +18 -3
- package/dist/resources/tasks.d.ts.map +1 -1
- package/dist/resources/tasks.js +16 -1
- package/dist/resources/tasks.js.map +1 -1
- package/dist/resources/tool-approvals.d.ts +24 -2
- package/dist/resources/tool-approvals.d.ts.map +1 -1
- package/dist/resources/tool-approvals.js.map +1 -1
- package/dist/transport.d.ts +20 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +35 -3
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +159 -32
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +22 -1
- package/dist/types.js.map +1 -1
- package/openapi.yaml +293 -31
- package/package.json +2 -2
- package/registry-openapi.yaml +17 -4
package/openapi.yaml
CHANGED
|
@@ -413,6 +413,15 @@ paths:
|
|
|
413
413
|
description: >
|
|
414
414
|
Synchronous run-to-completion. Auto `Idempotency-Key` (โ retry-safe). Supports `verify`/`cascade`.
|
|
415
415
|
For anything that may take minutes or hit a HITL gate, use `/v1/runs` instead (this call blocks).
|
|
416
|
+
๐ด PREPARE-TIME REFUSALS ARE TRIAGED ON WORK DONE (server >= 7.104.0 / S-271, one rule for the whole table): a
|
|
417
|
+
prepare-time refusal code that HAS a status in the server's per-code triage table (`resume_at.*`, governance codes,
|
|
418
|
+
`rewind.store_unconfigured` / `rewind.capture_disabled` / `rewind.child_scope_unsupported`, the registered `config.*`
|
|
419
|
+
codes incl. the three roster-bound ones, `corrupt_session`; codes outside the table, e.g. `rewind.invalid_spec`, stay
|
|
420
|
+
200 with a failed body) answers its 4xx / 5xx ERROR BODY only when the whole submission did ZERO WORK (cumulative
|
|
421
|
+
`stats.turns === 0` AND `stats.tokens === 0` โ the common case: nothing billed, not idempotency-cached). When a
|
|
422
|
+
`verify` / `cascade` run's earlier tier already ran turns and only the last tier is refused, the SAME code arrives
|
|
423
|
+
as 200 with a failed body (`terminal.code`; billed; a same-key resend replays). Multi-tier callers must read both
|
|
424
|
+
forms. On a park the 200 body is the result itself plus the three poll-receipt keys (`SyncSubmitResult`, S-173).
|
|
416
425
|
parameters:
|
|
417
426
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
418
427
|
requestBody:
|
|
@@ -422,15 +431,49 @@ paths:
|
|
|
422
431
|
schema: { $ref: '#/components/schemas/TaskRequest' }
|
|
423
432
|
responses:
|
|
424
433
|
'200':
|
|
425
|
-
description:
|
|
434
|
+
description: >-
|
|
435
|
+
The task result (`SyncSubmitResult`): the sealed + redacted engine result; on a park (`terminal.kind:"paused"`)
|
|
436
|
+
it additionally carries the poll receipt `{taskId, sessionId, status}` with `status` โ {suspended, needs_review}
|
|
437
|
+
(server >= 7.104.0 / S-173 โ before that a park answered ONLY those three keys). Terminal bodies carry no `status`
|
|
438
|
+
on >= 7.64; a server <= 7.63 answers the flat form instead (terminal word in `status`, no `terminal`) โ see SyncSubmitResult.
|
|
426
439
|
content:
|
|
427
440
|
application/json:
|
|
428
|
-
schema: { $ref: '#/components/schemas/
|
|
441
|
+
schema: { $ref: '#/components/schemas/SyncSubmitResult' }
|
|
429
442
|
'400': { $ref: '#/components/responses/BadRequest' }
|
|
430
443
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
431
444
|
'403': { $ref: '#/components/responses/Forbidden' } # (declared 2026-08-01) ๅธฆ `sessionId` ๅค็จไปไบบไผ่ฏ:ๅฝๅฑไธๅน้
โ 403(่ชๅ
ฌๅผๅฟซ็
ง่ตท็นๅณๆ,spec ๆญคๅๆผ็ป่ฎฐ)ใserver 3.15.0 ่ตทๅคไธไธช่งฆๅๆกไปถ:ๅค็ง้จ็ฝฒไธ session store ๆ ๅฝๅฑๅคๅซ่ฝๅๆถ,ๅค็จ**ไปปไฝ** caller ่ชๆฅ็ sessionId ้ฝ 403(ๅซๆฌ worker ่ชๅทฑๅ้ธ็ โโ ๆ register seam ๆถๅฝๅฑไปๆช่ขซ่ฎฐไธ)ใcore 2.11.0 ่ตท้ป่ฎคๅ
ๅญๅบ่ชๅธฆ่ฏฅ่ฝๅ โ ่ฏฅ่งฆๅๆกไปถๅจ้ป่ฎค้จ็ฝฒไธไธๅๅบ็ฐใ โ ๏ธ (declared 2026-08-05,server >=7.0.0)`memory.admission_denied` ไน่ตฐๆฌ็ถๆ โโ ๆฌ็ถๆ็ producer ๅ
จๆธ
ๅไธๅๆฏๅคๆฎๅๅจ `Forbidden` ็ปไปถ็ description ้(**้ฃๆฎตๆฏ่ขซ่งฃๆ็**,ๆฌ่กๆณจ้ๅชๆฏๆ่ทฏ,ไธๅค่ฟฐไปฅๅ
ไธคๅคๆผ็งป)ใ
|
|
432
|
-
'409':
|
|
445
|
+
'409':
|
|
446
|
+
description: >-
|
|
447
|
+
Conflict (ConflictError). 409 โ session already has an active run (`conflict.session_active_run`, `activeTaskId`,
|
|
448
|
+
`pendingGate`), OR an idempotency/session-CAS conflict. โ ๏ธ The SDK surfaces it as a TYPED ConflictError and does
|
|
449
|
+
NOT silently resolve it to that run: `activeTaskId` may be the caller's own first attempt OR an unrelated
|
|
450
|
+
concurrent run on the same session โ 409 alone cannot tell (same text as the `Conflict` response component).
|
|
451
|
+
K-24 (server >= 7.104.0 / S-724, zero-work submissions only): `rewind.store_unconfigured` โ this
|
|
452
|
+
deployment has NO file-history store but the request asks to restore files; the request is well-formed, the
|
|
453
|
+
deployment shape conflicts with it (change the deployment, not the request; `capabilities.rewindFiles` is false
|
|
454
|
+
there). Before 7.104.0 it arrived as 200 with a failed body.
|
|
455
|
+
content:
|
|
456
|
+
application/json:
|
|
457
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
458
|
+
'422':
|
|
459
|
+
description: >-
|
|
460
|
+
Semantically unprocessable. K-24 (server >= 7.104.0 / S-724): `rewind.capture_disabled` โ the run turned file
|
|
461
|
+
history off (`fileHistory: "disabled"`) and asks to restore in the same breath; this server's request face
|
|
462
|
+
refuses that combination earlier (400 `request.field_conflict`), so only a host building a TaskSpec directly can
|
|
463
|
+
reach this code. `rewind.child_scope_unsupported` / `resume_at.*` also land here.
|
|
464
|
+
content:
|
|
465
|
+
application/json:
|
|
466
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
433
467
|
'429': { $ref: '#/components/responses/RateLimited' }
|
|
468
|
+
'500':
|
|
469
|
+
description: >-
|
|
470
|
+
K-24 (server >= 7.104.0 / S-612): `corrupt_session` โ this session's saved log cannot be read at all (file backend:
|
|
471
|
+
no meta header; SQL backends: one `session_event.payload` row is not a readable entry). Nothing ran, nothing
|
|
472
|
+
billed; `error` is the engine / store sentence (no on-disk path). DETERMINISTIC: a retry cannot change it (the SDK
|
|
473
|
+
does not auto-retry this code); the repair is the operator's. Also `internal.error` (unclassified).
|
|
474
|
+
content:
|
|
475
|
+
application/json:
|
|
476
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
434
477
|
'503': { $ref: '#/components/responses/Unauthorized' } # โ ๏ธ (declared 2026-08-05,server >=7.0.0)ๆฌๆไฝ็ 503 producer ไธๆญข auth ้จ โโ producer ๆธ
ๅๅจ `Unauthorized` ็ปไปถ็ descriptionใ็ญๅพ
ๆ็คบ็ๅจๅบ็ฉ้ตๅจ่ฏฅ็ปไปถ็ `headers.Retry-After`(**ไธคๆฎต้ฝๆฏ่ขซ่งฃๆ็**;ๆฌ่กๅชๆ่ทฏ,ไธๅค่ฟฐไปฅๅ
ๆผ็งป)ใ
|
|
435
478
|
get:
|
|
436
479
|
tags: [trace]
|
|
@@ -1649,6 +1692,13 @@ paths:
|
|
|
1649
1692
|
rows. Owner-scoped (non-owner โ 404). Idempotent (`{deleted:false}` when nothing existed). ๐ด 409 while a run
|
|
1650
1693
|
is LIVE on the session (`activeTaskId` in the body) โ cancel it first so the session lock isn't orphaned.
|
|
1651
1694
|
501 without a durable session store.
|
|
1695
|
+
๐ด K-24 / S-790 (server >= 7.104.0): the delete FIRST ends the background children rooted at this session (parked
|
|
1696
|
+
ones are retired โ their cards leave the pending list and a later decide on such a card answers 409
|
|
1697
|
+
`decide.not_parked`; running ones on this replica are stopped) and only then deletes the record. A child it cannot
|
|
1698
|
+
stop (typically running on ANOTHER replica) โ the delete is refused and the session record stays (contract: nothing
|
|
1699
|
+
deleted; int-7104 `4a7f72e4` moves that check before every destructive step): 409 `conflict.session_children_alive`
|
|
1700
|
+
with `remaining`. A log that cannot be read at all, when the ownership probe has to open it (cold owner table after
|
|
1701
|
+
a restart) โ 500 `corrupt_session` (S-612; the bad log stays on disk).
|
|
1652
1702
|
responses:
|
|
1653
1703
|
'200':
|
|
1654
1704
|
description: Delete result (idempotent).
|
|
@@ -1669,7 +1719,21 @@ paths:
|
|
|
1669
1719
|
$ref: '#/components/responses/BadRequest'
|
|
1670
1720
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
1671
1721
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
1672
|
-
'409':
|
|
1722
|
+
'409':
|
|
1723
|
+
description: >-
|
|
1724
|
+
Two conflicts, told apart by `errorCode` (both ConflictError): `conflict.session_active_run` โ a run is LIVE on the
|
|
1725
|
+
session (`activeTaskId`), cancel it first; `conflict.session_children_alive` (server >= 7.104.0 / S-790) โ some
|
|
1726
|
+
background children rooted at this session could not be stopped from here, NOTHING was deleted, and `remaining`
|
|
1727
|
+
lists their ids (the same strings as `GET /v1/agents/roster`'s `handle`): wait for them to finish or stop them
|
|
1728
|
+
where they run, then retry the delete verbatim (idempotent). Not a server fault โ do not back off as for a 5xx.
|
|
1729
|
+
content:
|
|
1730
|
+
application/json:
|
|
1731
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
1732
|
+
'500':
|
|
1733
|
+
description: '`corrupt_session` (server >= 7.104.0 / S-612): the session log cannot be read at all and the ownership probe had to open it (cold owner table); the delete is refused and the log stays as it is. Deterministic โ not auto-retried. Also `internal.error` (int-7104 `4a7f72e4`: children this replica could stop but did not stop cleanly โ the session record stays, a retry converges).'
|
|
1734
|
+
content:
|
|
1735
|
+
application/json:
|
|
1736
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
1673
1737
|
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
1674
1738
|
|
|
1675
1739
|
/v1/sessions/{sessionId}/fork:
|
|
@@ -3114,6 +3178,12 @@ paths:
|
|
|
3114
3178
|
`not_found.approval` (it used to 409 โ a single-bit cross-tenant "who is parked on an approval"
|
|
3115
3179
|
oracle); a legitimately-owned old token (a shell retrying its own already-decided row) keeps the
|
|
3116
3180
|
attributable 409 + `terminal:"resolved"` verbatim.
|
|
3181
|
+
PARKED-CHILD lane, K-24 (server >= 7.104.0 / S-790) โ two codes gain a trigger, same code, same body keys:
|
|
3182
|
+
`decide.not_parked` (DecideParkMovedError) now also answers when the child's ROOT SESSION was deleted, or deleted
|
|
3183
|
+
and the same id re-registered as a new session (the decide leg reads the root session's occupant before and after
|
|
3184
|
+
the claim and rolls back when it is gone or different) โ a 7.104.0 session delete retires such cards, so this form
|
|
3185
|
+
mostly meets cards left by a pre-7.104.0 delete; `decide.row_unrevivable` (DecideError) now also answers when the
|
|
3186
|
+
parked row carries no root-session anchor (refused before the claim, nothing consumed).
|
|
3117
3187
|
content:
|
|
3118
3188
|
application/json:
|
|
3119
3189
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
@@ -3140,6 +3210,13 @@ paths:
|
|
|
3140
3210
|
(grandchild) row, or one whose root session was deleted / changed owner, still does (core #1112 pending) โ
|
|
3141
3211
|
render it as "this card can only be denied / wait for a server upgrade". Not a regression: 7.31.x children
|
|
3142
3212
|
never had those tools.
|
|
3213
|
+
๐ด THE TWO CAUSES ARE TOLD APART BY `cause` (server S-818, riding core #1161; ADDITIVE, optional): the body may
|
|
3214
|
+
carry `cause` โ core's CAUSE WORD for this startup failure, relayed VERBATIM from the engine receipt's `details`
|
|
3215
|
+
(no rewrite, no default; absent when the engine did not say, i.e. every server before S-818 and every core before
|
|
3216
|
+
#1161). The closed set is core's (#1161 exports it as a constant, named in core 7.34.1's release notes); this
|
|
3217
|
+
spec copies no word list, so treat it as an OPEN string with a default arm. Absent โ "cannot tell": offer both
|
|
3218
|
+
ways out. SDK โ `ParkedResumeStartupError.startupCause` (`undefined` when absent or not a string; the wire key stays
|
|
3219
|
+
`cause` โ the SDK does not put it on the standard `Error.cause`, which means a chained error).
|
|
3143
3220
|
content:
|
|
3144
3221
|
application/json:
|
|
3145
3222
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
@@ -4034,7 +4111,7 @@ paths:
|
|
|
4034
4111
|
application/json:
|
|
4035
4112
|
schema: { $ref: '#/components/schemas/AskDecisionAck' }
|
|
4036
4113
|
'400':
|
|
4037
|
-
description: 'Malformed body โ `request.invalid_json` (unparseable) or `request.body_shape` (schema reject, e.g. an `actor` carrying anything but `label`).'
|
|
4114
|
+
description: 'Malformed body โ `request.invalid_json` (unparseable) or `request.body_shape` (schema reject, e.g. an `actor` carrying anything but `label`, or โ on a server < 7.104.0 โ a `settledBy` key). Server >= 7.104.0 (S-843) adds the `settledBy` refusals shared with the durable `/decide` leg: `request.field_conflict` (with a non-deny decision), `settled_by_not_in_proof` (direct-door worker), `request.field_invalid` (non-string, or outside the 1..16-character column) โ see AskDecisionBody.settledBy.'
|
|
4038
4115
|
content:
|
|
4039
4116
|
application/json:
|
|
4040
4117
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
@@ -6267,6 +6344,11 @@ components:
|
|
|
6267
6344
|
`state.model_roster_pending` (roster not loaded yet; retry -> ServiceStateError), and (server >=7.0.0,
|
|
6268
6345
|
synchronous `POST /v1/tasks` only) `memory.admission_required` โ the org-memory admission directory is
|
|
6269
6346
|
transiently undecidable, refused fail-closed BEFORE any model call, mapped to MemoryAdmissionError.
|
|
6347
|
+
K-24 (server >= 7.104.0 / S-271, synchronous `POST /v1/tasks` only, and only when the submission did zero work):
|
|
6348
|
+
`config.tool_name_too_long` / `config.tool_contract_too_long` / `config.tool_roster_bound` โ a tool the DEPLOYMENT
|
|
6349
|
+
declared exceeds the roster bound (name 128, contract id / revision 64, `modelGate` 64); the caller cannot route
|
|
6350
|
+
around it and a verbatim retry never changes it (DETERMINISTIC โ the SDK does not auto-retry these codes; they land
|
|
6351
|
+
on ServiceStateError via the 503 tail, with no wait hint); only the deployment fixing its declaration helps.
|
|
6270
6352
|
Which of them carry a wait hint is stated ONCE, under `headers.Retry-After` below (kept in one place so
|
|
6271
6353
|
the two statements cannot drift apart).
|
|
6272
6354
|
headers:
|
|
@@ -6369,8 +6451,16 @@ components:
|
|
|
6369
6451
|
Scenario:
|
|
6370
6452
|
type: string
|
|
6371
6453
|
description: >
|
|
6372
|
-
Primary routing axis (one image serves many
|
|
6373
|
-
|
|
6454
|
+
Primary routing axis (one image serves many). Selects model/tools/skills/prompt. OPEN: a stock server's builtin
|
|
6455
|
+
table is `code` (factory default) / `default` / `code-review` / `scan` (SDK `KNOWN_SCENARIOS`, checked against the
|
|
6456
|
+
published server's `buildScenarios()` table) plus `discuss` โ still accepted today, deliberately not in
|
|
6457
|
+
`KNOWN_SCENARIOS` because it sits inside core #1056's (7.35.0) retirement sweep (server S-630 โก) โ and a deployment may
|
|
6458
|
+
register more through the registry. A name
|
|
6459
|
+
the caller SENDS that the deployment does not serve is a loud 400 `scenario_unknown` (server >= 5.1.0, the body
|
|
6460
|
+
carries the live vocabulary) โ the silent fold to `default` exists only on the server-side ASSIGNMENT chain.
|
|
6461
|
+
Retired, no alias: `oa` (5.0.0), `autonomous` ([2400] CAPS-OPS-11), `team` (renamed `discuss`, server #273 / C-R14;
|
|
6462
|
+
alias withdrawn at #342 โ the discuss scenario's body key `team`, which picks the roster template, kept its name).
|
|
6463
|
+
examples: ['code', 'default', 'code-review', 'scan']
|
|
6374
6464
|
|
|
6375
6465
|
ScenarioDetail:
|
|
6376
6466
|
# ๆฐๅข(2026-07-25 ๅๅกซๆน):`GET /v1/capabilities/scenarios/{name}` ๆญคๅ**ๆดๆก่ทฏๅพ**้ฝไธๅจๆฌๆไปถ้
|
|
@@ -6702,8 +6792,11 @@ components:
|
|
|
6702
6792
|
`resumeAnchorStore.resolve(sessionId, handle, principal)` โ entry id; unknown handle โ 404
|
|
6703
6793
|
`rewind_files_to.unknown_event`; no session โ 422 `rewind_files_to.no_session`; no anchor store / no getLeafId โ
|
|
6704
6794
|
501. โ ๏ธ The 501 is NOT the capability's whole predicate: `capabilities.rewindFilesTo` also requires the
|
|
6705
|
-
file-history store
|
|
6706
|
-
`rewind.store_unconfigured`
|
|
6795
|
+
file-history store; without it the server does not 501 โ core refuses at prepare with
|
|
6796
|
+
`rewind.store_unconfigured` (server >= 7.104.0 / S-724: a 409 error body on the synchronous `POST /v1/tasks` when
|
|
6797
|
+
the submission did zero work; the async / live legs keep a terminal run row with the same code; and
|
|
6798
|
+
`FILE_HISTORY_CAPTURE=false` no longer triggers it) โ so probe the bit first. Riding together with
|
|
6799
|
+
`fileHistory: "disabled"` โ 400 `request.field_conflict`. Honored ONLY when `resumeAt` is absent. One-shot at submit
|
|
6707
6800
|
(resume legs strip it, server >= 7.72.0).
|
|
6708
6801
|
restoreFiles:
|
|
6709
6802
|
type: boolean
|
|
@@ -6726,6 +6819,19 @@ components:
|
|
|
6726
6819
|
๐ด Applies to BOTH restore legs (codex R2 correction): `resumeAt`+`restoreFiles` AND the
|
|
6727
6820
|
code-only `rewindFilesTo` โ a code-only caller omitting it gets the loud terminal too. Recovery
|
|
6728
6821
|
either way: re-run the same restore (per-file idempotent, converges).
|
|
6822
|
+
fileHistory:
|
|
6823
|
+
type: string
|
|
6824
|
+
enum: [disabled]
|
|
6825
|
+
description: >-
|
|
6826
|
+
K-24 (server >= 7.104.0 / S-724; core 7.31.0 #1048 `TaskSpec.fileHistory`) โ the REQUEST-LEVEL file-history off
|
|
6827
|
+
word. ONE word, `disabled`: this run takes no first-touch backup of an edited file and mints no turn boundaries
|
|
6828
|
+
(delegates inherit it); absent = the deployment's setting (there is no `enabled` spelling). Any other value โ 400
|
|
6829
|
+
`request.field_invalid` ("fileHistory must be the string 'disabled' when present โฆ"), fresh and resume legs alike.
|
|
6830
|
+
๐ด Riding together with ANY restore key (`restoreFiles` / `rewindFilesTo` / the retired `rewindFiles`) โ 400
|
|
6831
|
+
`request.field_conflict` AT ADMISSION ("fileHistory: 'disabled' cannot ride with a file restore โฆ"), session and
|
|
6832
|
+
files untouched โ drop it to restore. The leg's own verdict is `wiring_manifest.fileHistory`; whether to render a
|
|
6833
|
+
"don't capture this session" switch is `capabilities.fileHistoryCapture === "on-optional"` (the switch = send this
|
|
6834
|
+
key on every submit of that session). โ ๏ธ A server < 7.104.0 answers 400 `request.body_shape` (unknown key).
|
|
6729
6835
|
permissionMode:
|
|
6730
6836
|
type: string
|
|
6731
6837
|
enum: [default, plan, acceptEdits, bypassPermissions, auto]
|
|
@@ -7436,6 +7542,54 @@ components:
|
|
|
7436
7542
|
sessionId: { type: string }
|
|
7437
7543
|
status: { $ref: '#/components/schemas/RunStatus' }
|
|
7438
7544
|
|
|
7545
|
+
SealedKeyCapability:
|
|
7546
|
+
type: object
|
|
7547
|
+
description: >
|
|
7548
|
+
K-24 (server >= 7.104.0 / S-737) โ the `GET /v1/capabilities` `sealedKey` segment: EXACTLY three keys, key-for-key
|
|
7549
|
+
the server's `src/sealed-key.ts` `SealedKeyCapability`. Private keys, the custody path, the held key-id list and
|
|
7550
|
+
`createdAt` never reach the wire.
|
|
7551
|
+
additionalProperties: false
|
|
7552
|
+
required: [alg, publicKeyId, publicKey]
|
|
7553
|
+
properties:
|
|
7554
|
+
alg:
|
|
7555
|
+
type: string
|
|
7556
|
+
enum: [libsodium-sealedbox-x25519]
|
|
7557
|
+
description: 'v1 sole value, the same word as settings-schema `SEALED_BOX_ALG`; another alg is a loud per-model refusal.'
|
|
7558
|
+
publicKeyId: { type: string, description: 'Goes into `sealedApiKey.publicKeyId` (server default mint `exec-<first 12 hex of sha256(raw public key)>`; treat as opaque); the engine opens with EXACTLY this key.' }
|
|
7559
|
+
publicKey: { type: string, description: 'STANDARD base64 of the 32-byte X25519 public key (44 chars). Public โ safe to log.' }
|
|
7560
|
+
SyncParkReceipt:
|
|
7561
|
+
type: object
|
|
7562
|
+
description: >
|
|
7563
|
+
K-24 (server >= 7.104.0 / S-173) โ the three POLL-RECEIPT keys a synchronous `POST /v1/tasks` adds on a PARK (the
|
|
7564
|
+
whole park body before 7.104.0, values byte-identical), key-for-key the server's `http/sync-submit-body.ts`
|
|
7565
|
+
`SyncParkReceipt`. `status` is the word on the `GET /v1/runs/{taskId}` row โ the server derives the two words from
|
|
7566
|
+
its `RUN_STATUS_CLASS` table (the `parked` class).
|
|
7567
|
+
additionalProperties: false
|
|
7568
|
+
required: [taskId, sessionId, status]
|
|
7569
|
+
properties:
|
|
7570
|
+
taskId: { type: string, description: 'The durable run id minted at submit โ the `GET /v1/runs/{taskId}` poll key.' }
|
|
7571
|
+
sessionId: { type: string }
|
|
7572
|
+
status: { type: string, enum: [suspended, needs_review] }
|
|
7573
|
+
SyncSubmitResult:
|
|
7574
|
+
description: >
|
|
7575
|
+
K-24 โ the synchronous `POST /v1/tasks` 200 body (server name `SyncSubmitBody`, one mint `buildSyncSubmitBody`).
|
|
7576
|
+
ONE RULE (contract ยง5.0c): it is ALWAYS the result itself (the sealed + redacted engine result โ `TaskResult`); when
|
|
7577
|
+
the run is parked (`terminal.kind === "paused"`) it additionally carries the `SyncParkReceipt` keys, so `status`
|
|
7578
|
+
appears ONLY on a park โ terminal bodies carry none (since 7.64.0). A park here is byte-identical to the same park
|
|
7579
|
+
on `/v1/tasks/stream`'s `done.result` except for the identity keys; the resume credential is never on it.
|
|
7580
|
+
Read "is it parked" off `terminal.kind === "paused"`; the old reading `status โ {suspended, needs_review}` still
|
|
7581
|
+
holds. โ ๏ธ THREE GENERATIONS behind one type (the SDK's support floor is 3.0.0): server <= 7.63 answers the FLAT form
|
|
7582
|
+
(`LegacyPlaneTaskResult`: `status` is the terminal word โ completed / failed / blocked or a park word โ and there is
|
|
7583
|
+
no `terminal`); 7.64โ7.103 answers the current `terminal` form on terminal bodies but a park with ONLY the three receipt
|
|
7584
|
+
keys (no `terminal`, no `stats`); >= 7.104 follows the rule above. Read `status` for "parked" first (all three carry
|
|
7585
|
+
a park word on a park), then tell the generations apart by whether `terminal` is present.
|
|
7586
|
+
allOf:
|
|
7587
|
+
- $ref: '#/components/schemas/TaskResult'
|
|
7588
|
+
- type: object
|
|
7589
|
+
properties:
|
|
7590
|
+
status:
|
|
7591
|
+
allOf: [{ $ref: '#/components/schemas/RunStatus' }]
|
|
7592
|
+
description: 'Poll-receipt word on a park (>= 7.64: suspended / needs_review only), or the flat terminal word of a server <= 7.63 (LegacyPlaneTaskResult.status).'
|
|
7439
7593
|
RunRecord:
|
|
7440
7594
|
type: object
|
|
7441
7595
|
description: >
|
|
@@ -7492,12 +7646,18 @@ components:
|
|
|
7492
7646
|
current cause form on anything server >= 7.64.0 wrote, and the retired flat form on rows written
|
|
7493
7647
|
before the upgrade. The service passes the stored blob through verbatim (redaction only) and does
|
|
7494
7648
|
NOT back-fill `terminal`. Narrow on `"terminal" in result`.
|
|
7649
|
+
๐ด K-24 / S-173 (server >= 7.104.0, contract ยง5.0c): the key always describes the CURRENT state โ a parked row
|
|
7650
|
+
(`suspended` / `needs_review`) carries the result it stopped with (`terminal.kind === "paused"`, credential
|
|
7651
|
+
stripped; = the synchronous 200 body minus `status`); a `running` row (incl. one claimed for resume) has none;
|
|
7652
|
+
a terminal row replaces it whole; an approval-expiry / stale reap clears it. READ `status` FIRST โ `result`
|
|
7653
|
+
present does not mean finished.
|
|
7495
7654
|
errorCode:
|
|
7496
7655
|
type: string
|
|
7497
7656
|
description: >
|
|
7498
7657
|
Result-level terminal code (e.g. `budget.exceeded`, `cancelled`); NOT an HTTP error. This ROW COLUMN
|
|
7499
7658
|
is unchanged at 7.64.0 โ only its source moved (projected from `result.terminal`, or read straight
|
|
7500
|
-
off a legacy flat blob).
|
|
7659
|
+
off a legacy flat blob). โ ๏ธ K-24 / S-173 (server >= 7.104.0): on a `needs_review` PARK row it is core's canonical
|
|
7660
|
+
`review.pending` (absent before) โ never read "errorCode present" as "failed"; read `status` first.
|
|
7501
7661
|
error: { type: string }
|
|
7502
7662
|
jobId:
|
|
7503
7663
|
type: string
|
|
@@ -8331,10 +8491,12 @@ components:
|
|
|
8331
8491
|
Code-only rewind (`TaskRequest.rewindFilesTo`) is wired โ mint `routes/capabilities.ts:839` =
|
|
8332
8492
|
`Boolean(deps.fileHistoryStore && deps.resumeAnchorStore && deps.sessionStorage?.getLeafId)`: it needs the
|
|
8333
8493
|
file-history store (to restore) AND the anchor map (to resolve the target HANDLE). Corrected in sdk 11.4.0
|
|
8334
|
-
(board [8437] U3): the store is the FILE-HISTORY store (not the pre-S-15 whole-tree snapshot store)
|
|
8335
|
-
server 7.97.0
|
|
8336
|
-
that
|
|
8337
|
-
(
|
|
8494
|
+
(board [8437] U3): the store is the FILE-HISTORY store (not the pre-S-15 whole-tree snapshot store).
|
|
8495
|
+
๐ด K-24: on server 7.97.0โ7.103.x that seat was the CAPTURE face (backend AND the `FILE_HISTORY_CAPTURE` knob), so a
|
|
8496
|
+
deployment that turned capture off reported this bit false together with `rewindFiles` / `restoreFiles` /
|
|
8497
|
+
`sessionSync`. Since server 7.104.0 (S-724) the knob ONLY turns capture off (the store stays wired, stored history
|
|
8498
|
+
still restores and syncs) โ this bit and those three no longer depend on it; they read "is there a file-history
|
|
8499
|
+
store" (= a storage backend). Gate rewind entries on this bit / `rewindFiles`, never on `fileHistoryCapture`.
|
|
8338
8500
|
restoreFiles:
|
|
8339
8501
|
type: boolean
|
|
8340
8502
|
description: >-
|
|
@@ -8926,22 +9088,40 @@ components:
|
|
|
8926
9088
|
ABSENT = an older worker (<= 7.94) โ read as `true` (contract appendix B.1: it passed through back then).
|
|
8927
9089
|
fileHistoryCapture:
|
|
8928
9090
|
type: string
|
|
8929
|
-
enum: ['off', on-always]
|
|
8930
|
-
description: >
|
|
8931
|
-
server >= 7.97.0 (S-589; mint `routes/capabilities.ts:
|
|
8932
|
-
closed word set owned by the
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
`off` = this deployment captures no first-touch snapshots
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
off
|
|
8944
|
-
|
|
9091
|
+
enum: ['off', on-optional, on-always]
|
|
9092
|
+
description: >
|
|
9093
|
+
server >= 7.97.0 (S-589), WORDS CHANGED at 7.104.0 (S-724; mint int-7104 `routes/capabilities.ts:846` =
|
|
9094
|
+
`fileHistoryCaptureOf(deps.fileHistoryStore, deps.config.fileHistoryCapture)`, closed word set owned by the
|
|
9095
|
+
server's `src/file-history-capture.ts` `FILE_HISTORY_CAPTURE_WORD_SET`) โ IS FILE-HISTORY CAPTURE ON, AND CAN A RUN
|
|
9096
|
+
TURN IT OFF. Derived from the ASSEMBLY RESULT (store present AND the `FILE_HISTORY_CAPTURE` knob not off), NOT an
|
|
9097
|
+
echo of the knob โ a deployment without the backend is `off` too. Read it EXHAUSTIVELY:
|
|
9098
|
+
`off` = this deployment captures no first-touch snapshots โ render no "turn capture off" switch. ๐ด Since 7.104.0
|
|
9099
|
+
it no longer implies "no rewind": the knob only stops capture, stored history still restores / syncs โ gate rewind
|
|
9100
|
+
entries on `rewindFiles` / `rewindFilesTo`, not on this bit.
|
|
9101
|
+
`on-optional` = capturing, and a run CAN turn it off: send `fileHistory: "disabled"` on the submit โ render the
|
|
9102
|
+
switch (off = send it on every submit of that session; the resume legs replay the same body).
|
|
9103
|
+
โฐ๏ธ `on-always` is a RETIRED word: server 7.104.0 no longer sends it (once the request word is wired "capturing and
|
|
9104
|
+
cannot be turned off" is structurally unreachable), but a 7.97.0โ7.103.x worker still does = capturing and it
|
|
9105
|
+
CANNOT be turned off per session โ render one read-only true sentence, never a switch that cannot switch (contract
|
|
9106
|
+
appendix B.1). It stays in this enum while the SDK's support floor (3.0.0) is below 7.104.0 โ removing it would make
|
|
9107
|
+
a valid 7.103 capabilities response fail this schema. An unknown word is treated as unknown (never guess by
|
|
9108
|
+
prefix). Turning capture off does NOT delete what was already captured.
|
|
9109
|
+
ABSENT = an older worker (<= 7.96, no knob at all) โ fall back to `rewindFiles` (`true` โ `on-always`, `false` โ `off`).
|
|
9110
|
+
sealedKey:
|
|
9111
|
+
allOf: [{ $ref: '#/components/schemas/SealedKeyCapability' }]
|
|
9112
|
+
description: >
|
|
9113
|
+
K-24 (server >= 7.104.0 / S-737; mint int-7104 `routes/capabilities.ts:969`, a plain member
|
|
9114
|
+
`sealedKey: projectSealedKeyCapability(deps.sealedKeyPublic)`) โ the PUBLIC-KEY DISCOVERY face for sealed model
|
|
9115
|
+
keys: the newest X25519 public key in this process's model-key custody store, exactly three keys. Seal a model key
|
|
9116
|
+
(its UTF-8 bytes) with `crypto_box_seal` against `publicKey`, encode the ciphertext as STANDARD base64 and write it
|
|
9117
|
+
with `alg` / `publicKeyId` into `ModelEntry.sealedApiKey` (local lane: `config.d/models.json`; server USAGE ยง9.10).
|
|
9118
|
+
Sealed wins over `apiKeyEnv`; a key that cannot be opened fails that model on every call (no fallback to
|
|
9119
|
+
`apiKeyEnv`, none to the gateway key).
|
|
9120
|
+
๐ด PRESENT-IFF โ the one per-key exception on this surface (contract appendix B.1): ABSENT means an older server
|
|
9121
|
+
(< 7.104.0) OR this engine built no custody store today (the same body's `version` tells them apart); either way
|
|
9122
|
+
do NOT seal โ use `apiKeyEnv`, or fix the custody directory and restart. Absent is a missing key, never `null`.
|
|
9123
|
+
๐ด ONE STORE PER HOST (`<data root>/sealed-key/`): replicas that do not share that directory answer different
|
|
9124
|
+
keys, and a ciphertext sealed against replica A's key is `stale_ciphertext` on replica B.
|
|
8945
9125
|
background:
|
|
8946
9126
|
type: object
|
|
8947
9127
|
additionalProperties: true
|
|
@@ -12421,6 +12601,13 @@ components:
|
|
|
12421
12601
|
catch and answered 500 `internal.error` โ a caller-side mistake reported as a server fault, which
|
|
12422
12602
|
also made it a retry-worthy-looking code. A consumer that branched on 500 for those paths must move
|
|
12423
12603
|
the branch to the 400 (the fix is the caller's either way: re-encode the id).
|
|
12604
|
+
๐ด DETERMINISTIC failure codes (K-24): a few codes arrive on a status that normally means "retry may help" (500 /
|
|
12605
|
+
503) while the server contract says a verbatim retry NEVER changes the verdict. The SDK's retry arm exempts them
|
|
12606
|
+
by code: `corrupt_session` (500, server >= 7.104.0 / S-612 โ the session's saved log cannot be read),
|
|
12607
|
+
`config.tool_name_too_long` / `config.tool_contract_too_long` / `config.tool_roster_bound` (503, server >=
|
|
12608
|
+
7.104.0 / S-271 โ a deployment-declared tool exceeds the roster bound), `corrupt` (500 โ the session rule store
|
|
12609
|
+
cannot read its own bytes) and `internal.memory_control_plane_corrupt` (500 โ the memory control plane refuses
|
|
12610
|
+
fail-closed). Every other 5xx code keeps the status-based retry.
|
|
12424
12611
|
error: { type: string }
|
|
12425
12612
|
errorMessage: { type: string }
|
|
12426
12613
|
activeTaskId:
|
|
@@ -12441,6 +12628,30 @@ components:
|
|
|
12441
12628
|
๐ด NOT interchangeable with `taskId`: the workflow-child park lane mints no taskId at all (this
|
|
12442
12629
|
decision never landed on any run, so minting one would be a lie), and the other two decide lanes
|
|
12443
12630
|
mint no runId. Branch by `errorCode`, never fall back from one handle to the other.
|
|
12631
|
+
cause:
|
|
12632
|
+
type: string
|
|
12633
|
+
description: >-
|
|
12634
|
+
server S-818 (riding core #1161), on `parked_resume.startup_failed` (422) ONLY: core's CAUSE WORD for the parked
|
|
12635
|
+
resume's startup failure, relayed verbatim (never rewritten, never defaulted; absent when the engine did not say).
|
|
12636
|
+
An OPEN string here โ the closed set is core's (#1161 exports it; the constant's name is in core 7.34.1's release
|
|
12637
|
+
notes). Absent โ cannot tell which of the two causes (see the `/v1/approvals/{sessionId}/decide` 422 text).
|
|
12638
|
+
SDK reads it as `ParkedResumeStartupError.startupCause`.
|
|
12639
|
+
remaining:
|
|
12640
|
+
type: array
|
|
12641
|
+
items: { type: string }
|
|
12642
|
+
description: >-
|
|
12643
|
+
K-24 (server >= 7.104.0 / S-790), on 409 `conflict.session_children_alive` ONLY (`DELETE /v1/sessions/{sessionId}`):
|
|
12644
|
+
the ids of the background children rooted at this session that are still alive (count = length) โ the SAME
|
|
12645
|
+
strings as the `handle` on `GET /v1/agents/roster` rows. Nothing was deleted; wait for them to finish (or stop
|
|
12646
|
+
them where they run) and retry the delete verbatim. SDK: `err.extra.remaining` on the ConflictError.
|
|
12647
|
+
blockedBy:
|
|
12648
|
+
type: string
|
|
12649
|
+
description: >-
|
|
12650
|
+
On 409 `resume_blocked_by_policy` ONLY: the `errorCode` the folded refusal would have carried had it gone out
|
|
12651
|
+
directly โ the original code when it had one, else the status-derived coarse code (`request.rejected` /
|
|
12652
|
+
`not_found.resource` / `request.unprocessable` / `capability.unavailable` โฆ). ALWAYS PRESENT on server >= 7.104.0
|
|
12653
|
+
(S-607); before that it was absent when the original refusal carried no code. SDK:
|
|
12654
|
+
`ResumeBlockedByPolicyError.blockedBy` (`undefined` when the key is absent or not a string โ never defaulted).
|
|
12444
12655
|
|
|
12445
12656
|
# โโ Streaming event taxonomy (the UX ๅฝ่). Each SSE `data:` line is one JSON-serialized AgentEvent. โโ
|
|
12446
12657
|
# TWO vocabularies (the pinned wire contract Drift 3). โ ๏ธ The two lines below are the SHAPE-DEFINING
|
|
@@ -13687,6 +13898,17 @@ components:
|
|
|
13687
13898
|
server >= 7.66.0 (core 7.8.0 design/388 B-4) โ this leg's WHOLE tool roster. The service passes it
|
|
13688
13899
|
through verbatim only after core's own typebox check accepted it; a roster that fails that check is
|
|
13689
13900
|
ABSENT as a whole (never half a roster on the wire). Effective half only (never on the static half).
|
|
13901
|
+
fileHistory:
|
|
13902
|
+
type: string
|
|
13903
|
+
description: >
|
|
13904
|
+
K-24 (server >= 7.104.0 / S-724; core 7.31.0 #1048 / #1050; contract appendix G.20) โ TENANT and OPERATOR faces
|
|
13905
|
+
alike: does THIS LEG capture file history. `on` = edited files are backed up before the first touch and turn
|
|
13906
|
+
boundaries are minted; `disabled` = no capture, whatever the cause (the request word `fileHistory:"disabled"`,
|
|
13907
|
+
the deployment knob `FILE_HISTORY_CAPTURE=false`, no history store, no filesystem on this leg). Effective half only.
|
|
13908
|
+
๐ด `disabled` โ "cannot restore": with the deployment knob off stored history still restores
|
|
13909
|
+
(`capabilities.rewindFiles`); only a run the REQUEST word turned off cannot restore itself.
|
|
13910
|
+
OPEN on read: the server does not enumerate the word (a present non-string is dropped), a third word passes
|
|
13911
|
+
through โ treat it as unknown. ABSENT = an older engine / external derivation, never "capturing".
|
|
13690
13912
|
eventId: { type: string }
|
|
13691
13913
|
parentToolCallId: { type: string }
|
|
13692
13914
|
sourceTaskId: { type: string }
|
|
@@ -13992,6 +14214,21 @@ components:
|
|
|
13992
14214
|
was armed but declined/failed (check the store, check authorisation), `false` = there was no lane at all
|
|
13993
14215
|
(wire one up). The two recovery verbs differ, so a consumer MUST render them apart โ NEVER fold them into
|
|
13994
14216
|
one "nobody approved it".
|
|
14217
|
+
`session.records_skipped` (K-24; server >= 7.104.0 / S-612 form B; contract ยง17.4 / appendix D.3) โ ๐ด SERVER-MINTED
|
|
14218
|
+
(not in core's register; owner, audience `user` and mint all live in the server). The session's saved log was
|
|
14219
|
+
OPENED and some records could not be read and were skipped (file session backend only โ both SQL backends refuse a
|
|
14220
|
+
bad row with `corrupt_session`); the session woke up and THIS TURN RUNS, but the model sees a shorter history.
|
|
14221
|
+
`{ dropped, entriesKept, sessionId }`: `dropped` = records skipped by this replay, `entriesKept` = surviving entries
|
|
14222
|
+
counted after the open succeeded (the meta header not counted); both are observed counts โ do NO arithmetic (there
|
|
14223
|
+
is no "total"); `entriesKept === 0` = header present, no entry left (empty context, the turn still runs). NO `runId`
|
|
14224
|
+
(minted inside the session store's open; attribution = whichever run's stream / ledger it lands on). Deduplicated
|
|
14225
|
+
ONCE PER OPEN: until the log is repaired every real open emits again; a turn served from the server's session cache
|
|
14226
|
+
(`SESSION_CACHE_TTL_SEC`, default 300 s) does not reopen and emits nothing โ an event, not a standing state. Only an
|
|
14227
|
+
open "for this session itself" mints it (a list / export / head / ownership probe reading another session's bad log
|
|
14228
|
+
does not). โ ๏ธ When a skipped record is an ancestor of the current leaf the turn then fails `invalid_session` in
|
|
14229
|
+
prepare (core #1077) โ the frame still arrives first. โ ๏ธ The non-streaming synchronous `POST /v1/tasks` registers no
|
|
14230
|
+
notice delivery (every `engine_notice` code alike), so there it reaches the operator log only. A log that cannot be
|
|
14231
|
+
read AT ALL (no meta header) emits no frame โ that turn is refused with 500 `corrupt_session`.
|
|
13995
14232
|
Starter whitelist (server 7.36): `memory.session_polluted` `{reason, sessionId?}` ยท
|
|
13996
14233
|
`memory.harvest_quarantined` `{count, moved, escalated, reason?}` โ `moved` and `escalated` MUST NOT be
|
|
13997
14234
|
subtracted from each other (an in-place tombstone counts as both) ยท `memory.delegation_static_mark_waived`
|
|
@@ -15629,6 +15866,25 @@ components:
|
|
|
15629
15866
|
additionalProperties: false
|
|
15630
15867
|
properties:
|
|
15631
15868
|
label: { type: string, maxLength: 256 }
|
|
15869
|
+
settledBy:
|
|
15870
|
+
type: string
|
|
15871
|
+
enum: [policy]
|
|
15872
|
+
description: >-
|
|
15873
|
+
server S-843 (>= 7.104.0), ADDITIVE โ the SETTLEMENT SOURCE of this decision. Same word, same source, same
|
|
15874
|
+
sentence as the durable decide leg's key (`POST /v1/approvals/{sessionId}/decide`, ApprovalDecision.settledBy โ
|
|
15875
|
+
see that schema for the full account; the server judges this door and `/decide` with one function, and the live
|
|
15876
|
+
respond leg reads the same two refusal sentences under its own `request.body_shape` family):
|
|
15877
|
+
`"policy"` = the deployment's own policy answered this card, not a person; ABSENT = today's shape.
|
|
15878
|
+
`decision:"deny"` only (an approve carrying it โ 400 `request.field_conflict`); REFUSED on a direct-door worker
|
|
15879
|
+
(400 `settled_by_not_in_proof`); a non-string โ 400 `request.field_invalid`. ๐ด An UNKNOWN word is the OPPOSITE of
|
|
15880
|
+
`/decide` here: this door does not judge the word, so it answers 200 and the word is stored with the decision (the
|
|
15881
|
+
card is settled as `deny`; its source cannot be corrected afterwards, and an idempotent replay replays it), and the
|
|
15882
|
+
engine refuses the word fail-closed at settlement โ NOT `/decide`'s 409 `resume_outcome_invalid` with the card left
|
|
15883
|
+
pending for a corrected re-decide. THIS leg only: the value lands in a fixed-width
|
|
15884
|
+
`settled_by` column โ outside 1..16 characters โ 400 `request.field_invalid` before the CAS; none of the three
|
|
15885
|
+
response bodies echoes it. OLDER SERVERS (< 7.104.0): this body schema is strict, so the key is an unknown key โ
|
|
15886
|
+
400 `request.body_shape` and nothing is decided โ a loud refusal, not a silent drop. No capability bit; gate on
|
|
15887
|
+
the server version.
|
|
15632
15888
|
|
|
15633
15889
|
AskDecisionAck:
|
|
15634
15890
|
type: object
|
|
@@ -16710,7 +16966,7 @@ components:
|
|
|
16710
16966
|
๐ด ONE RULE FOR EVERY "EFFECTIVE HALF ONLY" KEY (sdk 9.7.0, after a codex adversarial-review [high]):
|
|
16711
16967
|
this schema's only consumer today is `GET /v1/diagnostics/wiring`'s `static` half, and every key marked
|
|
16712
16968
|
"effective half only" (`leg`, `ask.effective`, `configFingerprint`, `tools`, `hooks`, `lsp`,
|
|
16713
|
-
`modelGate`, `autoMode`, `writeProtection`, `readDeny`, `autoConsolidation`) is ALWAYS ABSENT on that
|
|
16969
|
+
`modelGate`, `autoMode`, `writeProtection`, `readDeny`, `autoConsolidation`, `fileHistory`) is ALWAYS ABSENT on that
|
|
16714
16970
|
wire โ THEIR ABSENCE HERE CARRIES NO INFORMATION. The per-key absence readings ("absent = not armed",
|
|
16715
16971
|
"absent = a third state", โฆ) hold for the LIVE FRAME (`Event_wiring_manifest`) and must not be carried
|
|
16716
16972
|
over to this response. For the facts behind those keys: a tenant reads
|
|
@@ -16885,6 +17141,12 @@ components:
|
|
|
16885
17141
|
the operator LIVE projection; for "is this deployment armed", read
|
|
16886
17142
|
`GET /v1/sessions/{sessionId}/memory-status`'s `autoConsolidationArmed` (always present, a real
|
|
16887
17143
|
boolean). Full per-key contract: see Event_wiring_manifest.autoConsolidation.
|
|
17144
|
+
fileHistory:
|
|
17145
|
+
type: string
|
|
17146
|
+
description: >
|
|
17147
|
+
K-24 (server >= 7.104.0 / S-724) โ does this leg capture file history (`on` / `disabled`, OPEN word). EFFECTIVE
|
|
17148
|
+
HALF ONLY โ ALWAYS ABSENT ON THIS ENDPOINT; the deployment-level reading is `capabilities.fileHistoryCapture`.
|
|
17149
|
+
Full per-key contract: see Event_wiring_manifest.fileHistory.
|
|
16888
17150
|
WiringManifestWriteProtection:
|
|
16889
17151
|
# sdk 9.7.0:ไธ `WiringManifestMcpEntry` / `WiringManifestLspSeam` ๅไธๆก่ฃๅฎ โโ ๅไธๆฎตๅฝข่ขซ live ๅธงไธ
|
|
16890
17152
|
# ้ๆ่ฏๆญ้ขไธคๅคๅผ็จ,ๅ
่ๅฐฑๆฏไธคไปฝไผๅ่ชๆผ็้ๅ,ๆไปฅๅ
ทๅๅๆบใ
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.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",
|
|
@@ -52,6 +52,6 @@
|
|
|
52
52
|
"prepublishOnly": "rm -f tsconfig.tsbuildinfo && npm run build && npm run typecheck --workspaces=false --prefix ../.. && npm test --workspaces=false --prefix ../.."
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@sema-agent/settings-schema": "^
|
|
55
|
+
"@sema-agent/settings-schema": "^6.3.0"
|
|
56
56
|
}
|
|
57
57
|
}
|
package/registry-openapi.yaml
CHANGED
|
@@ -129,9 +129,12 @@ paths:
|
|
|
129
129
|
๐ด CAS axis = the `updatedAt` STRING (verbatim echo), NOT a version number โ the scopes/config
|
|
130
130
|
face below uses a NUMBER `version` axis; the two axes must never be mixed (pinned). 409 carries
|
|
131
131
|
`currentUpdatedAt` (typed ConfigCasConflictError; retryOn409 merge-callback retries ONCE).
|
|
132
|
+
409 SCOPE-GONE (web-admin W41F, 2026-09-27): the scope this token is bound to no longer exists โ
|
|
133
|
+
`409 {error:"scope_gone", error_description}` โ NO `currentUpdatedAt`, nothing written, NOT a CAS conflict:
|
|
134
|
+
never refetch+merge+retry it (the SDK throws `ScopeGoneError` and skips the merge leg; `classifyRegistryConflict`).
|
|
132
135
|
responses:
|
|
133
136
|
'200': { description: Written. }
|
|
134
|
-
'409': { description: '{currentUpdatedAt} โ concurrent write; refetch+merge+retry once.' }
|
|
137
|
+
'409': { description: '{error:"conflict", currentUpdatedAt} โ concurrent write; refetch+merge+retry once. OR {error:"scope_gone"} โ the token''s scope no longer exists; nothing written; do NOT retry.' }
|
|
135
138
|
/api/v1/users/{u}/config/{domain}:
|
|
136
139
|
parameters:
|
|
137
140
|
- { in: path, name: u, required: true, schema: { type: string } }
|
|
@@ -145,7 +148,7 @@ paths:
|
|
|
145
148
|
summary: Managed CAS-write (same updatedAt axis + 409 semantics as me/config).
|
|
146
149
|
responses:
|
|
147
150
|
'200': { description: Written. }
|
|
148
|
-
'409': { description: '{currentUpdatedAt}.' }
|
|
151
|
+
'409': { description: '{error:"conflict", currentUpdatedAt} โ CAS conflict. OR {error:"scope_gone"} โ the token''s scope no longer exists; nothing written; do NOT retry (SDK ScopeGoneError).' }
|
|
149
152
|
|
|
150
153
|
# โโ scope config draft / publish (CAS on the version NUMBER axis) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
151
154
|
/api/v1/scopes/{s}/config/{domain}:
|
|
@@ -174,7 +177,12 @@ paths:
|
|
|
174
177
|
summary: CAS-write the draft (putScopeConfigDraft; version NUMBER axis โ not updatedAt).
|
|
175
178
|
responses:
|
|
176
179
|
'200': { description: Written. }
|
|
177
|
-
'409':
|
|
180
|
+
'409':
|
|
181
|
+
description: >
|
|
182
|
+
`{error:"conflict", currentVersion?}` โ version conflict (SDK ScopeConfigCasConflictError: re-read, re-base, retry).
|
|
183
|
+
OR `{error:"scope_gone", error_description}` (web-admin W41F / KL-24) โ the scope was deleted, or deleted and re-created
|
|
184
|
+
under the same name, while this write was in flight (or the optional `baseIncarnation` no longer matches): NO
|
|
185
|
+
`currentVersion`, nothing written, NOT retryable โ a re-read reads the REPLACEMENT scope (SDK ScopeGoneError).
|
|
178
186
|
/api/v1/scopes/{s}/publish:
|
|
179
187
|
parameters:
|
|
180
188
|
- { in: path, name: s, required: true, schema: { type: string } }
|
|
@@ -274,7 +282,12 @@ paths:
|
|
|
274
282
|
get: { operationId: adminAuthProvidersShow, summary: 'ADMIN: one auth provider.', responses: { '200': { description: OK } } }
|
|
275
283
|
/api/v1/scopes/{s}/rollback:
|
|
276
284
|
parameters: [{ in: path, name: s, required: true, schema: { type: string } }]
|
|
277
|
-
post:
|
|
285
|
+
post:
|
|
286
|
+
operationId: adminScopeRollback
|
|
287
|
+
summary: 'ADMIN: rollback a scope''s published config.'
|
|
288
|
+
responses:
|
|
289
|
+
'200': { description: OK }
|
|
290
|
+
'409': { description: '{error:"scope_gone"} โ the scope was deleted / re-created under the same name while the rollback was in flight; nothing written; do NOT retry (SDK ScopeGoneError, still a RegistryApiError). Other 409s stay a plain RegistryApiError.' }
|
|
278
291
|
/api/v1/usage/me:
|
|
279
292
|
get: { operationId: adminUsageMe, summary: 'Usage of the caller.', responses: { '200': { description: OK } } }
|
|
280
293
|
/api/v1/usage/summary:
|