sequence-base 0.3.3__tar.gz → 0.3.5__tar.gz

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 (164) hide show
  1. {sequence_base-0.3.3 → sequence_base-0.3.5}/PKG-INFO +1 -1
  2. {sequence_base-0.3.3 → sequence_base-0.3.5}/pyproject.toml +1 -1
  3. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/__init__.py +6 -2
  4. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/constants/version.py +3 -1
  5. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/__init__.py +4 -1
  6. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/act.py +3 -0
  7. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/benchmarks.py +6 -0
  8. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/connect.py +6 -0
  9. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/deployments.py +10 -0
  10. sequence_base-0.3.5/sequence_base/contract/io.py +83 -0
  11. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/policy.py +13 -13
  12. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schema_export.py +6 -0
  13. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ActionChunk.json +1 -1
  14. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ActionContract.json +1 -1
  15. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ActionStep.json +1 -1
  16. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/AdapterTransform.json +1 -1
  17. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Autoscaler.json +1 -1
  18. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/BenchmarkRegisterRequest.json +28 -1
  19. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/BenchmarkSpec.json +2 -2
  20. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/BenchmarkStatusResponse.json +1 -1
  21. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/BootstrapResponse.json +1 -1
  22. sequence_base-0.3.5/sequence_base/schemas/Camera.json +25 -0
  23. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ClampInfo.json +1 -1
  24. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/CodeBundle.json +1 -1
  25. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Concurrency.json +1 -1
  26. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Conditions.json +1 -1
  27. sequence_base-0.3.5/sequence_base/schemas/ConnectRequest.json +29 -0
  28. sequence_base-0.3.5/sequence_base/schemas/ConnectResponse.json +225 -0
  29. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/DeploymentAccepted.json +1 -1
  30. sequence_base-0.3.5/sequence_base/schemas/DeploymentPolicy.json +239 -0
  31. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/DeploymentRequest.json +139 -1
  32. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/DeploymentStatusResponse.json +1 -1
  33. sequence_base-0.3.5/sequence_base/schemas/Embodiment.json +143 -0
  34. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ErrorBody.json +1 -1
  35. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Estimate.json +1 -1
  36. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/EvalDryRunResponse.json +1 -1
  37. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/EvalReport.json +1 -1
  38. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/EvalRequest.json +1 -1
  39. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/EvalResponse.json +1 -1
  40. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ImageFrame.json +1 -1
  41. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ImageSpec.json +1 -1
  42. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ImageStepApt.json +1 -1
  43. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ImageStepEnv.json +1 -1
  44. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ImageStepRun.json +1 -1
  45. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/ImageStepUvPip.json +1 -1
  46. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Lease.json +1 -1
  47. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/LossyTransform.json +1 -1
  48. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/MetricAgg.json +1 -1
  49. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Observation.json +19 -1
  50. sequence_base-0.3.5/sequence_base/schemas/ObservationContract.json +73 -0
  51. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/PolicyRegistration.json +128 -2
  52. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/PolicySpec.json +127 -1
  53. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Proprioception.json +1 -1
  54. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/RenderSpec.json +1 -1
  55. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Resources.json +1 -1
  56. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/RolloutResult.json +1 -1
  57. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/SecretCreateRequest.json +1 -1
  58. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/SecretInfo.json +1 -1
  59. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/SecretRef.json +1 -1
  60. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/SeqFlags.json +1 -1
  61. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Step.json +1 -1
  62. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/SuiteAgg.json +1 -1
  63. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/TaskAgg.json +1 -1
  64. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Timeouts.json +1 -1
  65. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/UploadTarget.json +1 -1
  66. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/UsageReport.json +1 -1
  67. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/Variant.json +1 -1
  68. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/VolumeAttach.json +1 -1
  69. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/VolumeFile.json +1 -1
  70. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/VolumeInfo.json +1 -1
  71. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/VolumeMount.json +1 -1
  72. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/VolumeRef.json +1 -1
  73. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/VolumeUploadRequest.json +1 -1
  74. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/VolumeUploadResponse.json +1 -1
  75. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/schemas/WarmingError.json +1 -1
  76. {sequence_base-0.3.3 → sequence_base-0.3.5}/tests/test_contracts.py +27 -0
  77. sequence_base-0.3.3/sequence_base/schemas/ConnectRequest.json +0 -16
  78. sequence_base-0.3.3/sequence_base/schemas/ConnectResponse.json +0 -81
  79. sequence_base-0.3.3/sequence_base/schemas/DeploymentPolicy.json +0 -101
  80. {sequence_base-0.3.3 → sequence_base-0.3.5}/.github/workflows/ci.yml +0 -0
  81. {sequence_base-0.3.3 → sequence_base-0.3.5}/.gitignore +0 -0
  82. {sequence_base-0.3.3 → sequence_base-0.3.5}/README.md +0 -0
  83. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/README.md +0 -0
  84. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/REVIEW.md +0 -0
  85. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/START.md +0 -0
  86. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/accounts.md +0 -0
  87. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/billing.md +0 -0
  88. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/build/BUILD_LOG.md +0 -0
  89. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/build/goal_sha256.json +0 -0
  90. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/build/gs-build-wave.js +0 -0
  91. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/build/gs-spec-goals.js +0 -0
  92. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/container.md +0 -0
  93. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/contracts.md +0 -0
  94. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/deploy/PLAN.md +0 -0
  95. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/deploy/PROD_REORG.md +0 -0
  96. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/deploy/SCHEMA_COMPAT.md +0 -0
  97. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/deploy/archive/sequences-gw.genseq-506918.20261001.yaml +0 -0
  98. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/eval.md +0 -0
  99. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/gateway.md +0 -0
  100. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/A1.yaml +0 -0
  101. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/A2.yaml +0 -0
  102. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/A3.yaml +0 -0
  103. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/C1.yaml +0 -0
  104. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/C2.yaml +0 -0
  105. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/C3.yaml +0 -0
  106. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/C4.yaml +0 -0
  107. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/C5.yaml +0 -0
  108. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/G1.yaml +0 -0
  109. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/G2.yaml +0 -0
  110. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/G3.yaml +0 -0
  111. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/G4.yaml +0 -0
  112. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/G5.yaml +0 -0
  113. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/O1.yaml +0 -0
  114. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/O2.yaml +0 -0
  115. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/O3.yaml +0 -0
  116. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/O4.yaml +0 -0
  117. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/O5.yaml +0 -0
  118. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/R1.yaml +0 -0
  119. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/R2.yaml +0 -0
  120. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/R3.yaml +0 -0
  121. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/S1.yaml +0 -0
  122. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/S2.yaml +0 -0
  123. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/S3.yaml +0 -0
  124. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/S4.yaml +0 -0
  125. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/S5.yaml +0 -0
  126. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/S6.yaml +0 -0
  127. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/V1-storage.md +0 -0
  128. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/V2-user-quotas.md +0 -0
  129. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/W0.1.yaml +0 -0
  130. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/goals/W0.2.yaml +0 -0
  131. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/README.md +0 -0
  132. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/architecture.md +0 -0
  133. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/connect.md +0 -0
  134. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/cost.md +0 -0
  135. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/custom-domain.md +0 -0
  136. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/debugging.md +0 -0
  137. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/goals.md +0 -0
  138. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/limits.md +0 -0
  139. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/plan.md +0 -0
  140. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/white-label.md +0 -0
  141. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/modal/wiring.md +0 -0
  142. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/observability.md +0 -0
  143. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/references.md +0 -0
  144. {sequence_base-0.3.3 → sequence_base-0.3.5}/docs/platform/sdk.md +0 -0
  145. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/auth.py +0 -0
  146. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/codec/__init__.py +0 -0
  147. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/codec/image.py +0 -0
  148. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/codec/resize.py +0 -0
  149. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/constants/__init__.py +0 -0
  150. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/constants/env.py +0 -0
  151. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/constants/headers.py +0 -0
  152. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/accounts.py +0 -0
  153. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/errors.py +0 -0
  154. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/eval.py +0 -0
  155. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/flags.py +0 -0
  156. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/contract/volumes.py +0 -0
  157. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/errors/__init__.py +0 -0
  158. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/errors/transport.py +0 -0
  159. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/obs/__init__.py +0 -0
  160. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/obs/log.py +0 -0
  161. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/obs/rid.py +0 -0
  162. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/telemetry/__init__.py +0 -0
  163. {sequence_base-0.3.3 → sequence_base-0.3.5}/sequence_base/telemetry/events.py +0 -0
  164. {sequence_base-0.3.3 → sequence_base-0.3.5}/tests/test_codec_roundtrip.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sequence-base
3
- Version: 0.3.3
3
+ Version: 0.3.5
4
4
  Summary: Shared foundation for the Sequences platform — wire contract, correlation, error taxonomy, constants. Used by the robot SDK, gateway, and container harness.
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: pydantic>=2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sequence-base"
3
- version = "0.3.3"
3
+ version = "0.3.5"
4
4
  description = "Shared foundation for the Sequences platform — wire contract, correlation, error taxonomy, constants. Used by the robot SDK, gateway, and container harness."
5
5
  requires-python = ">=3.11"
6
6
  dependencies = ["pydantic>=2.0"]
@@ -14,6 +14,9 @@ catalogue values stay in container / gateway / spec.py.
14
14
  # contract — the full shared wire contract (obs/action + registry + deployments + connect + eval +
15
15
  # accounts + error bodies). One definition per shape; see sequence_base/contract for the grouping.
16
16
  from sequence_base.contract import ( # noqa: F401 (re-export surface)
17
+ Camera,
18
+ Embodiment,
19
+ ObservationContract,
17
20
  MAX_CODE_BUNDLE_BYTES,
18
21
  UploadTarget,
19
22
  VolumeFile,
@@ -114,7 +117,8 @@ __all__ = [
114
117
  "ImageFrame", "Proprioception", "Observation", "ActionSpace", "ActionStep", "ActionChunk",
115
118
  # contract 1 — flags + policy registry
116
119
  "SeqFlags", "ImageStepUvPip", "ImageStepApt", "ImageStepEnv", "ImageStepRun", "ImageStep", "ImageSpec",
117
- "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "PolicySpec", "PolicyRegistration",
120
+ "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract", "Embodiment",
121
+ "PolicySpec", "PolicyRegistration",
118
122
  # contract 2 — deployments
119
123
  "MAX_CODE_BUNDLE_BYTES", "CodeBundle",
120
124
  "Resources", "Autoscaler", "Timeouts", "VolumeAttach", "DeploymentPolicy", "DeploymentRequest",
@@ -140,4 +144,4 @@ __all__ = [
140
144
  "auth", "WorkerLogEvent",
141
145
  ]
142
146
 
143
- __version__ = "0.3.3"
147
+ __version__ = "0.3.5"
@@ -6,5 +6,7 @@ PROTOCOL_VERSION = "1"
6
6
  # across deployments / repos can tell which version of a shape it is validating against. MUST change
7
7
  # whenever any shared wire shape changes (a field added / removed / retyped) — that is what makes
8
8
  # contract evolution mechanically detectable instead of eyeballed. Bump on any shape change.
9
- CONTRACT_VERSION = "0.4.2" # 0.4.1 -> 0.4.2: 契约7 volumes (uploads: VolumeFile/VolumeUploadRequest/UploadTarget/VolumeUploadResponse/VolumeInfo), weights accept vol://<name>[@v<n>]; DeploymentRequest name is a slug and weights need an origin
9
+ CONTRACT_VERSION = "0.4.4" # 0.4.3 -> 0.4.4: BenchmarkRegisterRequest.secrets (by name) + score (has @seq.score)
10
+ # previous: 0.4.3 # 0.4.2 -> 0.4.3: I/O contract — ObservationContract/Camera/Embodiment on PolicySpec + DeploymentPolicy, Observation.state, ConnectRequest.embodiment, ConnectResponse.action/observation/embodiment
11
+ # previous: 0.4.2 # 0.4.1 -> 0.4.2: 契约7 volumes (uploads: VolumeFile/VolumeUploadRequest/UploadTarget/VolumeUploadResponse/VolumeInfo), weights accept vol://<name>[@v<n>]; DeploymentRequest name is a slug and weights need an origin
10
12
  # previous: 0.4.1 # 0.4.0 -> 0.4.1: 契约2 deploy body completed during S3/G4 — DeploymentPolicy.secrets (name-only passthrough), DeploymentRequest.volumes: list[VolumeAttach{uri,mount,create_if_missing}], concurrency default materialized; telemetry events add load_start stage + emitted_at/rid/dedup_key (O4)
@@ -15,6 +15,9 @@ from sequence_base.contract.act import (
15
15
  # contract 1 — lifecycle flags + policy registry
16
16
  from sequence_base.contract.flags import SeqFlags
17
17
  from sequence_base.contract.policy import (
18
+ Camera,
19
+ Embodiment,
20
+ ObservationContract,
18
21
  ActionContract,
19
22
  Concurrency,
20
23
  ImageSpec,
@@ -105,7 +108,7 @@ __all__ = [
105
108
  # contract 1
106
109
  "SeqFlags",
107
110
  "ImageStepUvPip", "ImageStepApt", "ImageStepEnv", "ImageStepRun", "ImageStep", "ImageSpec",
108
- "VolumeMount", "VolumeRef", "Concurrency", "ActionContract",
111
+ "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract", "Embodiment",
109
112
  "PolicySpec", "PolicyRegistration",
110
113
  # contract 2
111
114
  "MAX_CODE_BUNDLE_BYTES", "CodeBundle",
@@ -50,6 +50,9 @@ class Observation(BaseModel):
50
50
  images: list[ImageFrame] = Field(..., min_length=1, max_length=256)
51
51
  proprioception: Proprioception
52
52
  instruction: str
53
+ # Named state vectors that are not joints — an end-effector axis-angle, an object pose — so they need not
54
+ # be smuggled into joint_positions. Absent when the policy declares none. {io-contract.md "Observation.state"}
55
+ state: dict[str, list[float]] | None = None
53
56
 
54
57
 
55
58
  class ActionSpace(str, Enum):
@@ -139,6 +139,12 @@ class BenchmarkRegisterRequest(BaseModel):
139
139
  # The action contract the benchmark's sim consumes; eval compares it with the policy's and requires an
140
140
  # adapter when they differ.
141
141
  action_contract: ActionContract | None = None
142
+ # Credentials the sim's own code needs (a dataset token), by name only — injected into the build check and
143
+ # every eval shard, never into the policy. {gs-plans/customization/benchmark.md "A.1 SECRETS"}
144
+ secrets: list[SecretRef] = Field(default_factory=list)
145
+ # Whether the benchmark defines @seq.score — the platform then calls it per group (overall, each suite, each
146
+ # task) after every episode has run, and its keys override those groups' means. {benchmark.md "A.2"}
147
+ score: bool = False
142
148
 
143
149
 
144
150
  class BenchmarkStatusResponse(BaseModel):
@@ -15,6 +15,7 @@ from pydantic import BaseModel, ConfigDict, Field
15
15
 
16
16
  # The 503 cold/warming body is defined once in contract.errors and reused here — no second shape.
17
17
  from sequence_base.contract.errors import WarmingError
18
+ from sequence_base.contract.io import ActionContract, ObservationContract
18
19
 
19
20
  __all__ = ["Lease", "ConnectRequest", "ConnectResponse", "WarmingError"]
20
21
 
@@ -35,6 +36,7 @@ class ConnectRequest(BaseModel):
35
36
  model_config = ConfigDict(extra="forbid")
36
37
 
37
38
  model: str = Field(..., description="Deployment name to connect to")
39
+ embodiment: str | None = Field(default=None, description="Which declared embodiment this session drives")
38
40
 
39
41
 
40
42
  class ConnectResponse(BaseModel):
@@ -51,3 +53,7 @@ class ConnectResponse(BaseModel):
51
53
  lease: Lease
52
54
  warming: bool = Field(default=False, description="True → worker still warming; see warming_eta_s")
53
55
  warming_eta_s: int | None = Field(default=None, description="Seconds until warm, when warming")
56
+ # The contracts this session is held to, so the client can check and assemble before the first act.
57
+ action: ActionContract | None = None
58
+ observation: ObservationContract | None = None
59
+ embodiment: str | None = None
@@ -22,6 +22,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_valida
22
22
 
23
23
  from sequence_base.contract.accounts import SecretRef
24
24
  from sequence_base.contract.volumes import VOL_SCHEME, parse_vol
25
+ from sequence_base.contract.io import Embodiment, ObservationContract
25
26
  from sequence_base.contract.policy import (
26
27
  ActionContract,
27
28
  Concurrency,
@@ -104,6 +105,15 @@ class DeploymentPolicy(BaseModel):
104
105
  streaming: bool = False
105
106
  frames_per_chunk: int | None = None
106
107
  secrets: list[SecretRef] = Field(default_factory=list)
108
+ # The observation contract the worker checks every /act against (None: undeclared), and per-robot
109
+ # contracts for a multi-embodiment policy — the worker picks one by the session's embodiment.
110
+ observation: ObservationContract | None = None
111
+ embodiments: dict[str, Embodiment] | None = None
112
+ # Did the author declare `action=` (or embodiments)? `action` is required on the wire, so an SDK that had
113
+ # nothing declared sends a placeholder; only a declared contract is enforced on the worker and handed to the
114
+ # robot. None (an older SDK) is treated as undeclared, so an older policy is never refused for the
115
+ # placeholder it never chose. {io-contract.md "旧 SDK 写的 POLICY 照样能 BUILD"}
116
+ action_declared: bool | None = None
107
117
 
108
118
 
109
119
  MAX_CODE_BUNDLE_BYTES = 8 * 1024 * 1024
@@ -0,0 +1,83 @@
1
+ """
2
+ The I/O contract — what a policy reads and what it returns, declared once and checked everywhere.
3
+
4
+ In one sentence: the author declares `action=` (and `observation=`, or per-robot `embodiments=`) on `@seq.policy`
5
+ → it rides the deploy body into the worker's manifest → the worker refuses an /act whose observation does not
6
+ match before inference, and a chunk that does not match before it leaves → connect hands the same contracts to
7
+ the robot, which checks and assembles against them. {gs-plans/customization/io-contract.md}
8
+
9
+ Kept in its own module (not policy.py) because both the policy declaration and the connect response use it, and
10
+ policy → accounts → connect would otherwise import back into policy.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ from typing import Any
15
+
16
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
17
+
18
+ from sequence_base.contract.act import ActionSpace
19
+
20
+
21
+ class ActionContract(BaseModel):
22
+ """The fixed obs→ActionChunk contract a policy promises. Every field required; `action_space` reuses
23
+ contract 4's enum (not a free string). Each ActionChunk echoes exactly these invariants back."""
24
+
25
+ model_config = ConfigDict(extra="forbid")
26
+
27
+ robot: str
28
+ action_space: ActionSpace
29
+ action_dim: int
30
+ control_frequency_hz: float
31
+
32
+
33
+ # The proprioception fields an observation contract may require, with the wire field each one names.
34
+ PROPRIO_FIELDS = ("joint_positions", "joint_velocities", "end_effector_pose", "gripper")
35
+
36
+
37
+ class Camera(BaseModel):
38
+ """One camera view a policy reads: the size it expects. Informational at the worker (the policy resizes);
39
+ the client resizes and letterboxes to it before sending, so the bytes on the wire are what is used."""
40
+
41
+ model_config = ConfigDict(extra="forbid")
42
+
43
+ width: int = Field(..., gt=0, le=8192)
44
+ height: int = Field(..., gt=0, le=8192)
45
+
46
+
47
+ class ObservationContract(BaseModel):
48
+ """What a policy reads, declared once: the worker checks every /act against it before inference, the
49
+ client assembles to it. An observation that does not match is refused with what is missing — it is never
50
+ inferred on. {gs-plans/customization/io-contract.md "二、观测契约"}"""
51
+
52
+ model_config = ConfigDict(extra="forbid")
53
+
54
+ cameras: dict[str, Camera] = Field(default_factory=dict, description="view name → expected size")
55
+ history: int = Field(default=1, ge=1, le=64, description="frames per view the policy reads")
56
+ proprio: dict[str, int] = Field(default_factory=dict,
57
+ description="proprioception field → its length, e.g. joint_positions: 7")
58
+ state: dict[str, int] = Field(default_factory=dict,
59
+ description="named extra state vector → its length (Observation.state)")
60
+ instruction: bool = Field(default=True, description="whether a non-empty instruction is required")
61
+
62
+ @field_validator("proprio")
63
+ @classmethod
64
+ def _known_proprio(cls, v: dict[str, int]) -> dict[str, int]:
65
+ bad = sorted(set(v) - set(PROPRIO_FIELDS))
66
+ if bad:
67
+ raise ValueError(f"proprio keys must be among {PROPRIO_FIELDS}; got {bad} — put other vectors in state=")
68
+ if any(n < 1 for n in v.values()):
69
+ raise ValueError("each proprio length must be at least 1")
70
+ return v
71
+
72
+
73
+ class Embodiment(BaseModel):
74
+ """One robot body a multi-embodiment policy serves: its action contract, its observation contract, and
75
+ free-form metadata the policy reads (e.g. which normalisation statistics). Chosen per session at connect."""
76
+
77
+ model_config = ConfigDict(extra="forbid")
78
+
79
+ action: ActionContract
80
+ observation: ObservationContract | None = None
81
+ meta: dict[str, Any] = Field(default_factory=dict)
82
+
83
+
@@ -8,10 +8,19 @@ Every shape here forbids unknown fields and pins exact field types — no `Optio
8
8
  """
9
9
  from __future__ import annotations
10
10
 
11
+ from typing import Any
12
+
11
13
  from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
12
14
 
13
15
  from sequence_base.contract.accounts import SecretRef
14
- from sequence_base.contract.act import ActionSpace
16
+ from sequence_base.contract.act import ActionSpace # noqa: F401 — re-exported for older imports
17
+ from sequence_base.contract.io import ( # noqa: F401 — the I/O contract lives in io.py, re-exported here
18
+ PROPRIO_FIELDS,
19
+ ActionContract,
20
+ Camera,
21
+ Embodiment,
22
+ ObservationContract,
23
+ )
15
24
  from sequence_base.contract.flags import SeqFlags
16
25
 
17
26
  __all__ = [
@@ -112,18 +121,6 @@ class Concurrency(BaseModel):
112
121
  target_inputs: int
113
122
 
114
123
 
115
- class ActionContract(BaseModel):
116
- """The fixed obs→ActionChunk contract a policy promises. Every field required; `action_space` reuses
117
- contract 4's enum (not a free string). Each ActionChunk echoes exactly these invariants back."""
118
-
119
- model_config = ConfigDict(extra="forbid")
120
-
121
- robot: str
122
- action_space: ActionSpace
123
- action_dim: int
124
- control_frequency_hz: float
125
-
126
-
127
124
  class PolicySpec(BaseModel):
128
125
  """What `@seq.policy(...)` accrues — a policy's complete infra declaration, losslessly. `action` is
129
126
  required (no default): a policy without an obs→ActionChunk contract is not deployable."""
@@ -144,6 +141,9 @@ class PolicySpec(BaseModel):
144
141
  streaming: bool = False
145
142
  frames_per_chunk: int | None = None
146
143
  action: ActionContract
144
+ # What the policy reads (None: undeclared — an older SDK); per-robot contracts when one model drives several.
145
+ observation: ObservationContract | None = None
146
+ embodiments: dict[str, Embodiment] | None = None
147
147
 
148
148
  @field_validator("weights")
149
149
  @classmethod
@@ -79,6 +79,9 @@ from sequence_base.contract.eval import (
79
79
  )
80
80
  from sequence_base.contract.flags import seqflags_json_schema
81
81
  from sequence_base.contract.policy import (
82
+ Camera,
83
+ Embodiment,
84
+ ObservationContract,
82
85
  ActionContract,
83
86
  Concurrency,
84
87
  ImageSpec,
@@ -113,6 +116,9 @@ WIRE_MODELS: dict[str, type[BaseModel]] = {
113
116
  "VolumeRef": VolumeRef,
114
117
  "Concurrency": Concurrency,
115
118
  "ActionContract": ActionContract,
119
+ "Camera": Camera,
120
+ "ObservationContract": ObservationContract,
121
+ "Embodiment": Embodiment,
116
122
  "PolicySpec": PolicySpec,
117
123
  "PolicyRegistration": PolicyRegistration,
118
124
  # contract 2 — deployments
@@ -98,5 +98,5 @@
98
98
  ],
99
99
  "title": "ActionChunk",
100
100
  "type": "object",
101
- "x-contract-version": "0.4.2"
101
+ "x-contract-version": "0.4.4"
102
102
  }
@@ -39,5 +39,5 @@
39
39
  ],
40
40
  "title": "ActionContract",
41
41
  "type": "object",
42
- "x-contract-version": "0.4.2"
42
+ "x-contract-version": "0.4.4"
43
43
  }
@@ -19,5 +19,5 @@
19
19
  ],
20
20
  "title": "ActionStep",
21
21
  "type": "object",
22
- "x-contract-version": "0.4.2"
22
+ "x-contract-version": "0.4.4"
23
23
  }
@@ -38,5 +38,5 @@
38
38
  ],
39
39
  "title": "AdapterTransform",
40
40
  "type": "object",
41
- "x-contract-version": "0.4.2"
41
+ "x-contract-version": "0.4.4"
42
42
  }
@@ -39,5 +39,5 @@
39
39
  },
40
40
  "title": "Autoscaler",
41
41
  "type": "object",
42
- "x-contract-version": "0.4.2"
42
+ "x-contract-version": "0.4.4"
43
43
  }
@@ -240,6 +240,21 @@
240
240
  "title": "RenderSpec",
241
241
  "type": "object"
242
242
  },
243
+ "SecretRef": {
244
+ "additionalProperties": false,
245
+ "description": "A by-name reference to a secret (PolicySpec.secrets / BenchmarkSpec.secrets). Name only — the\nvalue lives in Secret Manager and is injected at worker bootstrap. Never carries a value.",
246
+ "properties": {
247
+ "name": {
248
+ "title": "Name",
249
+ "type": "string"
250
+ }
251
+ },
252
+ "required": [
253
+ "name"
254
+ ],
255
+ "title": "SecretRef",
256
+ "type": "object"
257
+ },
243
258
  "Variant": {
244
259
  "additionalProperties": false,
245
260
  "description": "One structured variant axis of the eval matrix (e.g. axis=\"lighting\", values=[\"day\",\"night\"]).",
@@ -376,6 +391,18 @@
376
391
  ],
377
392
  "default": null
378
393
  },
394
+ "score": {
395
+ "default": false,
396
+ "title": "Score",
397
+ "type": "boolean"
398
+ },
399
+ "secrets": {
400
+ "items": {
401
+ "$ref": "#/$defs/SecretRef"
402
+ },
403
+ "title": "Secrets",
404
+ "type": "array"
405
+ },
379
406
  "suite_of": {
380
407
  "additionalProperties": {
381
408
  "type": "string"
@@ -393,5 +420,5 @@
393
420
  ],
394
421
  "title": "BenchmarkRegisterRequest",
395
422
  "type": "object",
396
- "x-contract-version": "0.4.2"
423
+ "x-contract-version": "0.4.4"
397
424
  }
@@ -207,7 +207,7 @@
207
207
  ],
208
208
  "title": "SeqFlags",
209
209
  "type": "integer",
210
- "x-contract-version": "0.4.2",
210
+ "x-contract-version": "0.4.4",
211
211
  "x-flag-names": {
212
212
  "CHECK": 65536,
213
213
  "INFER": 16,
@@ -397,5 +397,5 @@
397
397
  ],
398
398
  "title": "BenchmarkSpec",
399
399
  "type": "object",
400
- "x-contract-version": "0.4.2"
400
+ "x-contract-version": "0.4.4"
401
401
  }
@@ -40,5 +40,5 @@
40
40
  ],
41
41
  "title": "BenchmarkStatusResponse",
42
42
  "type": "object",
43
- "x-contract-version": "0.4.2"
43
+ "x-contract-version": "0.4.4"
44
44
  }
@@ -72,5 +72,5 @@
72
72
  ],
73
73
  "title": "BootstrapResponse",
74
74
  "type": "object",
75
- "x-contract-version": "0.4.2"
75
+ "x-contract-version": "0.4.4"
76
76
  }
@@ -0,0 +1,25 @@
1
+ {
2
+ "additionalProperties": false,
3
+ "description": "One camera view a policy reads: the size it expects. Informational at the worker (the policy resizes);\nthe client resizes and letterboxes to it before sending, so the bytes on the wire are what is used.",
4
+ "properties": {
5
+ "height": {
6
+ "exclusiveMinimum": 0,
7
+ "maximum": 8192,
8
+ "title": "Height",
9
+ "type": "integer"
10
+ },
11
+ "width": {
12
+ "exclusiveMinimum": 0,
13
+ "maximum": 8192,
14
+ "title": "Width",
15
+ "type": "integer"
16
+ }
17
+ },
18
+ "required": [
19
+ "width",
20
+ "height"
21
+ ],
22
+ "title": "Camera",
23
+ "type": "object",
24
+ "x-contract-version": "0.4.4"
25
+ }
@@ -23,5 +23,5 @@
23
23
  ],
24
24
  "title": "ClampInfo",
25
25
  "type": "object",
26
- "x-contract-version": "0.4.2"
26
+ "x-contract-version": "0.4.4"
27
27
  }
@@ -23,5 +23,5 @@
23
23
  ],
24
24
  "title": "CodeBundle",
25
25
  "type": "object",
26
- "x-contract-version": "0.4.2"
26
+ "x-contract-version": "0.4.4"
27
27
  }
@@ -17,5 +17,5 @@
17
17
  ],
18
18
  "title": "Concurrency",
19
19
  "type": "object",
20
- "x-contract-version": "0.4.2"
20
+ "x-contract-version": "0.4.4"
21
21
  }
@@ -55,5 +55,5 @@
55
55
  ],
56
56
  "title": "Conditions",
57
57
  "type": "object",
58
- "x-contract-version": "0.4.2"
58
+ "x-contract-version": "0.4.4"
59
59
  }
@@ -0,0 +1,29 @@
1
+ {
2
+ "additionalProperties": false,
3
+ "properties": {
4
+ "embodiment": {
5
+ "anyOf": [
6
+ {
7
+ "type": "string"
8
+ },
9
+ {
10
+ "type": "null"
11
+ }
12
+ ],
13
+ "default": null,
14
+ "description": "Which declared embodiment this session drives",
15
+ "title": "Embodiment"
16
+ },
17
+ "model": {
18
+ "description": "Deployment name to connect to",
19
+ "title": "Model",
20
+ "type": "string"
21
+ }
22
+ },
23
+ "required": [
24
+ "model"
25
+ ],
26
+ "title": "ConnectRequest",
27
+ "type": "object",
28
+ "x-contract-version": "0.4.4"
29
+ }