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.
- {sequence_base-0.4.34 → sequence_base-0.5.0}/PKG-INFO +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/pyproject.toml +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/__init__.py +9 -8
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/version.py +3 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/__init__.py +40 -10
- sequence_base-0.5.0/sequence_base/contract/benchmarks.py +194 -0
- sequence_base-0.5.0/sequence_base/contract/connect.py +123 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/deployments.py +41 -25
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/eval.py +29 -32
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/flags.py +3 -4
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/own_io.py +14 -47
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/policy.py +105 -34
- sequence_base-0.5.0/sequence_base/contract/settings.py +357 -0
- sequence_base-0.5.0/sequence_base/contract/team.py +185 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/wire.py +9 -7
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/presets/robot_arm.py +9 -7
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schema_export.py +35 -13
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActRequest.json +1 -15
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActResponse.json +1 -15
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActionChunk.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActionContract.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ActionStep.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/AdapterPair.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/AddLocal.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Autoscaler.json +2 -23
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BenchmarkRegisterRequest.json +31 -368
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BenchmarkSpec.json +56 -135
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BenchmarkStatusResponse.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/BootstrapResponse.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Camera.json +3 -3
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/CodeBundle.json +1 -1
- sequence_base-0.5.0/sequence_base/schemas/Concurrency.json +113 -0
- sequence_base-0.5.0/sequence_base/schemas/ConnectRequest.json +54 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ConnectResponse.json +95 -218
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentAccepted.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentPolicy.json +61 -237
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentRequest.json +81 -265
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/DeploymentStatusResponse.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ErrorBody.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ErrorCodes.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Estimate.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalDryRunResponse.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalReport.json +14 -29
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalRequest.json +5 -41
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/EvalResponse.json +1 -1
- sequence_base-0.5.0/sequence_base/schemas/GroupObservation.json +41 -0
- sequence_base-0.5.0/sequence_base/schemas/GroupObserve.json +13 -0
- sequence_base-0.5.0/sequence_base/schemas/GroupObserved.json +16 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageFrame.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageSpec.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepAddLocal.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepApt.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepEnv.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepProject.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepRun.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepTemplateFiles.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ImageStepUvPip.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/InferParam.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Lease.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/MetricAgg.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Observation.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ObservationContract.json +3 -3
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Observations.json +3 -3
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ObserveRequest.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ObserveResponse.json +1 -1
- sequence_base-0.5.0/sequence_base/schemas/PlanAppend.json +13 -0
- sequence_base-0.5.0/sequence_base/schemas/PlanAppended.json +28 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/PolicyRegistration.json +87 -256
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/PolicySpec.json +81 -253
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Project.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Proprioception.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/ReplaySpec.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Resources.json +1 -1
- sequence_base-0.5.0/sequence_base/schemas/RolloutResult.json +90 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SecretCreateRequest.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SecretInfo.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SecretRef.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/SeqFlags.json +4 -2
- sequence_base-0.5.0/sequence_base/schemas/SettingsChange.json +56 -0
- sequence_base-0.5.0/sequence_base/schemas/SettingsChanged.json +137 -0
- sequence_base-0.5.0/sequence_base/schemas/SettingsView.json +402 -0
- sequence_base-0.5.0/sequence_base/schemas/Standby.json +92 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Stream.json +3 -3
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/TaskAgg.json +1 -1
- sequence_base-0.5.0/sequence_base/schemas/TeamGroup.json +120 -0
- sequence_base-0.5.0/sequence_base/schemas/TeamGroups.json +135 -0
- sequence_base-0.5.0/sequence_base/schemas/TeamGroupsRequest.json +21 -0
- sequence_base-0.5.0/sequence_base/schemas/TeamMember.json +39 -0
- sequence_base-0.5.0/sequence_base/schemas/TeamPlans.json +51 -0
- sequence_base-0.5.0/sequence_base/schemas/TeamPlansWritten.json +30 -0
- sequence_base-0.5.0/sequence_base/schemas/TeamSpec.json +22 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/TemplateFiles.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Tensors.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/Timeouts.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/UploadTarget.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeFile.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeInfo.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeMount.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeRef.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeUploadRequest.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/VolumeUploadResponse.json +1 -1
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/schemas/WarmingError.json +1 -1
- sequence_base-0.4.34/sequence_base/contract/benchmarks.py +0 -305
- sequence_base-0.4.34/sequence_base/contract/connect.py +0 -74
- sequence_base-0.4.34/sequence_base/schemas/Actions.json +0 -63
- sequence_base-0.4.34/sequence_base/schemas/BenchmarkConditionSpec.json +0 -54
- sequence_base-0.4.34/sequence_base/schemas/Concurrency.json +0 -100
- sequence_base-0.4.34/sequence_base/schemas/Conditions.json +0 -59
- sequence_base-0.4.34/sequence_base/schemas/ConnectRequest.json +0 -16
- sequence_base-0.4.34/sequence_base/schemas/RenderSpec.json +0 -40
- sequence_base-0.4.34/sequence_base/schemas/RolloutResult.json +0 -59
- sequence_base-0.4.34/sequence_base/schemas/Step.json +0 -86
- sequence_base-0.4.34/sequence_base/schemas/Variant.json +0 -24
- {sequence_base-0.4.34 → sequence_base-0.5.0}/.gitignore +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/README.md +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/auth.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/by_name.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/codec/__init__.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/codec/image.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/codec/marked.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/__init__.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/cards.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/headers.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/constants/limits.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/construct.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/accounts.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/act.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/adapters.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/errors.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/io.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/obs_schedule.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/observe.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/retired.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/templates.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/contract/volumes.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/episode.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/errors/__init__.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/errors/transport.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/msgpack_io.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/obs/__init__.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/obs/log.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/obs/rid.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/presets/__init__.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/presets/frames.py +0 -0
- {sequence_base-0.4.34 → sequence_base-0.5.0}/sequence_base/telemetry/__init__.py +0 -0
- {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.
|
|
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.
|
|
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", "
|
|
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
|
-
"
|
|
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",
|
|
@@ -45,7 +45,7 @@ from sequence_base.contract.policy import (
|
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
from sequence_base.contract.own_io import
|
|
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", "
|
|
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
|
-
"
|
|
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
|
|
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.
|
|
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
|
-
|
|
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.
|
|
169
|
-
(
|
|
170
|
-
|
|
171
|
-
`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
241
|
-
|
|
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")
|