@sema-agent/sdk 0.0.120 → 0.0.121

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.
Files changed (2) hide show
  1. package/openapi.yaml +257 -0
  2. package/package.json +1 -1
package/openapi.yaml CHANGED
@@ -719,6 +719,263 @@ paths:
719
719
  '404': { $ref: '#/components/responses/NotFound' }
720
720
  '501': { $ref: '#/components/responses/NotImplemented' }
721
721
 
722
+ /v1/sessions/{sessionId}/head:
723
+ parameters:
724
+ - $ref: '#/components/parameters/PrincipalHeader'
725
+ - in: path
726
+ name: sessionId
727
+ required: true
728
+ schema: { type: string }
729
+ get:
730
+ tags: [sessions]
731
+ operationId: sessionsHead
732
+ x-status: live # [1075]② session-follow light probe (server >=1.225).
733
+ summary: Light session-follow probe — the leaf pointer as a natural version number.
734
+ description: >
735
+ [1075]② — `leafId` is the session tree's leaf pointer; ANY append changes it, so it doubles as a
736
+ version number. Serves an ETag (`"<leafId>"`, `"empty"` when the session has no entries); poll with
737
+ `If-None-Match` and a hit is a zero-body 304 (idle-poll cost ≈ 0 — the deliberate alternative to a
738
+ cross-replica session SSE fan-out; the SSE face `/events` exists separately, connection-capped).
739
+ Owner-scoped (non-owner → 404, no existence oracle). 501 without a durable session store
740
+ (SESSION_BACKEND=tidb|pg|local).
741
+ parameters:
742
+ - in: header
743
+ name: If-None-Match
744
+ required: false
745
+ schema: { type: string }
746
+ description: Previous ETag; on match the response is 304 with no body.
747
+ responses:
748
+ '200':
749
+ description: The current leaf pointer (ETag header carries the same value).
750
+ content:
751
+ application/json:
752
+ schema:
753
+ type: object
754
+ required: [sessionId, leafId]
755
+ properties:
756
+ sessionId: { type: string }
757
+ leafId: { type: string, nullable: true, description: "null = session exists but has no entries yet." }
758
+ '304': { description: 'Leaf unchanged since the presented ETag (no body).' }
759
+ '401': { $ref: '#/components/responses/Unauthorized' }
760
+ '404': { $ref: '#/components/responses/NotFound' }
761
+ '501': { $ref: '#/components/responses/NotImplemented' }
762
+
763
+ /v1/sessions/{sessionId}/events:
764
+ parameters:
765
+ - $ref: '#/components/parameters/PrincipalHeader'
766
+ - in: path
767
+ name: sessionId
768
+ required: true
769
+ schema: { type: string }
770
+ get:
771
+ tags: [sessions]
772
+ operationId: sessionsEvents
773
+ x-status: live # [1196] session-level SSE head subscription.
774
+ summary: 'Session-level SSE: `event: head` pushes (latest-wins) when the leaf pointer moves.'
775
+ description: >
776
+ [1196] — the true-subscription face over the same predicate as `/head`: an SSE stream that pushes
777
+ `event: head` frames (data = the `/head` 200 body) whenever the session's leaf pointer changes,
778
+ latest-wins (intermediate leaves may be skipped). `?lastLeafId=` is the cursor — semantically the
779
+ ETag: when it matches the current leaf there is no initial frame; otherwise the current head is
780
+ replayed immediately on subscribe. 25s comment-line heartbeats. Auth and store gates are exactly
781
+ `/head`'s (owner-scoped 404; 501 without a durable session store). Connection cap exceeded →
782
+ 503 + Retry-After — fall back to polling `/head` (advertised via `capabilities.sessionEvents`).
783
+ parameters:
784
+ - in: query
785
+ name: lastLeafId
786
+ required: false
787
+ schema: { type: string }
788
+ description: 'Cursor: the last seen leafId. Matching the current leaf suppresses the initial replay frame.'
789
+ responses:
790
+ '200':
791
+ description: 'SSE stream (`text/event-stream`) of `event: head` frames.'
792
+ content:
793
+ text/event-stream:
794
+ schema: { type: string }
795
+ '401': { $ref: '#/components/responses/Unauthorized' }
796
+ '404': { $ref: '#/components/responses/NotFound' }
797
+ '501': { $ref: '#/components/responses/NotImplemented' }
798
+ '503': { description: 'Subscription connection cap exceeded — Retry-After set; fall back to polling /head.' }
799
+
800
+ /v1/sessions/{sessionId}/init:
801
+ parameters:
802
+ - $ref: '#/components/parameters/PrincipalHeader'
803
+ - in: path
804
+ name: sessionId
805
+ required: true
806
+ schema: { type: string }
807
+ get:
808
+ tags: [sessions]
809
+ operationId: sessionsInit
810
+ x-status: live # E11 shell-host startup bundle.
811
+ summary: One-call startup bundle for the shell banner (model + mode).
812
+ description: >
813
+ E11 (shell-host) — the one-call startup bundle so a shell renders its banner from ONE request instead
814
+ of fanning out to /v1/models + /v1/policy + /v1/capabilities. Worker-global config surface (same
815
+ posture as /v1/policy): principal OPTIONAL, enforced only under REQUIRE_PRINCIPAL. ADDITIVE contract —
816
+ `model` and `mode` are the load-bearing fields today; `tools`/`agents`/`commands`/`cwd` are omitted
817
+ (tolerate-absent; `cwd` is live-only E13 and never durable here).
818
+ responses:
819
+ '200':
820
+ description: The startup bundle.
821
+ content:
822
+ application/json:
823
+ schema:
824
+ type: object
825
+ required: [sessionId, model]
826
+ properties:
827
+ sessionId: { type: string }
828
+ model:
829
+ type: object
830
+ required: [provider, modelId]
831
+ properties:
832
+ provider: { type: string }
833
+ modelId: { type: string }
834
+ mode: { type: string, description: "Worker autonomy mode; absent when unconfigured." }
835
+ '401': { $ref: '#/components/responses/Unauthorized' }
836
+
837
+ /v1/sessions/{sessionId}/settings:
838
+ parameters:
839
+ - $ref: '#/components/parameters/PrincipalHeader'
840
+ - in: path
841
+ name: sessionId
842
+ required: true
843
+ schema: { type: string }
844
+ get:
845
+ tags: [sessions]
846
+ operationId: sessionsSettings
847
+ x-status: live # E24 read side (CC /config read). Write half needs a core seam — not advertised.
848
+ summary: Effective merged settings view (read-only).
849
+ description: >
850
+ E24 (shell-host) — the effective merged settings the run obeys (CC /config read side). Worker-global
851
+ config surface (principal optional unless REQUIRE_PRINCIPAL, same posture as /v1/policy and the E11
852
+ init bundle). The PATCH half (runtime settings write) needs a core seam and is deliberately absent —
853
+ no settings-write capability is advertised (honest read-only route).
854
+ responses:
855
+ '200':
856
+ description: The effective view.
857
+ content:
858
+ application/json:
859
+ schema:
860
+ type: object
861
+ required: [effective, applied]
862
+ properties:
863
+ effective:
864
+ type: object
865
+ description: 'Resolved worker config: model, mode?, approvalRequire, commandPolicy, limits {maxTaskCostUsd, maxTaskTokens}.'
866
+ applied:
867
+ type: object
868
+ description: 'Echo of the resolved model ({ model }).'
869
+ '401': { $ref: '#/components/responses/Unauthorized' }
870
+
871
+ /v1/sessions/{sessionId}/notify:
872
+ parameters:
873
+ - $ref: '#/components/parameters/PrincipalHeader'
874
+ - in: path
875
+ name: sessionId
876
+ required: true
877
+ schema: { type: string }
878
+ post:
879
+ tags: [sessions]
880
+ operationId: sessionsNotify
881
+ x-status: live # External task_notification injection (frame family = [446] bg_notification).
882
+ summary: Inject an EXTERNAL task_notification into a session (live nudge or inbox park).
883
+ description: >
884
+ Inject an external completion/event notice into a session as a `task_notification` frame
885
+ (task_type="external" is minted by core — an external caller can never impersonate an internal frame;
886
+ sanitize/fencing/three-state delivery are core-side). Live half: the session's active stream on THIS
887
+ replica gets a core notify verb → `delivery: "live"` (200). Idle half: parked into the session inbox
888
+ (external key domain) and drained as a `task_notification` on the next stream open → `delivery:
889
+ "parked"` (202). Owner-scoped fail-closed (unknown or foreign session → 404, no oracle); core contract
890
+ rejections (`notify.*`) surface as 400 with `errorCode`, never silently parked. 501 without the
891
+ session-ownership face or (park path) the workflow completion inbox.
892
+ requestBody:
893
+ required: true
894
+ content:
895
+ application/json:
896
+ schema:
897
+ type: object
898
+ required: [task_id, status, summary]
899
+ properties:
900
+ task_id: { type: string, maxLength: 190 }
901
+ status: { type: string, enum: [completed, failed, killed, cancelled, event] }
902
+ summary: { type: string }
903
+ result: { type: string }
904
+ seq: { type: integer, minimum: 1 }
905
+ source: { type: string, maxLength: 190 }
906
+ responses:
907
+ '200':
908
+ description: Delivered onto the live stream.
909
+ content:
910
+ application/json:
911
+ schema:
912
+ type: object
913
+ required: [sessionId, delivery]
914
+ properties:
915
+ sessionId: { type: string }
916
+ delivery: { type: string, enum: [live] }
917
+ '202':
918
+ description: No live stream — parked in the session inbox, drained on the next stream open.
919
+ content:
920
+ application/json:
921
+ schema:
922
+ type: object
923
+ required: [sessionId, delivery]
924
+ properties:
925
+ sessionId: { type: string }
926
+ delivery: { type: string, enum: [parked] }
927
+ note: { type: string }
928
+ '400': { $ref: '#/components/responses/BadRequest' }
929
+ '401': { $ref: '#/components/responses/Unauthorized' }
930
+ '404': { $ref: '#/components/responses/NotFound' }
931
+ '501': { $ref: '#/components/responses/NotImplemented' }
932
+
933
+ /v1/sessions/{sessionId}/wake:
934
+ parameters:
935
+ - $ref: '#/components/parameters/PrincipalHeader'
936
+ - in: path
937
+ name: sessionId
938
+ required: true
939
+ schema: { type: string }
940
+ post:
941
+ tags: [sessions]
942
+ operationId: sessionsWake
943
+ x-status: live # design/144 §3 wake arm.
944
+ summary: Wake a task_done-parked session (message delivery, NOT a gate decision).
945
+ description: >
946
+ design/144 §3 — deliver a message (or an already-parked pendingSteer) to a session parked on a
947
+ `task_done` checkpoint and resume it as the next turn's input. This is NOT a gate decision: it never
948
+ allows/denies a pending action — a pending gate ⇒ 409 `wake.gate_pending` (resolve through that gate's
949
+ own decide entry; approvals are never bypassed). Empty park + no message ⇒ nothing to deliver.
950
+ Owner-scoped; operator principals may carry trusted (`<system-reminder>`-bearing) messages. Resume
951
+ burns model budget — rate/quota/lease gates apply. 501 without the checkpoint store.
952
+ requestBody:
953
+ required: false
954
+ content:
955
+ application/json:
956
+ schema:
957
+ type: object
958
+ properties:
959
+ message: { type: string, minLength: 1 }
960
+ responses:
961
+ '202':
962
+ description: Resumed — the woken leg is driving into the durable run log.
963
+ content:
964
+ application/json:
965
+ schema:
966
+ type: object
967
+ required: [taskId, sessionId, status]
968
+ properties:
969
+ taskId: { type: string }
970
+ sessionId: { type: string }
971
+ status: { type: string }
972
+ '400': { $ref: '#/components/responses/BadRequest' }
973
+ '401': { $ref: '#/components/responses/Unauthorized' }
974
+ '404': { description: 'No parked checkpoint for this session (nothing to wake), or session not visible to the caller.' }
975
+ '409': { description: 'Pending gate (`wake.gate_pending` — decide it through its own entry) or resume context missing.' }
976
+ '422': { description: '`steering.invalid_content` — the message failed the steering content gate.' }
977
+ '501': { $ref: '#/components/responses/NotImplemented' }
978
+
722
979
  /v1/sessions/{sessionId}/policy:
723
980
  parameters:
724
981
  - $ref: '#/components/parameters/PrincipalHeader'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/sdk",
3
- "version": "0.0.120",
3
+ "version": "0.0.121",
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",