@sema-agent/sdk 18.2.0 → 19.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 +105 -0
- package/dist/control-types.d.ts +4 -3
- package/dist/control-types.d.ts.map +1 -1
- package/dist/control-types.js.map +1 -1
- package/dist/errors.d.ts +68 -30
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +70 -30
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +7 -6
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/health.d.ts +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/admin.d.ts +1 -1
- package/dist/resources/approvals.d.ts +12 -8
- package/dist/resources/approvals.d.ts.map +1 -1
- package/dist/resources/approvals.js +12 -7
- package/dist/resources/approvals.js.map +1 -1
- package/dist/resources/images.d.ts +2 -1
- package/dist/resources/images.d.ts.map +1 -1
- package/dist/resources/images.js +3 -2
- package/dist/resources/images.js.map +1 -1
- package/dist/resources/sessions.d.ts +4 -0
- package/dist/resources/sessions.d.ts.map +1 -1
- package/dist/resources/sessions.js +6 -2
- package/dist/resources/sessions.js.map +1 -1
- package/dist/resources/tool-approvals.d.ts +29 -1
- package/dist/resources/tool-approvals.d.ts.map +1 -1
- package/dist/resources/tool-approvals.js +5 -0
- package/dist/resources/tool-approvals.js.map +1 -1
- package/dist/resources/trace.d.ts.map +1 -1
- package/dist/resources/trace.js +3 -3
- package/dist/resources/trace.js.map +1 -1
- package/dist/sse.d.ts +30 -10
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +44 -11
- package/dist/sse.js.map +1 -1
- package/dist/types.d.ts +29 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -1
- package/openapi.yaml +116 -39
- package/package.json +2 -2
package/openapi.yaml
CHANGED
|
@@ -3262,10 +3262,11 @@ paths:
|
|
|
3262
3262
|
description: >
|
|
3263
3263
|
Frames: `meta` ({type,version,mode:"approvals-delta",pollMs}), then `synced` ({type,count}) once the
|
|
3264
3264
|
first full snapshot has been emitted, then `pending`/`resolved` deltas; plus `heartbeat` ({type}) on the
|
|
3265
|
-
keep-alive tick and
|
|
3266
|
-
fires — or, server >= 7.122.0, `error` with
|
|
3267
|
-
|
|
3268
|
-
|
|
3265
|
+
keep-alive tick and an `error` ({type,errorCode:"STREAM_MAX_DURATION",…}) when the 15-min cap
|
|
3266
|
+
fires (the server closes the stream; the SDK reader reconnects and tails on) — or, server >= 7.122.0, `error` with
|
|
3267
|
+
`errorCode:"draining"` at the moment the instance enters drain (same code and sentence as the billable-submit 503 `draining`;
|
|
3268
|
+
the server closes the stream right after the frame). After `draining` the SDK reader ENDS (shared terminal predicate): re-opening is
|
|
3269
|
+
the caller's call, on its own schedule and backoff, and lands on the replacement instance. (Corrected 2026-07-31: this list used to name only meta/pending/resolved — a consumer written to
|
|
3269
3270
|
it silently drops three frame kinds it really receives.) Each data payload mirrors its SSE event name in
|
|
3270
3271
|
`data.type` — proxy-safe dispatch. Cross-replica by
|
|
3271
3272
|
construction (polls the SHARED checkpoint table). 15-min cap + heartbeats; a DB blip retries, never
|
|
@@ -3366,9 +3367,13 @@ paths:
|
|
|
3366
3367
|
'409':
|
|
3367
3368
|
description: >
|
|
3368
3369
|
Either a session-CAS conflict (`ErrorResponse.activeTaskId`), OR a design/80 D-1
|
|
3369
|
-
`approval_binding_mismatch` (`errorCode`, `field`: boundCallId|boundInputHash
|
|
3370
|
-
|
|
3371
|
-
|
|
3370
|
+
`approval_binding_mismatch` (`errorCode`, `field`: boundCallId|boundInputHash, or absent — e.g. core's row-integrity
|
|
3371
|
+
refusal, whatever engine wrote the parked row) — your binding does NOT match the current pending action (TOCTOU/swap).
|
|
3372
|
+
🔴 server >= 7.124.0 ONE CODE, ONE CAUSE: this code only says "the binding changed". The content-ask `answer` cell (core 5.7.0's
|
|
3373
|
+
third `field` member) now answers `resume_outcome_invalid` with `field: "answer"` (fix the answer and decide again — not
|
|
3374
|
+
"refetch the coordinates"); before 7.124.0 that cell borrowed this code. The SDK reads `field` here as the closed pair of binding
|
|
3375
|
+
seats (an older server's borrowed `answer` reads as absent; the raw value stays in `err.extra.field`). `retriable: true` is unchanged
|
|
3376
|
+
(the card stays pending, the run row re-parks). The SDK splits these by `errorCode` into
|
|
3372
3377
|
ConflictError vs ApprovalBindingMismatchError (the engine's own code for the same refusal, `checkpoint.invalid_outcome`,
|
|
3373
3378
|
maps to that class too). binding_mismatch = SAFETY signal: refetch + re-present
|
|
3374
3379
|
to the human, NEVER auto-retry. A `decidedBy: "policy"` allow on a person-required card is the OTHER `invalid_outcome`
|
|
@@ -3448,7 +3453,12 @@ paths:
|
|
|
3448
3453
|
`checkpoint.reopen_revote` / `checkpoint.already_exists` / `checkpoint.resume_aborted` /
|
|
3449
3454
|
`checkpoint.unsupported_version` all arrive as 409 and fall on the SDK's `checkpoint.` PREFIX family
|
|
3450
3455
|
(→ ConflictError, `.errorCode` carried verbatim; an OPEN set, so a future core code degrades with
|
|
3451
|
-
information instead of collapsing anonymously).
|
|
3456
|
+
information instead of collapsing anonymously). 🔴 server >= 7.124.0: the `checkpoint.unsupported_version` body carries two
|
|
3457
|
+
additive keys `writerVersion` (the service version that parked the row, as recorded in the resume context) and `readerVersion`
|
|
3458
|
+
(this engine) — the same rule at EVERY mint point of that code (core's mirrored code and the server's two self-minted reading-marker
|
|
3459
|
+
refusals), present iff the resume context records a writer version (rows parked before 7.124.0 carry neither; equal values are still
|
|
3460
|
+
sent). `writerVersion` newer than `readerVersion` ⇒ decide on that version (or a newer one), not by retrying here. SDK type
|
|
3461
|
+
`CheckpointUnsupportedVersionExtra`, values at `err.extra`. The one non-409 member is `checkpoint.not_found`,
|
|
3452
3462
|
which the same mint point sends as a 404 (see below).
|
|
3453
3463
|
THIRD member (moved here from a documented-but-nonexistent 410, 2026-07-31): `approval_stale`
|
|
3454
3464
|
(`errorCode`; `terminal:"resolved"` when attributable, else the key is absent) — the checkpoint is
|
|
@@ -4333,7 +4343,16 @@ paths:
|
|
|
4333
4343
|
schema: { $ref: '#/components/schemas/ToolApprovalRespondAck' }
|
|
4334
4344
|
'400': { description: Malformed body (existence-independent). }
|
|
4335
4345
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
4336
|
-
'404':
|
|
4346
|
+
'404':
|
|
4347
|
+
description: >
|
|
4348
|
+
Unknown/settled/expired/foreign approval (no existence oracle) — `tool_approval.not_pending`. Past the owner gate the body may carry
|
|
4349
|
+
an additive `cause` (`ToolApprovalNotPendingCause`): a row-ending cause word (the card ended without a human decision — dismiss it)
|
|
4350
|
+
or `unknown_or_other_replica` (this replica does not know the id — retry on another endpoint / replica). 🔴 server >= 7.124.0 retired
|
|
4351
|
+
the old words `voided` / `denied` (replaced by the concrete cause word, no alias); a row with no recorded cause carries no key, and a
|
|
4352
|
+
deployment without a durable ask ledger never sends it. Not-yours is byte-identical to unknown.
|
|
4353
|
+
content:
|
|
4354
|
+
application/json:
|
|
4355
|
+
schema: { $ref: '#/components/schemas/ToolApprovalNotPendingBody' }
|
|
4337
4356
|
'501': { description: Live tool-approval HITL not enabled (TOOL_APPROVAL_ENABLED). }
|
|
4338
4357
|
|
|
4339
4358
|
/v1/tasks/{taskId}/asks/{askId}/decision:
|
|
@@ -4402,8 +4421,8 @@ paths:
|
|
|
4402
4421
|
'410':
|
|
4403
4422
|
description: >
|
|
4404
4423
|
The window is closed and the outcome is already cast: `gone.ask_parked` (gate coordinates in the
|
|
4405
|
-
body — route to the durable gate flow) or `gone.ask` (`{state,
|
|
4406
|
-
DISJOINT bodies.
|
|
4424
|
+
body — route to the durable gate flow) or `gone.ask` (`{state, cause?}`; server >= 7.124.0 renamed the key from `deniedReason`,
|
|
4425
|
+
no alias). The two legs carry DISJOINT bodies.
|
|
4407
4426
|
content:
|
|
4408
4427
|
application/json:
|
|
4409
4428
|
schema: { $ref: '#/components/schemas/AskGoneBody' }
|
|
@@ -5649,7 +5668,7 @@ paths:
|
|
|
5649
5668
|
apart, hard-stops — so the platform stop timeout (Docker `stop_grace_period`, systemd `TimeoutStopSec`, k8s
|
|
5650
5669
|
`terminationGracePeriodSeconds`) must be >= the requested deadline.
|
|
5651
5670
|
IDENTITY — the request names WHICH instance, compared field by field (no state change on a mismatch, 409 `conflict.fleet_identity`
|
|
5652
|
-
naming the field, never echoing the value): `worker` = the engine's worker name (`SEMA_REGISTRY_WORKER
|
|
5671
|
+
naming the field, never echoing the value): `worker` = the engine's worker name (`SEMA_WEB_ADMIN_WORKER`, `SEMA_REGISTRY_WORKER` on servers <= 7.123.x; the authenticated `GET /v1/capabilities` `centerWiring.worker` reads the same value; an engine without a center
|
|
5653
5672
|
lane has none, so every request mismatches); `expectedGeneration` = the fleet generation (`/health.generation`), ABSENT AGAINST ABSENT
|
|
5654
5673
|
(omitting it is the standalone form, not a wildcard — it mismatches a fleet member); `scope` = the tenant scope, both sides read as a
|
|
5655
5674
|
value (the engine's = env `FLEET_SCOPE`; unset on the engine and omitted in the request both read as the default scope `global`);
|
|
@@ -8313,7 +8332,16 @@ components:
|
|
|
8313
8332
|
enum: ['open', closed]
|
|
8314
8333
|
description: 'PRESENT-IFF `lease: configured`. The effective `FLEET_LEASE_FAIL_CLOSED` (default derived from `REQUIRE_PRINCIPAL`); `closed` ⇒ connection-level failures answer 503 `fleet.lease_unavailable` on every billing entry.'
|
|
8315
8334
|
usageReport: { type: boolean, description: 'The usage-report loop is mounted (the three center pieces suffice; `FLEET_ADVERTISE_ADDRESS` not required, S-866 ④).' }
|
|
8316
|
-
issuer: { type: string, enum: [explicit, fallback], description: 'Auth-bridge issuer: explicit `AUTH_BRIDGE_ISSUER` / fallback to `SEMA_REGISTRY_URL
|
|
8335
|
+
issuer: { type: string, enum: [explicit, fallback], description: 'Auth-bridge issuer: explicit `AUTH_BRIDGE_ISSUER` / fallback to the center base URL (`SEMA_WEB_ADMIN_URL`; `SEMA_REGISTRY_URL` on servers <= 7.123.x).' }
|
|
8336
|
+
worker:
|
|
8337
|
+
type: string
|
|
8338
|
+
minLength: 1
|
|
8339
|
+
description: >
|
|
8340
|
+
server >= 7.124.0 — the worker name this engine registers with the center (`SEMA_WEB_ADMIN_WORKER`, the same value the drain identity
|
|
8341
|
+
reads), verbatim. PRESENT-IFF a name is configured AND it is disclosable (the contract's identifier rule `isDisclosableIdentity`: not in
|
|
8342
|
+
identifier form / secret-shaped ⇒ treated as no name, key ABSENT, never masked). It lives only on this AUTHENTICATED face — the
|
|
8343
|
+
unauthenticated `/health` deliberately does not carry it. A shell uses it to build the web session link
|
|
8344
|
+
`<webBaseUrl>/chat?agent=<worker>&session=<id>` (paired with `/health.center.webBaseUrl`).
|
|
8317
8345
|
caller:
|
|
8318
8346
|
type: object
|
|
8319
8347
|
additionalProperties: false
|
|
@@ -8440,6 +8468,8 @@ components:
|
|
|
8440
8468
|
(log `one_time_migrations_applied` `holderDeathCodeRowsBackfilled`) and a new replica reads such a row as the code during the upgrade window,
|
|
8441
8469
|
but the migration has a window (30 days after the release, then the write-back and the read half are deleted) — so
|
|
8442
8470
|
"no `errorCode`" never proves "not a holder death": rows migrated late or after the window stay sentence-only.
|
|
8471
|
+
The three run-death codes as ONE runtime table: schema `RunDeathVerdictCode` (closed enum) = the SDK entry export
|
|
8472
|
+
`RUN_DEATH_VERDICT_CODES` — judge "this run was reaped / reclaimed" by that table; this column itself stays an open string.
|
|
8443
8473
|
error: { type: string }
|
|
8444
8474
|
jobId:
|
|
8445
8475
|
type: string
|
|
@@ -9733,7 +9763,7 @@ components:
|
|
|
9733
9763
|
K-32 (server >= 7.106.0 / S-866 ②; mint = release bytes `dist/http/routes/capabilities.js`
|
|
9734
9764
|
`centerWiring: deps.centerWiring?.(principal)`, shape owner `dist/capabilities/center-wiring.d.ts` `CenterWiring`) —
|
|
9735
9765
|
"IS THIS ENGINE WIRED TO THE CENTER RIGHT NOW, AND IS YOUR QUOTA ENFORCED". 🔴 PRESENT-IFF wired to a center
|
|
9736
|
-
(`SEMA_REGISTRY_URL`) — like `sealedKey`, a registered present-iff exception (contract appendix B.1): absence is the
|
|
9766
|
+
(`SEMA_WEB_ADMIN_URL`; `SEMA_REGISTRY_URL` on servers <= 7.123.x) — like `sealedKey`, a registered present-iff exception (contract appendix B.1): absence is the
|
|
9737
9767
|
KEY BEING ABSENT (never `null`) and has two meanings — an older server (< 7.106.0) or an engine not wired to a center
|
|
9738
9768
|
(the same body's `version` tells them apart); under both read "this face cannot answer wiring / enforcement", NEVER
|
|
9739
9769
|
"quota is enforced". 🔴 PER CALLER (`caller` is the verified principal's lease reading): do not cache it across
|
|
@@ -16603,6 +16633,13 @@ components:
|
|
|
16603
16633
|
type: string
|
|
16604
16634
|
enum: [allowed, denied, expired]
|
|
16605
16635
|
description: '"tool_approval_complete" only. Cosmetic dismiss reason. `expired` = TTL/abort/disconnect; what the ENGINE received for it DEPENDS on the deployment: where the design/172 ask ledger is on (server >= 7.3.0 under STREAM_APPROVAL_ENABLED) the server''s expireAsk CAS re-adjudicates the outcome to "unavailable" and the run PARKS; without that ledger the historical fail-closed DENY stands. Never derive the run''s fate from this frame.'
|
|
16636
|
+
cause:
|
|
16637
|
+
allOf: [{ $ref: '#/components/schemas/ApprovalSettleCause' }]
|
|
16638
|
+
description: >
|
|
16639
|
+
server >= 7.124.0, "tool_approval_complete" ONLY, ADDITIVE: the CAUSE of `outcome: "expired"` — one of the fourteen non-human ending
|
|
16640
|
+
words (`ApprovalSettleCause`), the same word the audit settle row carries. Present ⇔ a non-human ending; a human answer
|
|
16641
|
+
(`allowed` / `denied`) has none. The only HTTP face that shows the four waiting words. ABSENT is not evidence (older servers never send it);
|
|
16642
|
+
the run's fate is still read from the run row / checkpoint face.
|
|
16606
16643
|
|
|
16607
16644
|
# ── design/172 流内审批协议(#151)—— 已随 server 7.3.0 上线;开关 STREAM_APPROVAL_ENABLED 的默认值
|
|
16608
16645
|
# 分两段:server ≤7.4.0 默认 OFF,≥7.5.0 默认 ON(BREAKING,见 server CHANGELOG)。──
|
|
@@ -17442,6 +17479,49 @@ components:
|
|
|
17442
17479
|
first-decision echo now carries `decisionNote` when the row has one.
|
|
17443
17480
|
Retrying the same decision can never succeed — single-winner CAS means the outcome is already cast.
|
|
17444
17481
|
|
|
17482
|
+
RunDeathVerdictCode:
|
|
17483
|
+
type: string
|
|
17484
|
+
enum: [run.stalled, run.orphaned, approval.expired]
|
|
17485
|
+
description: >
|
|
17486
|
+
server >= 7.116.0 — the run-death verdict codes on `RunRecord.errorCode` (contract appendix A.1 (6)): `run.stalled` (heartbeat-lost reap),
|
|
17487
|
+
`run.orphaned` (local-lane restart reclaim) and `approval.expired` (a run parked on an approval was reaped). None means the request was
|
|
17488
|
+
wrong; the run cannot be picked up again — submit the work as a new task. The server's own `isHolderDeathVerdict` counts only the first two
|
|
17489
|
+
(the holding process died before the leg finished). Branch on the code, never on the `error` sentence; absence proves nothing. SDK runtime
|
|
17490
|
+
table: `RUN_DEATH_VERDICT_CODES` (same order).
|
|
17491
|
+
AskRowEndingCause:
|
|
17492
|
+
type: string
|
|
17493
|
+
enum: [routing_failure_fail_closed, run_cancelled, run_exited, batch_aborted, batch_sibling_withdrawn, batch_bound_elsewhere, adhoc_leg_no_durable_domain, orphan_ttl_exceeded, crashed_before_park, shutdown_before_park]
|
|
17494
|
+
description: >
|
|
17495
|
+
server >= 7.124.0 — the ask-row subset of the approval ENDING-CAUSE table (one closed table of seventeen words; a card that ended
|
|
17496
|
+
without a human decision says WHY with one word, and every read face reads the same word). These ten are the ones that land on the
|
|
17497
|
+
ask row: `410 gone.ask` `cause` (grouped by `state`: `DENIED` ⇒ `routing_failure_fail_closed` only, `VOID` ⇒ the other nine) and the
|
|
17498
|
+
late-answer `404 tool_approval.not_pending` `cause` (plus its own `unknown_or_other_replica`). Present ⇔ a non-human ending; a human
|
|
17499
|
+
answer has no cause. The server mints from this table and filters reads through it — closed.
|
|
17500
|
+
ApprovalSettleCause:
|
|
17501
|
+
type: string
|
|
17502
|
+
enum: [ttl_expired, broadcast_lost, stream_disconnected, undeliverable, run_cancelled, run_exited, batch_aborted, batch_sibling_withdrawn, batch_bound_elsewhere, routing_failure_fail_closed, crashed_before_park, shutdown_before_park, orphan_ttl_exceeded, adhoc_leg_no_durable_domain]
|
|
17503
|
+
description: >
|
|
17504
|
+
server >= 7.124.0 — the NON-HUMAN ending causes (fourteen words) carried by the live close frame `tool_approval_complete` `cause` (and the
|
|
17505
|
+
audit ledger's settle rows): the ten ask-row words (`AskRowEndingCause`) plus four waiting words that never land on the ask row —
|
|
17506
|
+
`ttl_expired` (the wait window ran out), `broadcast_lost` (neither frame family reached any connection), `stream_disconnected` (the
|
|
17507
|
+
carrying stream dropped; forced park), `undeliverable` (persisted row unusable / identity indeterminate / hanging without a row). The three
|
|
17508
|
+
decision words (`binding_changed` / `answer_invalid` / `outcome_cell_invalid`) refuse one decision, never end a card, and are not here.
|
|
17509
|
+
ToolApprovalNotPendingCause:
|
|
17510
|
+
type: string
|
|
17511
|
+
enum: [routing_failure_fail_closed, run_cancelled, run_exited, batch_aborted, batch_sibling_withdrawn, batch_bound_elsewhere, adhoc_leg_no_durable_domain, orphan_ttl_exceeded, crashed_before_park, shutdown_before_park, unknown_or_other_replica]
|
|
17512
|
+
description: >
|
|
17513
|
+
The late-answer `404 tool_approval.not_pending` `cause`: the ask-row ending-cause words (the card ended without a human decision — dismiss
|
|
17514
|
+
it) plus the 404-only `unknown_or_other_replica` (this replica does not know the id — retry on another endpoint / replica). server >= 7.124.0
|
|
17515
|
+
retired the old words `voided` / `denied` (no alias).
|
|
17516
|
+
ToolApprovalNotPendingBody:
|
|
17517
|
+
allOf:
|
|
17518
|
+
- $ref: '#/components/schemas/ErrorResponse'
|
|
17519
|
+
- type: object
|
|
17520
|
+
properties:
|
|
17521
|
+
cause:
|
|
17522
|
+
allOf: [{ $ref: '#/components/schemas/ToolApprovalNotPendingCause' }]
|
|
17523
|
+
description: 'Optional, past the owner gate only. See `ToolApprovalNotPendingCause`.'
|
|
17524
|
+
description: '404 body of `POST /v1/tool-approvals/{id}/respond` (`tool_approval.not_pending`).'
|
|
17445
17525
|
AskGoneBody:
|
|
17446
17526
|
allOf:
|
|
17447
17527
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
@@ -17450,25 +17530,21 @@ components:
|
|
|
17450
17530
|
sessionId: { type: string, description: 'gone.ask_parked ONLY — gate reconciliation coordinate 1; drive the existing durable-gate flow with it.' }
|
|
17451
17531
|
gateBoundCallId: { type: string, description: 'gone.ask_parked ONLY — gate reconciliation coordinate 2.' }
|
|
17452
17532
|
gateBoundInputHash: { type: string, description: 'gone.ask_parked ONLY — gate reconciliation coordinate 3.' }
|
|
17453
|
-
state: { type: string, enum: [DENIED, VOID], description: 'gone.ask ONLY — the terminal state. server >= 7.116.0 also mints `VOID` for "the process that held the ask is gone" (local lane restart; see `
|
|
17454
|
-
|
|
17455
|
-
|
|
17533
|
+
state: { type: string, enum: [DENIED, VOID], description: 'gone.ask ONLY — the terminal state. server >= 7.116.0 also mints `VOID` for "the process that held the ask is gone" (local lane restart; see `cause`).' }
|
|
17534
|
+
cause:
|
|
17535
|
+
allOf: [{ $ref: '#/components/schemas/AskRowEndingCause' }]
|
|
17456
17536
|
description: >
|
|
17457
|
-
gone.ask ONLY —
|
|
17458
|
-
|
|
17459
|
-
|
|
17460
|
-
`adhoc_leg_no_durable_domain`, `orphan_ttl_exceeded`
|
|
17461
|
-
`
|
|
17462
|
-
|
|
17463
|
-
The last two are the SAME word as `GET /v1/approvals` `crashConverged[].cause`; the other six were already on the wire
|
|
17464
|
-
(7.3.0 / 7.55.0 / 7.108.0) and are only registered in the server's self-minted word table by 7.116.0.
|
|
17465
|
-
ABSENT = the row carries no attribution. The two vocabularies never mix; the VOID one is open (read an unknown word as "the ask ended without
|
|
17466
|
-
a human decision, reason unknown").
|
|
17537
|
+
gone.ask ONLY — the row's ENDING CAUSE (server >= 7.124.0; the key was `deniedReason` before — renamed, no alias, the SDK reads only
|
|
17538
|
+
`cause`, as `AskGoneError.endingCause`). GROUPED BY `state`: `DENIED` carries only `routing_failure_fail_closed`; `VOID` carries the
|
|
17539
|
+
other nine words of the ask-row subset of the approval ending-cause table — `run_cancelled`, `run_exited`, `batch_aborted`,
|
|
17540
|
+
`batch_sibling_withdrawn`, `batch_bound_elsewhere`, `adhoc_leg_no_durable_domain`, `orphan_ttl_exceeded`, `crashed_before_park` /
|
|
17541
|
+
`shutdown_before_park` (the process that held the ask is gone; the SAME word as `GET /v1/approvals` `crashConverged[].cause`).
|
|
17542
|
+
Present ⇔ a non-human ending; ABSENT = the row carries no recorded cause (rows written before the upgrade are not back-filled).
|
|
17467
17543
|
description: >
|
|
17468
17544
|
410 body. THE TWO LEGS ARE DISJOINT: `gone.ask_parked` carries exactly the three gate coordinates,
|
|
17469
|
-
`gone.ask` carries exactly `{state,
|
|
17545
|
+
`gone.ask` carries exactly `{state, cause?}` (no `consumerState`; server >= 7.124.0 renamed `deniedReason` → `cause`, no alias).
|
|
17470
17546
|
🔴 server >= 7.116.0 (local lane, `DB_BACKEND=local`): after a crash / kill and a restart on the same data root, answering the PREVIOUS
|
|
17471
|
-
life's still-open card is now `410 gone.ask` with `state: "VOID"` and `deniedReason` `crashed_before_park` / `shutdown_before_park` —
|
|
17547
|
+
life's still-open card is now `410 gone.ask` with `state: "VOID"` and `cause` (`deniedReason` before 7.124.0) `crashed_before_park` / `shutdown_before_park` —
|
|
17472
17548
|
<= 7.115.x answered `200` + `consumerState: "absent"` (the run had long been reclaimed; nothing executed). An ask that was already decided
|
|
17473
17549
|
(decided, then the process died mid-execution) is unchanged: `409 conflict.ask_decided`. SQL backends are unchanged in 7.116.0. Routing off field presence across the legs is how a
|
|
17474
17550
|
consumer ends up driving the wrong durable gate.
|
|
@@ -18065,19 +18141,20 @@ components:
|
|
|
18065
18141
|
STREAM-CONTROL frame, NOT a run failure (server src/http/sse-log.ts; the trace leg emits the same
|
|
18066
18142
|
shape at routes/trace-usage.ts). The server writes it as a NAMED frame (`event: error`) whose payload
|
|
18067
18143
|
echoes `type`, so both an `event:`-dispatching client and a payload-dispatching one see it.
|
|
18068
|
-
🔴
|
|
18069
|
-
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
replaced — each of the eight read-only subscription streams gets this frame at the moment drain begins and
|
|
18073
|
-
same code and sentence as the billable-submit 503 `draining
|
|
18074
|
-
|
|
18075
|
-
|
|
18144
|
+
🔴 NOT a run failure (neither known code) — rendering it as a run terminal would declare a live task dead (`done` / `failed` are the
|
|
18145
|
+
run's terminal arms). How a reader handles it is ONE terminal predicate (SDK `isTerminalFrame`, shared by every resumable reader):
|
|
18146
|
+
`STREAM_MAX_DURATION` (the 15-minute cap fired; the run is still alive) does NOT end the reader — it reconnects with `Last-Event-ID`
|
|
18147
|
+
and keeps reading (the durable leg stamps `id:` on every frame). `draining` (server >= 7.122.0: the instance entered drain / is being
|
|
18148
|
+
replaced — each of the eight read-only subscription streams gets this frame at the moment drain begins and at the hard-stop start, and is
|
|
18149
|
+
then closed by the server; same code and sentence as the billable-submit 503 `draining`) ENDS the reader's leg: the frame is delivered,
|
|
18150
|
+
then the reader stops without reconnecting — re-opening (with the last `id:`) is the caller's call, on its own schedule and backoff, and
|
|
18151
|
+
lands on the replacement instance; it is a connection signal that says nothing about the run's state. Any other code ENDS the leg too
|
|
18152
|
+
(open set — branch on the code, read an unknown code as "this leg ended, reason unknown").
|
|
18076
18153
|
additionalProperties: false
|
|
18077
18154
|
required: [type, errorCode]
|
|
18078
18155
|
properties:
|
|
18079
18156
|
type: { const: error }
|
|
18080
|
-
errorCode: { type: string, description: 'STREAM_MAX_DURATION | draining (server >= 7.122.0) (open set).' }
|
|
18157
|
+
errorCode: { type: string, description: 'STREAM_MAX_DURATION (reader resumes) | draining (server >= 7.122.0; reader leg ends) (open set; any other code ends the leg).' }
|
|
18081
18158
|
message: { type: string }
|
|
18082
18159
|
Event_question:
|
|
18083
18160
|
type: object
|
|
@@ -19905,7 +19982,7 @@ components:
|
|
|
19905
19982
|
draining by this deadline". See `POST /v1/admin/drain` for how the identity fields are compared.
|
|
19906
19983
|
properties:
|
|
19907
19984
|
actionId: { type: string, minLength: 1, description: 'Idempotency key: the same id again answers `already_draining` and changes nothing. Hand-issued actions pick their own (e.g. `manual:<uuid>`).' }
|
|
19908
|
-
worker: { type: string, minLength: 1, description: The engine's worker name (`SEMA_REGISTRY_WORKER`). }
|
|
19985
|
+
worker: { type: string, minLength: 1, description: "The engine's worker name (`SEMA_WEB_ADMIN_WORKER`; `SEMA_REGISTRY_WORKER` on servers <= 7.123.x)." }
|
|
19909
19986
|
deadlineAt: { type: integer, minimum: 0, description: Epoch milliseconds by which the engine stops on its own. }
|
|
19910
19987
|
scope: { type: string, minLength: 1, description: 'The tenant scope; omitted = the default scope `global` (compared against env `FLEET_SCOPE`, unset = `global`).' }
|
|
19911
19988
|
expectedGeneration: { type: string, pattern: '^(0|[1-9][0-9]*)$', description: 'The fleet generation as a canonical decimal string (`/health.generation`); absent against absent — omit it only for a non-member.' }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "19.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 ../.. && npm run prepack"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@sema-agent/settings-schema": "^
|
|
55
|
+
"@sema-agent/settings-schema": "^11.2.0"
|
|
56
56
|
}
|
|
57
57
|
}
|