sequence-base 0.4.34__tar.gz → 0.5.0__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 (146) hide show
  1. {sequence_base-0.4.34 → sequence_base-0.5.0}/PKG-INFO +1 -1
  2. {sequence_base-0.4.34 → sequence_base-0.5.0}/pyproject.toml +1 -1
  3. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/__init__.py +9 -8
  4. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/version.py +3 -1
  5. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/__init__.py +40 -10
  6. sequence_base-0.5.0/sequence_base/contract/benchmarks.py +194 -0
  7. sequence_base-0.5.0/sequence_base/contract/connect.py +123 -0
  8. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/deployments.py +41 -25
  9. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/eval.py +29 -32
  10. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/flags.py +3 -4
  11. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/own_io.py +14 -47
  12. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/policy.py +105 -34
  13. sequence_base-0.5.0/sequence_base/contract/settings.py +357 -0
  14. sequence_base-0.5.0/sequence_base/contract/team.py +185 -0
  15. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/wire.py +9 -7
  16. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/presets/robot_arm.py +9 -7
  17. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schema_export.py +35 -13
  18. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActRequest.json +1 -15
  19. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActResponse.json +1 -15
  20. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActionChunk.json +1 -1
  21. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActionContract.json +1 -1
  22. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActionStep.json +1 -1
  23. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/AdapterPair.json +1 -1
  24. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/AddLocal.json +1 -1
  25. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Autoscaler.json +2 -23
  26. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BenchmarkRegisterRequest.json +31 -368
  27. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BenchmarkSpec.json +56 -135
  28. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BenchmarkStatusResponse.json +1 -1
  29. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BootstrapResponse.json +1 -1
  30. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Camera.json +3 -3
  31. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/CodeBundle.json +1 -1
  32. sequence_base-0.5.0/sequence_base/schemas/Concurrency.json +113 -0
  33. sequence_base-0.5.0/sequence_base/schemas/ConnectRequest.json +54 -0
  34. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ConnectResponse.json +95 -218
  35. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentAccepted.json +1 -1
  36. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentPolicy.json +61 -237
  37. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentRequest.json +81 -265
  38. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentStatusResponse.json +1 -1
  39. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ErrorBody.json +1 -1
  40. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ErrorCodes.json +1 -1
  41. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Estimate.json +1 -1
  42. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalDryRunResponse.json +1 -1
  43. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalReport.json +14 -29
  44. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalRequest.json +5 -41
  45. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalResponse.json +1 -1
  46. sequence_base-0.5.0/sequence_base/schemas/GroupObservation.json +41 -0
  47. sequence_base-0.5.0/sequence_base/schemas/GroupObserve.json +13 -0
  48. sequence_base-0.5.0/sequence_base/schemas/GroupObserved.json +16 -0
  49. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageFrame.json +1 -1
  50. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageSpec.json +1 -1
  51. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepAddLocal.json +1 -1
  52. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepApt.json +1 -1
  53. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepEnv.json +1 -1
  54. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepProject.json +1 -1
  55. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepRun.json +1 -1
  56. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepTemplateFiles.json +1 -1
  57. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepUvPip.json +1 -1
  58. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/InferParam.json +1 -1
  59. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Lease.json +1 -1
  60. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/MetricAgg.json +1 -1
  61. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Observation.json +1 -1
  62. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ObservationContract.json +3 -3
  63. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Observations.json +3 -3
  64. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ObserveRequest.json +1 -1
  65. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ObserveResponse.json +1 -1
  66. sequence_base-0.5.0/sequence_base/schemas/PlanAppend.json +13 -0
  67. sequence_base-0.5.0/sequence_base/schemas/PlanAppended.json +28 -0
  68. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/PolicyRegistration.json +87 -256
  69. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/PolicySpec.json +81 -253
  70. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Project.json +1 -1
  71. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Proprioception.json +1 -1
  72. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ReplaySpec.json +1 -1
  73. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Resources.json +1 -1
  74. sequence_base-0.5.0/sequence_base/schemas/RolloutResult.json +90 -0
  75. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SecretCreateRequest.json +1 -1
  76. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SecretInfo.json +1 -1
  77. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SecretRef.json +1 -1
  78. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SeqFlags.json +4 -2
  79. sequence_base-0.5.0/sequence_base/schemas/SettingsChange.json +56 -0
  80. sequence_base-0.5.0/sequence_base/schemas/SettingsChanged.json +137 -0
  81. sequence_base-0.5.0/sequence_base/schemas/SettingsView.json +402 -0
  82. sequence_base-0.5.0/sequence_base/schemas/Standby.json +92 -0
  83. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Stream.json +3 -3
  84. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/TaskAgg.json +1 -1
  85. sequence_base-0.5.0/sequence_base/schemas/TeamGroup.json +120 -0
  86. sequence_base-0.5.0/sequence_base/schemas/TeamGroups.json +135 -0
  87. sequence_base-0.5.0/sequence_base/schemas/TeamGroupsRequest.json +21 -0
  88. sequence_base-0.5.0/sequence_base/schemas/TeamMember.json +39 -0
  89. sequence_base-0.5.0/sequence_base/schemas/TeamPlans.json +51 -0
  90. sequence_base-0.5.0/sequence_base/schemas/TeamPlansWritten.json +30 -0
  91. sequence_base-0.5.0/sequence_base/schemas/TeamSpec.json +22 -0
  92. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/TemplateFiles.json +1 -1
  93. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Tensors.json +1 -1
  94. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Timeouts.json +1 -1
  95. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/UploadTarget.json +1 -1
  96. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeFile.json +1 -1
  97. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeInfo.json +1 -1
  98. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeMount.json +1 -1
  99. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeRef.json +1 -1
  100. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeUploadRequest.json +1 -1
  101. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeUploadResponse.json +1 -1
  102. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/WarmingError.json +1 -1
  103. sequence_base-0.4.34/sequence_base/contract/benchmarks.py +0 -305
  104. sequence_base-0.4.34/sequence_base/contract/connect.py +0 -74
  105. sequence_base-0.4.34/sequence_base/schemas/Actions.json +0 -63
  106. sequence_base-0.4.34/sequence_base/schemas/BenchmarkConditionSpec.json +0 -54
  107. sequence_base-0.4.34/sequence_base/schemas/Concurrency.json +0 -100
  108. sequence_base-0.4.34/sequence_base/schemas/Conditions.json +0 -59
  109. sequence_base-0.4.34/sequence_base/schemas/ConnectRequest.json +0 -16
  110. sequence_base-0.4.34/sequence_base/schemas/RenderSpec.json +0 -40
  111. sequence_base-0.4.34/sequence_base/schemas/RolloutResult.json +0 -59
  112. sequence_base-0.4.34/sequence_base/schemas/Step.json +0 -86
  113. sequence_base-0.4.34/sequence_base/schemas/Variant.json +0 -24
  114. {sequence_base-0.4.34 → sequence_base-0.5.0}/.gitignore +0 -0
  115. {sequence_base-0.4.34 → sequence_base-0.5.0}/README.md +0 -0
  116. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/auth.py +0 -0
  117. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/by_name.py +0 -0
  118. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/codec/__init__.py +0 -0
  119. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/codec/image.py +0 -0
  120. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/codec/marked.py +0 -0
  121. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/__init__.py +0 -0
  122. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/cards.py +0 -0
  123. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/headers.py +0 -0
  124. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/limits.py +0 -0
  125. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/construct.py +0 -0
  126. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/accounts.py +0 -0
  127. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/act.py +0 -0
  128. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/adapters.py +0 -0
  129. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/errors.py +0 -0
  130. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/io.py +0 -0
  131. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/obs_schedule.py +0 -0
  132. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/observe.py +0 -0
  133. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/retired.py +0 -0
  134. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/templates.py +0 -0
  135. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/volumes.py +0 -0
  136. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/episode.py +0 -0
  137. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/errors/__init__.py +0 -0
  138. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/errors/transport.py +0 -0
  139. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/msgpack_io.py +0 -0
  140. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/obs/__init__.py +0 -0
  141. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/obs/log.py +0 -0
  142. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/obs/rid.py +0 -0
  143. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/presets/__init__.py +0 -0
  144. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/presets/frames.py +0 -0
  145. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/telemetry/__init__.py +0 -0
  146. {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/telemetry/events.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sequence-base
3
- Version: 0.4.34
3
+ Version: 0.5.0
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
  Project-URL: Changelog, https://generalsequences.com/docs/changelog/
6
6
  Requires-Python: >=3.10
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sequence-base"
3
- version = "0.4.34"
3
+ version = "0.5.0"
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.10"
6
6
  dependencies = ["pydantic>=2.0"]
@@ -37,6 +37,11 @@ from sequence_base.contract import (
37
37
  parse_vol,
38
38
  TEMPLATE_SCHEME,
39
39
  parse_template,
40
+ SETTINGS,
41
+ Setting,
42
+ SettingsChange,
43
+ SettingsView,
44
+ SettingsChanged,
40
45
  AdapterPair,
41
46
  parse_pairs,
42
47
  ActionChunk,
@@ -44,14 +49,12 @@ from sequence_base.contract import (
44
49
  ActionSpace,
45
50
  ActionStep,
46
51
  Autoscaler,
47
- BenchmarkConditionSpec,
48
52
  BenchmarkRegisterRequest,
49
53
  BenchmarkStatusResponse,
50
54
  BenchmarkSpec,
51
55
  BootstrapResponse,
52
56
  CodeBundle,
53
57
  Concurrency,
54
- Conditions,
55
58
  ConnectRequest,
56
59
  ConnectResponse,
57
60
  DeploymentAccepted,
@@ -85,10 +88,8 @@ from sequence_base.contract import (
85
88
  PolicySpec,
86
89
  Observations,
87
90
  Stream,
88
- Actions,
89
91
  Tensors,
90
92
  Proprioception,
91
- RenderSpec,
92
93
  ReplaySpec,
93
94
  Resources,
94
95
  RolloutResult,
@@ -96,10 +97,8 @@ from sequence_base.contract import (
96
97
  SecretInfo,
97
98
  SecretRef,
98
99
  SeqFlags,
99
- Step,
100
100
  TaskAgg,
101
101
  Timeouts,
102
- Variant,
103
102
  VolumeMount,
104
103
  VolumeRef,
105
104
  WarmingError,
@@ -146,7 +145,7 @@ __all__ = [
146
145
  "FROZEN_PATH", "TemplateFiles", "ImageStepTemplateFiles", "Project", "ImageStepProject", "ImageStep", "ImageSpec",
147
146
  "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract",
148
147
  "PolicySpec", "PolicyRegistration", "PolicyConstructor",
149
- "Observations", "Stream", "Actions", "Tensors",
148
+ "Observations", "Stream", "Tensors",
150
149
 
151
150
  "MAX_CODE_BUNDLE_BYTES", "CodeBundle",
152
151
  "Resources", "Autoscaler", "Timeouts", "DeploymentPolicy", "InferParam", "DeploymentRequest",
@@ -154,7 +153,7 @@ __all__ = [
154
153
 
155
154
  "Lease", "ConnectRequest", "ConnectResponse",
156
155
 
157
- "Variant", "Conditions", "RenderSpec", "ReplaySpec", "Step", "BenchmarkSpec", "BenchmarkConditionSpec", "BenchmarkRegisterRequest", "BenchmarkStatusResponse",
156
+ "ReplaySpec", "BenchmarkSpec", "BenchmarkRegisterRequest", "BenchmarkStatusResponse",
158
157
  "EvalRequest", "Estimate", "EvalResponse", "EvalDryRunResponse", "RolloutResult",
159
158
  "EvalStatus", "TaskAgg", "MetricAgg", "EvalReport",
160
159
 
@@ -162,6 +161,8 @@ __all__ = [
162
161
 
163
162
  "VolumeFile", "VolumeUploadRequest", "UploadTarget", "VolumeUploadResponse", "VolumeInfo", "parse_vol",
164
163
 
164
+ "SETTINGS", "Setting", "SettingsChange", "SettingsView", "SettingsChanged",
165
+
165
166
  "TEMPLATE_SCHEME", "parse_template",
166
167
 
167
168
  "AdapterPair", "parse_pairs",
@@ -4,7 +4,9 @@
4
4
 
5
5
 
6
6
 
7
- CONTRACT_VERSION = "0.5.30"
7
+ CONTRACT_VERSION = "0.5.32"
8
+
9
+
8
10
 
9
11
 
10
12
 
@@ -45,7 +45,7 @@ from sequence_base.contract.policy import (
45
45
  )
46
46
 
47
47
 
48
- from sequence_base.contract.own_io import Actions, Observations, Stream, Tensors
48
+ from sequence_base.contract.own_io import Observations, Stream, Tensors
49
49
 
50
50
 
51
51
  from sequence_base.contract.deployments import (
@@ -63,19 +63,14 @@ from sequence_base.contract.deployments import (
63
63
  )
64
64
 
65
65
 
66
- from sequence_base.contract.connect import ConnectRequest, ConnectResponse, Lease
66
+ from sequence_base.contract.connect import ConnectRequest, ConnectResponse, Lease, Standby
67
67
 
68
68
 
69
69
  from sequence_base.contract.benchmarks import (
70
- BenchmarkConditionSpec,
71
70
  BenchmarkRegisterRequest,
72
71
  BenchmarkStatusResponse,
73
72
  BenchmarkSpec,
74
- Conditions,
75
- RenderSpec,
76
73
  ReplaySpec,
77
- Step,
78
- Variant,
79
74
  )
80
75
  from sequence_base.contract.eval import (
81
76
  Estimate,
@@ -117,6 +112,35 @@ from sequence_base.contract.volumes import (
117
112
  )
118
113
 
119
114
 
115
+ from sequence_base.contract.settings import (
116
+ SETTINGS,
117
+ Applied,
118
+ Setting,
119
+ SettingChanged,
120
+ SettingState,
121
+ SettingsChange,
122
+ SettingsChanged,
123
+ SettingsView,
124
+ )
125
+
126
+
127
+ from sequence_base.contract.team import (
128
+ TEAM_DEFAULT_GROUP,
129
+ GroupObservation,
130
+ GroupObserve,
131
+ GroupObserved,
132
+ PlanAppend,
133
+ PlanAppended,
134
+ TeamGroup,
135
+ TeamGroups,
136
+ TeamGroupsRequest,
137
+ TeamMember,
138
+ TeamPlans,
139
+ TeamPlansWritten,
140
+ TeamSpec,
141
+ )
142
+
143
+
120
144
  from sequence_base.contract.errors import ERRORS, ErrorBody, ErrorCode, ErrorSpec, WarmingError, code_for_status
121
145
 
122
146
  __all__ = [
@@ -130,15 +154,15 @@ __all__ = [
130
154
  "TemplateFiles", "ImageStepTemplateFiles", "Project", "ImageStepProject", "FROZEN_PATH", "ImageStep", "ImageSpec",
131
155
  "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract",
132
156
  "PolicySpec", "PolicyRegistration", "PolicyConstructor",
133
- "Observations", "Stream", "Actions", "Tensors",
157
+ "Observations", "Stream", "Tensors",
134
158
 
135
159
  "MAX_CODE_BUNDLE_BYTES", "CodeBundle",
136
160
  "Resources", "Autoscaler", "Timeouts", "DeploymentPolicy", "InferParam", "DeploymentRequest",
137
161
  "DeploymentAccepted", "DeploymentState", "DeploymentStatusResponse",
138
162
 
139
- "Lease", "ConnectRequest", "ConnectResponse",
163
+ "Lease", "ConnectRequest", "ConnectResponse", "Standby",
140
164
 
141
- "Variant", "Conditions", "RenderSpec", "ReplaySpec", "Step", "BenchmarkSpec", "BenchmarkConditionSpec", "BenchmarkRegisterRequest", "BenchmarkStatusResponse",
165
+ "ReplaySpec", "BenchmarkSpec", "BenchmarkRegisterRequest", "BenchmarkStatusResponse",
142
166
  "EvalRequest", "Estimate", "EvalResponse", "EvalDryRunResponse", "RolloutResult",
143
167
  "EvalStatus", "TaskAgg", "MetricAgg", "EvalReport",
144
168
 
@@ -147,6 +171,12 @@ __all__ = [
147
171
  "MAX_FILES", "MAX_UPLOAD_BYTES", "VolumeFile", "VolumeUploadRequest", "UploadTarget", "VolumeUploadResponse",
148
172
  "VolumeInfo", "check_volume_name", "parse_vol",
149
173
 
174
+ "SETTINGS", "Setting", "SettingsChange", "Applied", "SettingState", "SettingsView", "SettingChanged",
175
+ "SettingsChanged",
176
+
177
+ "TEAM_DEFAULT_GROUP", "TeamSpec", "TeamGroupsRequest", "GroupObservation", "TeamMember", "TeamGroup", "TeamGroups",
178
+ "TeamPlans", "TeamPlansWritten", "PlanAppend", "PlanAppended", "GroupObserve", "GroupObserved",
179
+
150
180
  "TEMPLATE_SCHEME", "parse_template",
151
181
 
152
182
  "AdapterPair", "parse_pairs",
@@ -0,0 +1,194 @@
1
+ """
2
+ Contract 5 (registration half) - a benchmark is the env you already have, run as it is: a short class of yours marks
3
+ three methods - @seq.setup builds this eval's worlds after the machine's snapshot, @seq.reset starts an episode of a task
4
+ at a seed, @seq.step plays one action and says what came of it - and declares its tasks, its seeds and how long an episode
5
+ may run. The platform reads none of its observations or actions: they go to the policy, and come from it, as a robot's
6
+ do. The eval *run* wire types (RolloutResult, EvalReport, ...) live in contract/eval.py.
7
+
8
+
9
+ """
10
+ from __future__ import annotations
11
+
12
+ from typing import Literal
13
+
14
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
15
+
16
+ from sequence_base.constants.cards import DRIVER, check_driver
17
+ from sequence_base.constants.limits import MAX_ENVS, TASK_DESCRIPTION_MAX
18
+ from sequence_base.contract.accounts import SecretRef
19
+ from sequence_base.contract.deployments import CodeBundle, DeploymentState, InferParam
20
+ from sequence_base.contract.flags import BENCHMARK_BINDABLE, SeqFlags
21
+ from sequence_base.contract.policy import KIND_NAME, ImageSpec, VolumeRef
22
+
23
+ __all__ = [
24
+ "ReplaySpec",
25
+ "BenchmarkSpec",
26
+ "BenchmarkRegisterRequest",
27
+ "BenchmarkStatusResponse",
28
+ ]
29
+
30
+
31
+ TASK_NAME = r"^[A-Za-z0-9][A-Za-z0-9._/:-]{0,127}$"
32
+
33
+
34
+ def _check_tasks(tasks: dict, seeds: list, max_seconds) -> None:
35
+ import re as _re
36
+
37
+ if not tasks:
38
+ raise ValueError("tasks names at least one task: {name: description}")
39
+ for name, text in tasks.items():
40
+ if not _re.match(TASK_NAME, name):
41
+ raise ValueError(f"task {name!r}: 1-128 letters, digits, '.', '_', '/', ':' or '-', starting with a letter "
42
+ "or digit")
43
+ if len(text or "") > TASK_DESCRIPTION_MAX:
44
+ raise ValueError(f"tasks[{name!r}] is {len(text)} characters: at most {TASK_DESCRIPTION_MAX}")
45
+ if not seeds:
46
+ raise ValueError("seeds names at least one seed")
47
+ if len(set(seeds)) != len(seeds):
48
+ raise ValueError("seeds names each seed once")
49
+ limits = max_seconds if isinstance(max_seconds, dict) else {"": max_seconds}
50
+ for task, limit in limits.items():
51
+ if task and task not in tasks:
52
+ raise ValueError(f"max_seconds names {task!r}, which is not one of its tasks")
53
+ if not limit > 0:
54
+ raise ValueError(f"max_seconds{'[' + repr(task) + ']' if task else ''} must be above 0 s, not {limit!r}")
55
+
56
+
57
+ class ReplaySpec(BaseModel):
58
+ """a.k.a. `seq.Replay` — declares that the platform records the eval's 3D replay: each step every node's world
59
+ transform, drawn in the owner's browser after the eval. `engine` picks the platform's
60
+ adapter that reads the simulation's state ("mujoco", "sapien", "isaac"); "own" means the benchmark hands the frames itself
61
+ (`seq.replay.scene` / `seq.replay.frame`); None takes the benchmark's own `engine`. `state` names the benchmark
62
+ method an adapter calls for the engine's state of an env (or of a batched benchmark's slots), `looks` the one that
63
+ says what the adapter cannot read - a colour or a visibility each episode sets. Whether an eval records it is the
64
+ eval's `replay` ("3d" by default, "none")."""
65
+
66
+ model_config = ConfigDict(extra="forbid")
67
+
68
+ engine: Literal["mujoco", "sapien", "isaac", "own"] | None = Field(
69
+ None, description="The adapter that reads the simulation: 'mujoco' (incl. MuJoCo Warp), 'sapien', 'isaac', or "
70
+ "'own' (the benchmark hands frames itself); None: the benchmark's engine")
71
+ state: str | None = Field(None, pattern=r"^[A-Za-z_][A-Za-z0-9_]*$",
72
+ description="The benchmark method an adapter calls for an env's (or slots') engine state")
73
+ looks: str | None = Field(None, pattern=r"^[A-Za-z_][A-Za-z0-9_]*$",
74
+ description="The benchmark method that says each episode's colours or visibility")
75
+
76
+
77
+ class BenchmarkSpec(BaseModel):
78
+ """What `@seq.benchmark(...)` and its marked methods add up to, as an eval runs it. `bindings` names the methods:
79
+ RESET and STEP always, SETUP when it builds its worlds after the machine's snapshot - which a vectorized env, one
80
+ stepping `worlds` worlds a call (@seq.concurrent(sizes=[N]) on its step), always does. `max_seconds` is an episode's
81
+ time on the robot's clock, the same for every task or {task: seconds}; `assets` are versioned scene volumes mounted
82
+ at /assets; `secrets` by name."""
83
+
84
+ model_config = ConfigDict(extra="forbid")
85
+
86
+ name: str
87
+ image: ImageSpec
88
+ tasks: dict[str, str] = Field(..., description="Each task's name and what it asks of the robot, shown beside it")
89
+ seeds: list[int] = Field(..., description="The seeds an episode starts at; trial k of a task runs seeds[k % len]")
90
+ max_seconds: float | dict[str, float] = Field(..., description="An episode's time limit, or {task: seconds}")
91
+ handler_ref: str
92
+ bindings: dict[SeqFlags, str] = Field(..., description="SETUP / RESET / STEP -> method name")
93
+
94
+
95
+ worlds: int | None = Field(default=None, ge=1, le=MAX_ENVS)
96
+
97
+ gpu: str | None = None
98
+
99
+ driver: str | None = Field(default=None, pattern=DRIVER)
100
+ assets: list[VolumeRef] = Field(default_factory=list)
101
+
102
+ replay: ReplaySpec | None = None
103
+ cpu: int | None = None
104
+ memory_gb: int | None = None
105
+ secrets: list[SecretRef] = Field(default_factory=list)
106
+
107
+ engine: str | None = Field(default=None, pattern=KIND_NAME)
108
+
109
+ @model_validator(mode="after")
110
+ def _tasks(self) -> "BenchmarkSpec":
111
+ _check_tasks(self.tasks, self.seeds, self.max_seconds)
112
+ return self
113
+
114
+ @model_validator(mode="after")
115
+ def _bindings(self) -> "BenchmarkSpec":
116
+ bad = set(self.bindings) - set(BENCHMARK_BINDABLE)
117
+ if bad:
118
+ names = ", ".join(sorted(f.name or str(f.value) for f in bad))
119
+ raise ValueError(f"a benchmark marks @seq.setup, @seq.reset and @seq.step only; got {names}")
120
+ missing = [f.name for f in (SeqFlags.RESET, SeqFlags.STEP) if f not in self.bindings]
121
+ if missing:
122
+ raise ValueError(f"a benchmark marks @seq.reset and @seq.step; {', '.join(missing).lower()} is missing")
123
+ if self.worlds is not None and SeqFlags.SETUP not in self.bindings:
124
+ raise ValueError("a vectorized benchmark (@seq.concurrent on its step) builds its worlds in @seq.setup")
125
+ return self
126
+
127
+ @model_validator(mode="after")
128
+ def _driver_of_a_card(self) -> "BenchmarkSpec":
129
+ check_driver(self.driver, self.gpu)
130
+ return self
131
+
132
+
133
+ class BenchmarkRegisterRequest(BaseModel):
134
+ """POST /v1/benchmarks - what `seq benchmark register` sends: the declaration, the code, and the parameters its
135
+ @seq.setup takes beside worlds and policy (each settable by an eval's --param, with its type)."""
136
+
137
+ model_config = ConfigDict(extra="forbid")
138
+
139
+ name: str
140
+ image: ImageSpec
141
+ tasks: dict[str, str]
142
+ seeds: list[int]
143
+ max_seconds: float | dict[str, float]
144
+ handler_ref: str
145
+ worlds: int | None = Field(default=None, ge=1, le=MAX_ENVS)
146
+ assets: list[VolumeRef] = Field(default_factory=list)
147
+ replay: ReplaySpec | None = None
148
+ cpu: int | None = None
149
+ memory_gb: int | None = None
150
+
151
+ code: CodeBundle | None = None
152
+
153
+ freeze: bool | None = None
154
+ secrets: list[SecretRef] = Field(default_factory=list)
155
+ gpu: str | None = Field(default=None, max_length=32)
156
+
157
+
158
+ driver: str | None = Field(default=None, pattern=DRIVER,
159
+ description='The NVIDIA driver its card must have, by major version: "580"')
160
+
161
+
162
+ params: dict[str, InferParam] | None = Field(default=None, max_length=32)
163
+
164
+ image_context: CodeBundle | None = None
165
+ engine: str | None = Field(default=None, pattern=KIND_NAME)
166
+
167
+ @model_validator(mode="after")
168
+ def _tasks(self) -> "BenchmarkRegisterRequest":
169
+ _check_tasks(self.tasks, self.seeds, self.max_seconds)
170
+ return self
171
+
172
+ @model_validator(mode="after")
173
+ def _param_names(self) -> "BenchmarkRegisterRequest":
174
+ for name in self.params or {}:
175
+ if not name.isidentifier() or name.startswith("_") or name in ("worlds", "policy"):
176
+ raise ValueError(f"setup parameter {name!r} is not a public Python identifier other than worlds and "
177
+ "policy")
178
+ return self
179
+
180
+ @model_validator(mode="after")
181
+ def _driver_of_a_card(self) -> "BenchmarkRegisterRequest":
182
+ check_driver(self.driver, self.gpu)
183
+ return self
184
+
185
+
186
+ class BenchmarkStatusResponse(BaseModel):
187
+ """GET /v1/benchmarks/{name} — the build state of a registered benchmark (same lifecycle as a deployment:
188
+ building → ready | failed), with the failure reason when failed."""
189
+
190
+ model_config = ConfigDict(extra="forbid")
191
+
192
+ name: str
193
+ status: DeploymentState
194
+ error: str | None = None
@@ -0,0 +1,123 @@
1
+ """
2
+ Contract 3 — connect / lease (client → gateway; control plane, first call + renewal).
3
+
4
+ Control plane / data plane split: `connect(model)` goes through the gateway once (admission → acquire →
5
+ ensure worker up) and hands back the *direct* coordinates the client then uses to hit the worker's
6
+ `/act` without the gateway in the hot path (contract 4). The cold-start fallback is a defined wire body,
7
+ not an HTTP header alone — a 503 returns `WarmingError` (contract/errors.py), so `503 + Retry-After`
8
+ and the warming ETA are typed and checkable.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ from datetime import datetime
13
+ from typing import Any, Literal
14
+
15
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
16
+
17
+
18
+ from sequence_base.contract.errors import WarmingError
19
+ from sequence_base.contract.own_io import Observations
20
+ from sequence_base.contract.retired import dropped
21
+ from sequence_base.contract.team import check_name
22
+
23
+ __all__ = ["Lease", "ConnectRequest", "ConnectResponse", "Standby", "WarmingError"]
24
+
25
+
26
+ class Lease(BaseModel):
27
+ """A time-boxed grant of the direct coordinates. Renewed before `expires_at`; `epoch` is the
28
+ worker/secret generation — a client holding a stale epoch against a new worker gets 401 and must
29
+ re-connect."""
30
+
31
+ model_config = ConfigDict(extra="forbid")
32
+
33
+ ttl_s: int
34
+ expires_at: datetime
35
+ epoch: int = Field(..., description="Worker/secret generation counter; rolls on worker change")
36
+
37
+
38
+ class ConnectRequest(BaseModel):
39
+ model_config = ConfigDict(extra="forbid")
40
+
41
+ model: str = Field(..., description="Deployment name to connect to")
42
+
43
+
44
+
45
+
46
+ standby: bool = Field(default=False, description="this SDK keeps a standby connection and switches to it")
47
+
48
+
49
+ switched: bool = Field(default=False, description="this robot just switched to the standby copy it was handed")
50
+
51
+
52
+
53
+
54
+ team: str | None = Field(default=None, description="the team this robot joins, by name")
55
+ group: str | None = Field(default=None, description="its group in that team; None: the default group")
56
+
57
+ @model_validator(mode="before")
58
+ @classmethod
59
+ def _retired(cls, data: Any) -> Any:
60
+ return dropped(data, "embodiment")
61
+
62
+ @model_validator(mode="after")
63
+ def _a_group_is_a_teams(self) -> "ConnectRequest":
64
+ if self.team is not None:
65
+ check_name(self.team, "team")
66
+ if self.group is not None:
67
+ if self.team is None:
68
+ raise ValueError("a group is a team's: say the team too")
69
+ check_name(self.group, "group")
70
+ return self
71
+
72
+
73
+ class Standby(BaseModel):
74
+ """The standby copy a connect hands a robot whose SDK keeps one (ConnectRequest.standby): another worker of the
75
+ deployment, on another machine, holding a place for it - no seat: its acts go there only once the copy it is on
76
+ cannot be reached, and its next connect says it switched. Its coordinates as the primary's are: where to send, how to
77
+ check its certificate (pinned by cert_fingerprint, or "public" for tls_name, masked as the primary's) and the bearer
78
+ and lease its acts carry."""
79
+
80
+ model_config = ConfigDict(extra="forbid")
81
+
82
+ worker_url: str = Field(..., description="The standby worker's direct URL")
83
+
84
+
85
+ cert_fingerprint: str | None = Field(..., description="Its certificate's fingerprint the SDK pins; null where "
86
+ "tls is public")
87
+ direct_secret: str = Field(..., description="Bearer for its /act; valid within its lease")
88
+ tls: Literal["pinned", "public"] = Field(default="pinned", description="how its certificate is checked")
89
+ tls_name: str | None = Field(default=None, description="the name a public certificate is checked for, masked")
90
+ lease: Lease
91
+
92
+
93
+ class ConnectResponse(BaseModel):
94
+ """200 — the full set of coordinates for a direct worker connection.
95
+
96
+ `direct_secret` is a plaintext platform-minted bearer for the worker's `/act`; it is on the
97
+ allow-list of fields permitted to carry a secret value in the down direction (contract 6 / goal 15)."""
98
+
99
+ model_config = ConfigDict(extra="forbid")
100
+
101
+ worker_url: str = Field(..., description="Worker static-IP direct URL, e.g. https://<ip>:8080")
102
+ cert_fingerprint: str = Field(..., description="Self-signed cert fingerprint the SDK pins")
103
+ direct_secret: str = Field(..., description="Bearer for the worker /act; valid within the lease")
104
+ lease: Lease
105
+
106
+
107
+ hz: float | None = Field(default=None, gt=0, le=1000)
108
+ action_chunk_len: int | None = Field(default=None, ge=1, le=100_000)
109
+ action_chunk_exec_len: int | None = Field(default=None, ge=1, le=100_000)
110
+
111
+ io: str | None = None
112
+
113
+
114
+ observations: Observations | None = None
115
+
116
+
117
+ standby: Standby | None = None
118
+
119
+ @model_validator(mode="before")
120
+ @classmethod
121
+ def _retired(cls, data: Any) -> Any:
122
+
123
+ return dropped(data, "embodiment", "feedback", "action", "observation", "actions")
@@ -3,7 +3,7 @@ Contract 2 — `POST /v1/deployments` (SDK `seq deploy` → gateway) and its res
3
3
 
4
4
  The request is the normalized wire form of a PolicySpec: one big body (new config adds a field, never a
5
5
  new endpoint) whose sub-shapes reuse contract 1's types
6
- (ImageSpec, VolumeMount, Concurrency, ActionContract). Field names align with the PolicySpec side —
6
+ (ImageSpec, VolumeMount, Concurrency). Field names align with the PolicySpec side —
7
7
  `gpu` is normalized to list[str] here, the memory field is `memory_gb` (goal 7).
8
8
 
9
9
  Responses have no open-ended fields: 202 → status fixed to `building`; GET → status is a restricted
@@ -21,16 +21,17 @@ from typing import Any, Literal
21
21
  from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
22
22
 
23
23
  from sequence_base.contract.accounts import SecretRef
24
- from sequence_base.contract.io import ObservationContract
25
- from sequence_base.contract.own_io import Actions, Observations, Tensors, check_own_io
24
+ from sequence_base.contract.own_io import Observations, Tensors
26
25
  from sequence_base.contract.retired import dropped
26
+ from sequence_base.contract.team import TeamSpec
27
27
  from sequence_base.contract.policy import (
28
28
  KIND_NAME,
29
- ActionContract,
29
+ SCALING_RETIRED,
30
30
  Concurrency,
31
31
  Episodes,
32
32
  ImageSpec,
33
33
  VolumeMount,
34
+ check_chunk_lens,
34
35
  )
35
36
 
36
37
  __all__ = [
@@ -79,20 +80,22 @@ class Resources(BaseModel):
79
80
 
80
81
 
81
82
  class Autoscaler(BaseModel):
82
- """How the deployment scales. Defaults mirror PolicySpec so an omitted block scales to zero."""
83
+ """How the deployment scales. Defaults mirror PolicySpec so an omitted block scales to zero: machines always on,
84
+ spare ones beside those in use, and the most GPUs it holds - the rest the platform's (contract 0.5.31;
85
+ policy.SCALING_RETIRED, read and dropped)."""
83
86
 
84
87
  model_config = ConfigDict(extra="forbid")
85
88
 
89
+ @model_validator(mode="before")
90
+ @classmethod
91
+ def _retired(cls, data: Any) -> Any:
92
+ return dropped(data, *SCALING_RETIRED)
93
+
86
94
  min_containers: int = 0
87
95
 
88
96
 
89
97
  max_gpus: int | None = Field(default=None, ge=1, le=256)
90
98
  buffer_containers: int | None = None
91
- scaledown_window: int = 600
92
-
93
-
94
- on_full: Literal["queue", "reject"] = "queue"
95
- queue_timeout_s: int = Field(default=120, ge=5, le=3600)
96
99
 
97
100
 
98
101
  class Timeouts(BaseModel):
@@ -165,10 +168,11 @@ def describe(param: "InferParam") -> str:
165
168
 
166
169
 
167
170
  class DeploymentPolicy(BaseModel):
168
- """The policy block of the deployments body. Only `handler_ref` is required. The robot-arm preset's contracts
169
- (`action`, `observation`) are optional since contract 0.4.14: a deployment that declares none is held to nothing and
170
- its inputs / outputs pass through the worker untouched. One stored from before contract 0.5.29 reads with its
171
- `embodiments` and `feedback` dropped (contract.retired).
171
+ """The policy block of the deployments body. Only `handler_ref` is required. Its inputs and outputs are its own
172
+ (north star 5): they pass through the worker untouched. One stored from before contract 0.5.29 reads with its
173
+ `embodiments` and `feedback` dropped, and one from before 0.5.31 with the robot-arm preset's `action`,
174
+ `observation` and `action_declared` and its `actions` (seq.Actions; its hz and action chunk lengths are fields of
175
+ its own now) dropped (contract.retired).
172
176
 
173
177
  `secrets` carries the policy's declared secret BUNDLES BY NAME ONLY (list[SecretRef]) — the gateway
174
178
  validates each name exists and belongs to the deployer at submit time, and the
@@ -181,24 +185,24 @@ class DeploymentPolicy(BaseModel):
181
185
  @model_validator(mode="before")
182
186
  @classmethod
183
187
  def _retired(cls, data: Any) -> Any:
184
- return dropped(data, "embodiments", "feedback")
188
+ return dropped(data, "embodiments", "feedback", "action", "observation", "action_declared", "actions")
185
189
 
186
190
  handler_ref: str
187
- action: ActionContract | None = None
188
191
 
189
192
 
190
- episodes: Episodes | None = None
191
193
 
192
194
 
193
- streaming: bool = Field(default=False, exclude=True)
194
- secrets: list[SecretRef] = Field(default_factory=list)
195
195
 
196
- observation: ObservationContract | None = None
196
+ hz: float | None = Field(default=None, gt=0, le=1000)
197
+ action_chunk_len: int | None = Field(default=None, ge=1, le=100_000)
198
+ action_chunk_exec_len: int | None = Field(default=None, ge=1, le=100_000)
197
199
 
198
200
 
201
+ episodes: Episodes | None = None
199
202
 
200
203
 
201
- action_declared: bool | None = None
204
+ streaming: bool = Field(default=False, exclude=True)
205
+ secrets: list[SecretRef] = Field(default_factory=list)
202
206
 
203
207
 
204
208
  io: str | None = Field(default=None, max_length=4000)
@@ -220,11 +224,23 @@ class DeploymentPolicy(BaseModel):
220
224
  plan_every_s: float | None = Field(default=None, gt=0)
221
225
 
222
226
 
223
-
224
227
  observations: Observations | None = None
225
- actions: Actions | None = None
226
228
  tensors: Tensors | None = None
227
229
 
230
+
231
+ team: TeamSpec | None = None
232
+
233
+ @model_validator(mode="after")
234
+ def _team_answers_no_act(self) -> "DeploymentPolicy":
235
+ if self.team is not None:
236
+ said = [name for name in ("hz", "action_chunk_len", "action_chunk_exec_len", "observations", "tensors")
237
+ if getattr(self, name) is not None]
238
+ if said:
239
+ raise ValueError(f"a team answers no act, so it declares no {', '.join(said)}")
240
+ if self.plan_every_s is None:
241
+ raise ValueError("a team plans: its policy block says plan_every_s")
242
+ return self
243
+
228
244
  @model_validator(mode="after")
229
245
  def _episodes_of_streaming(self) -> "DeploymentPolicy":
230
246
 
@@ -237,8 +253,8 @@ class DeploymentPolicy(BaseModel):
237
253
  return self
238
254
 
239
255
  @model_validator(mode="after")
240
- def _own_io(self) -> "DeploymentPolicy":
241
- check_own_io(self)
256
+ def _plays_what_it_holds(self) -> "DeploymentPolicy":
257
+ check_chunk_lens(self.action_chunk_len, self.action_chunk_exec_len)
242
258
  return self
243
259
 
244
260
  @model_validator(mode="after")