sequence-base 0.4.31__tar.gz → 0.4.32__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 (126) hide show
  1. {sequence_base-0.4.31 → sequence_base-0.4.32}/PKG-INFO +1 -1
  2. {sequence_base-0.4.31 → sequence_base-0.4.32}/pyproject.toml +1 -1
  3. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/__init__.py +2 -6
  4. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/by_name.py +44 -7
  5. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/constants/version.py +2 -1
  6. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/__init__.py +1 -2
  7. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/connect.py +12 -5
  8. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/deployments.py +11 -9
  9. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/io.py +3 -4
  10. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/own_io.py +1 -1
  11. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/policy.py +10 -9
  12. sequence_base-0.4.32/sequence_base/contract/retired.py +22 -0
  13. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/wire.py +9 -9
  14. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/presets/robot_arm.py +1 -10
  15. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schema_export.py +0 -2
  16. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ActRequest.json +1 -28
  17. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ActResponse.json +1 -1
  18. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ActionChunk.json +1 -1
  19. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ActionContract.json +1 -1
  20. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ActionStep.json +1 -1
  21. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Actions.json +1 -1
  22. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/AdapterPair.json +1 -1
  23. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/AddLocal.json +1 -1
  24. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Autoscaler.json +1 -1
  25. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/BenchmarkConditionSpec.json +1 -1
  26. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/BenchmarkRegisterRequest.json +1 -1
  27. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/BenchmarkSpec.json +2 -2
  28. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/BenchmarkStatusResponse.json +1 -1
  29. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/BootstrapResponse.json +1 -1
  30. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Camera.json +1 -1
  31. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/CodeBundle.json +1 -1
  32. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Concurrency.json +1 -1
  33. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Conditions.json +1 -1
  34. sequence_base-0.4.32/sequence_base/schemas/ConnectRequest.json +16 -0
  35. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ConnectResponse.json +1 -25
  36. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/DeploymentAccepted.json +1 -1
  37. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/DeploymentPolicy.json +2 -59
  38. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/DeploymentRequest.json +2 -59
  39. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/DeploymentStatusResponse.json +1 -1
  40. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ErrorBody.json +1 -1
  41. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ErrorCodes.json +1 -1
  42. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Estimate.json +1 -1
  43. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/EvalDryRunResponse.json +1 -1
  44. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/EvalReport.json +1 -1
  45. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/EvalRequest.json +1 -1
  46. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/EvalResponse.json +1 -1
  47. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageFrame.json +1 -1
  48. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageSpec.json +1 -1
  49. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageStepAddLocal.json +1 -1
  50. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageStepApt.json +1 -1
  51. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageStepEnv.json +1 -1
  52. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageStepProject.json +1 -1
  53. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageStepRun.json +1 -1
  54. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageStepTemplateFiles.json +1 -1
  55. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ImageStepUvPip.json +1 -1
  56. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/InferParam.json +1 -1
  57. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Lease.json +1 -1
  58. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/MetricAgg.json +1 -1
  59. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Observation.json +1 -1
  60. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ObservationContract.json +1 -1
  61. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Observations.json +1 -1
  62. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ObserveRequest.json +1 -1
  63. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ObserveResponse.json +1 -1
  64. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/PolicyRegistration.json +3 -60
  65. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/PolicySpec.json +2 -59
  66. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Project.json +1 -1
  67. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Proprioception.json +1 -1
  68. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/RenderSpec.json +1 -1
  69. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/ReplaySpec.json +1 -1
  70. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Resources.json +1 -1
  71. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/RolloutResult.json +1 -1
  72. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/SecretCreateRequest.json +1 -1
  73. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/SecretInfo.json +1 -1
  74. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/SecretRef.json +1 -1
  75. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/SeqFlags.json +1 -1
  76. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Step.json +1 -1
  77. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Stream.json +1 -1
  78. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/TaskAgg.json +1 -1
  79. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/TemplateFiles.json +1 -1
  80. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Tensors.json +1 -1
  81. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Timeouts.json +1 -1
  82. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/UploadTarget.json +1 -1
  83. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/Variant.json +1 -1
  84. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/VolumeFile.json +1 -1
  85. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/VolumeInfo.json +1 -1
  86. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/VolumeMount.json +1 -1
  87. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/VolumeRef.json +1 -1
  88. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/VolumeUploadRequest.json +1 -1
  89. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/VolumeUploadResponse.json +1 -1
  90. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/schemas/WarmingError.json +1 -1
  91. sequence_base-0.4.31/sequence_base/feedback.py +0 -106
  92. sequence_base-0.4.31/sequence_base/schemas/ConnectRequest.json +0 -29
  93. sequence_base-0.4.31/sequence_base/schemas/Embodiment.json +0 -301
  94. {sequence_base-0.4.31 → sequence_base-0.4.32}/.gitignore +0 -0
  95. {sequence_base-0.4.31 → sequence_base-0.4.32}/README.md +0 -0
  96. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/auth.py +0 -0
  97. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/codec/__init__.py +0 -0
  98. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/codec/image.py +0 -0
  99. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/codec/marked.py +0 -0
  100. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/constants/__init__.py +0 -0
  101. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/constants/cards.py +0 -0
  102. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/constants/headers.py +0 -0
  103. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/constants/limits.py +0 -0
  104. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/construct.py +0 -0
  105. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/accounts.py +0 -0
  106. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/act.py +0 -0
  107. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/adapters.py +0 -0
  108. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/benchmarks.py +0 -0
  109. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/errors.py +0 -0
  110. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/eval.py +0 -0
  111. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/flags.py +0 -0
  112. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/obs_schedule.py +0 -0
  113. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/observe.py +0 -0
  114. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/templates.py +0 -0
  115. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/contract/volumes.py +0 -0
  116. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/episode.py +0 -0
  117. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/errors/__init__.py +0 -0
  118. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/errors/transport.py +0 -0
  119. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/msgpack_io.py +0 -0
  120. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/obs/__init__.py +0 -0
  121. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/obs/log.py +0 -0
  122. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/obs/rid.py +0 -0
  123. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/presets/__init__.py +0 -0
  124. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/presets/frames.py +0 -0
  125. {sequence_base-0.4.31 → sequence_base-0.4.32}/sequence_base/telemetry/__init__.py +0 -0
  126. {sequence_base-0.4.31 → sequence_base-0.4.32}/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.31
3
+ Version: 0.4.32
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.31"
3
+ version = "0.4.32"
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"]
@@ -24,7 +24,6 @@ from sequence_base.contract import (
24
24
  Project,
25
25
  ImageStepProject,
26
26
  Camera,
27
- Embodiment,
28
27
  ObservationContract,
29
28
  ObserveFrame,
30
29
  ObserveRequest,
@@ -130,9 +129,6 @@ from sequence_base.errors.transport import (
130
129
  from sequence_base.episode import Episode
131
130
 
132
131
 
133
- from sequence_base.feedback import Feedback
134
-
135
-
136
132
  from sequence_base import auth
137
133
 
138
134
 
@@ -148,7 +144,7 @@ __all__ = [
148
144
 
149
145
  "SeqFlags", "ImageStepUvPip", "ImageStepApt", "ImageStepEnv", "ImageStepRun", "AddLocal", "ImageStepAddLocal",
150
146
  "FROZEN_PATH", "TemplateFiles", "ImageStepTemplateFiles", "Project", "ImageStepProject", "ImageStep", "ImageSpec",
151
- "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract", "Embodiment",
147
+ "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract",
152
148
  "PolicySpec", "PolicyRegistration", "PolicyConstructor",
153
149
  "Observations", "Stream", "Actions", "Tensors",
154
150
 
@@ -177,7 +173,7 @@ __all__ = [
177
173
 
178
174
  "TransportUnavailable", "TransportWarming", "TransportRejected", "TransportOverloaded",
179
175
 
180
- "Episode", "Feedback",
176
+ "Episode",
181
177
 
182
178
  "auth",
183
179
  ]
@@ -14,6 +14,13 @@ the platform refused to deploy one - so binding them by name changes nothing a c
14
14
  that takes one beside its inference parameters keeps taking its inputs whole. The SDK reads the rule when a class is
15
15
  declared (seq/named.py, registry.infer_params), the worker when it calls the method (harness/handler/loader.py): one
16
16
  rule on both sides.
17
+
18
+ What the platform hands a method itself is `episode` - an act function, an observe function and the method an
19
+ episode's end calls alike - and an eval's `seed`; `retired(parameters, what)` refuses a method that still takes what it
20
+ handed once (episode_id, embodiment, feedback), and `ends(parameters, what)` an end method that takes anything but the episode,
21
+ each in words that say what to write instead - the SDK when a class is declared, the worker when it loads one declared
22
+ before.
23
+
17
24
  """
18
25
  from __future__ import annotations
19
26
 
@@ -22,12 +29,17 @@ from collections.abc import Iterable, Mapping
22
29
  from dataclasses import dataclass
23
30
  from typing import Any
24
31
 
25
- __all__ = ["INFER_PLATFORM", "OBSERVE_PLATFORM", "ByName", "takes_by_name"]
32
+ __all__ = ["INFER_PLATFORM", "OBSERVE_PLATFORM", "RETIRED", "ByName", "ends", "retired", "takes_by_name"]
33
+
26
34
 
27
35
 
36
+ INFER_PLATFORM = frozenset({"seed", "episode", "plan", "robot"})
37
+ OBSERVE_PLATFORM = frozenset({"step", "episode"})
28
38
 
29
- INFER_PLATFORM = frozenset({"seed", "episode_id", "episode", "feedback", "plan", "robot", "embodiment"})
30
- OBSERVE_PLATFORM = frozenset({"step"})
39
+
40
+ RETIRED = {"episode_id": "take episode, a seq.Episode, and read episode.id",
41
+ "embodiment": "send what the robot is with its observations, in observe(x)",
42
+ "feedback": "send what the robot was playing with its observations, in observe(x)"}
31
43
 
32
44
  _VARIADIC = (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD)
33
45
 
@@ -47,7 +59,7 @@ class ByName:
47
59
  def call(self, inputs: Any, what: str) -> tuple[list, dict]:
48
60
  """(args, kwargs) the method `what` ("Model.predict") is called with for an act's `inputs`; ValueError, in its
49
61
  words, for inputs that are not a dict of its arguments."""
50
- takes = ", ".join(n if n in self.required else f"{n} (optional)" for n in self.names)
62
+ takes = ", ".join(n if n in self.required else f"{n} (optional)" for n in self.names) or "none of them"
51
63
  if not isinstance(inputs, Mapping):
52
64
  raise ValueError(f"{what} takes its inputs by name ({takes}): an act's inputs are a dict of them, and "
53
65
  f"these are a {type(inputs).__name__}")
@@ -73,18 +85,43 @@ class ByName:
73
85
  return args, {k: v for k, v in inputs.items() if k not in self.positional}
74
86
 
75
87
 
76
- def takes_by_name(parameters: Iterable[inspect.Parameter], platform: frozenset[str] = frozenset()) -> ByName | None:
88
+ def takes_by_name(parameters: Iterable[inspect.Parameter], platform: frozenset[str] = frozenset(), *,
89
+ always: bool = False) -> ByName | None:
77
90
  """How a method of these `parameters` (self left out) takes an act's inputs: by name (ByName) when two or more of
78
- its arguments - *args, **kwargs and `platform`'s left out - have no default, else None: whole, as one argument."""
91
+ its arguments - *args, **kwargs and `platform`'s left out - have no default, else None: whole, as one argument.
92
+ `always`: by name however many it takes - an infer= beside observe=, handed an act's arguments alone (plan3.5/92)."""
79
93
  every = list(parameters)
80
94
  params = [p for p in every if p.kind not in _VARIADIC and p.name not in platform]
81
95
  required = tuple(p.name for p in params if p.default is inspect.Parameter.empty)
82
- if len(required) < 2:
96
+ if len(required) < 2 and not always:
83
97
  return None
84
98
  return ByName(names=tuple(p.name for p in params), required=required,
85
99
  positional=tuple(p.name for p in params if p.kind is inspect.Parameter.POSITIONAL_ONLY),
86
100
  rest=any(p.kind is inspect.Parameter.VAR_KEYWORD for p in every), platform=frozenset(platform))
87
101
 
88
102
 
103
+ def retired(parameters: Iterable[inspect.Parameter], what: str) -> str | None:
104
+ """Why `what` ("Model.infer"), a method the platform calls, cannot be deployed: it takes what the platform no longer
105
+ hands it (RETIRED), said with what to write instead - or None, when it takes none of it."""
106
+ names = [p.name for p in parameters if p.name in RETIRED]
107
+ if not names:
108
+ return None
109
+ return (f"{what} takes {' and '.join(names)}, which the platform no longer hands it: "
110
+ + "; ".join(RETIRED[n] for n in names))
111
+
112
+
113
+ def ends(parameters: Iterable[inspect.Parameter], what: str) -> str | None:
114
+ """Why `what` ("Model.end"), the method an episode's end calls (@seq.on_episode), cannot be deployed: an episode's
115
+ end hands it the episode alone, so it takes `episode` or nothing - any other argument with a default, never one
116
+ the platform no longer hands (RETIRED) - or None, when it does."""
117
+ taken = [p.name for p in parameters if p.kind not in _VARIADIC
118
+ and (p.name in RETIRED or (p.name != "episode" and p.default is inspect.Parameter.empty))]
119
+ if not taken:
120
+ return None
121
+ name = what.rsplit(".", 1)[-1]
122
+ return (f"{what} takes {' and '.join(taken)}: an episode's end hands it the episode alone - write "
123
+ f"def {name}(self, episode) and read its id as episode.id, or def {name}(self)")
124
+
125
+
89
126
  def _keys(names: list) -> str:
90
127
  return ", ".join(repr(n) for n in names)
@@ -4,7 +4,8 @@
4
4
 
5
5
 
6
6
 
7
- CONTRACT_VERSION = "0.5.28"
7
+ CONTRACT_VERSION = "0.5.29"
8
+
8
9
 
9
10
 
10
11
 
@@ -21,7 +21,6 @@ from sequence_base.contract.observe import ObserveFrame, ObserveRequest, Observe
21
21
  from sequence_base.contract.flags import SeqFlags
22
22
  from sequence_base.contract.policy import (
23
23
  Camera,
24
- Embodiment,
25
24
  ObservationContract,
26
25
  ActionContract,
27
26
  Concurrency,
@@ -129,7 +128,7 @@ __all__ = [
129
128
  "SeqFlags",
130
129
  "ImageStepUvPip", "ImageStepApt", "ImageStepEnv", "ImageStepRun", "AddLocal", "ImageStepAddLocal",
131
130
  "TemplateFiles", "ImageStepTemplateFiles", "Project", "ImageStepProject", "FROZEN_PATH", "ImageStep", "ImageSpec",
132
- "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract", "Embodiment",
131
+ "VolumeMount", "VolumeRef", "Concurrency", "ActionContract", "Camera", "ObservationContract",
133
132
  "PolicySpec", "PolicyRegistration", "PolicyConstructor",
134
133
  "Observations", "Stream", "Actions", "Tensors",
135
134
 
@@ -10,13 +10,15 @@ and the warming ETA are typed and checkable.
10
10
  from __future__ import annotations
11
11
 
12
12
  from datetime import datetime
13
+ from typing import Any
13
14
 
14
- from pydantic import BaseModel, ConfigDict, Field
15
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
15
16
 
16
17
 
17
18
  from sequence_base.contract.errors import WarmingError
18
19
  from sequence_base.contract.io import ActionContract, ObservationContract
19
20
  from sequence_base.contract.own_io import Actions, Observations
21
+ from sequence_base.contract.retired import dropped
20
22
 
21
23
  __all__ = ["Lease", "ConnectRequest", "ConnectResponse", "WarmingError"]
22
24
 
@@ -37,7 +39,11 @@ class ConnectRequest(BaseModel):
37
39
  model_config = ConfigDict(extra="forbid")
38
40
 
39
41
  model: str = Field(..., description="Deployment name to connect to")
40
- embodiment: str | None = Field(default=None, description="Which declared embodiment this session drives")
42
+
43
+ @model_validator(mode="before")
44
+ @classmethod
45
+ def _retired(cls, data: Any) -> Any:
46
+ return dropped(data, "embodiment")
41
47
 
42
48
 
43
49
  class ConnectResponse(BaseModel):
@@ -55,7 +61,6 @@ class ConnectResponse(BaseModel):
55
61
 
56
62
  action: ActionContract | None = None
57
63
  observation: ObservationContract | None = None
58
- embodiment: str | None = None
59
64
 
60
65
  io: str | None = None
61
66
 
@@ -63,5 +68,7 @@ class ConnectResponse(BaseModel):
63
68
  observations: Observations | None = None
64
69
  actions: Actions | None = None
65
70
 
66
-
67
- feedback: bool | None = None
71
+ @model_validator(mode="before")
72
+ @classmethod
73
+ def _retired(cls, data: Any) -> Any:
74
+ return dropped(data, "embodiment", "feedback")
@@ -16,13 +16,14 @@ import binascii
16
16
  import hashlib
17
17
  import re
18
18
  from enum import Enum
19
- from typing import Literal
19
+ from typing import Any, Literal
20
20
 
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 Embodiment, ObservationContract
24
+ from sequence_base.contract.io import ObservationContract
25
25
  from sequence_base.contract.own_io import Actions, Observations, Tensors, check_own_io
26
+ from sequence_base.contract.retired import dropped
26
27
  from sequence_base.contract.policy import (
27
28
  KIND_NAME,
28
29
  ActionContract,
@@ -165,8 +166,9 @@ def describe(param: "InferParam") -> str:
165
166
 
166
167
  class DeploymentPolicy(BaseModel):
167
168
  """The policy block of the deployments body. Only `handler_ref` is required. The robot-arm preset's contracts
168
- (`action`, `observation`, `embodiments`) are optional since contract 0.4.14: a deployment that declares none is held
169
- to nothing and its inputs / outputs pass through the worker untouched.
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).
170
172
 
171
173
  `secrets` carries the policy's declared secret BUNDLES BY NAME ONLY (list[SecretRef]) — the gateway
172
174
  validates each name exists and belongs to the deployer at submit time, and the
@@ -176,6 +178,11 @@ class DeploymentPolicy(BaseModel):
176
178
 
177
179
  model_config = ConfigDict(extra="forbid")
178
180
 
181
+ @model_validator(mode="before")
182
+ @classmethod
183
+ def _retired(cls, data: Any) -> Any:
184
+ return dropped(data, "embodiments", "feedback")
185
+
179
186
  handler_ref: str
180
187
  action: ActionContract | None = None
181
188
 
@@ -184,14 +191,9 @@ class DeploymentPolicy(BaseModel):
184
191
 
185
192
 
186
193
  streaming: bool = Field(default=False, exclude=True)
187
-
188
-
189
- feedback: bool | None = None
190
194
  secrets: list[SecretRef] = Field(default_factory=list)
191
195
 
192
-
193
196
  observation: ObservationContract | None = None
194
- embodiments: dict[str, Embodiment] | None = None
195
197
 
196
198
 
197
199
 
@@ -1,5 +1,5 @@
1
1
  """
2
- The robot-arm I/O contracts (`action=`, `observation=`, `embodiments=`), re-exported from
2
+ The robot-arm I/O contracts (`action=`, `observation=`), re-exported from
3
3
  `sequence_base.presets.robot_arm`.
4
4
 
5
5
  Declaring one is optional since contract 0.4.14: a deployment that declares none is held to nothing, and its
@@ -11,11 +11,10 @@ from sequence_base.presets.robot_arm import (
11
11
  PROPRIO_FIELDS,
12
12
  ActionContract,
13
13
  Camera,
14
- Embodiment,
15
14
  ObservationContract,
16
15
  fit_hint,
17
16
  frame_size_problem,
18
17
  )
19
18
 
20
- __all__ = ["ActionContract", "PROPRIO_FIELDS", "Camera", "ObservationContract", "Embodiment", "frame_size_problem",
21
- "fit_hint", "PAYLOAD_HINT"]
19
+ __all__ = ["ActionContract", "PROPRIO_FIELDS", "Camera", "ObservationContract", "frame_size_problem", "fit_hint",
20
+ "PAYLOAD_HINT"]
@@ -235,7 +235,7 @@ def check_own_io(spec: Any) -> None:
235
235
  new = [name for name in ("observations", "actions", "tensors") if getattr(spec, name) is not None]
236
236
  if not new:
237
237
  return
238
- if spec.action or spec.observation or spec.embodiments:
238
+ if spec.action or spec.observation:
239
239
  raise ValueError(f"{', '.join(new)} {'is' if len(new) == 1 else 'are'} for a policy of its own inputs and "
240
240
  "outputs; this one declares the robot-arm contract, where observation history and the action "
241
241
  "chunk say it")
@@ -20,11 +20,11 @@ from sequence_base.contract.io import (
20
20
  PROPRIO_FIELDS,
21
21
  ActionContract,
22
22
  Camera,
23
- Embodiment,
24
23
  ObservationContract,
25
24
  )
26
25
  from sequence_base.contract.flags import SeqFlags
27
26
  from sequence_base.contract.own_io import Actions, Observations, Tensors, check_own_io
27
+ from sequence_base.contract.retired import dropped
28
28
 
29
29
  __all__ = [
30
30
  "Episodes",
@@ -347,12 +347,18 @@ Episodes = Literal["shared", "own"]
347
347
 
348
348
 
349
349
  class PolicySpec(BaseModel):
350
- """What `@seq.policy(...)` accrues — a policy's complete infra declaration, losslessly. `action` /
351
- `observation` / `embodiments` are optional (contract 0.4.14): a policy that declares none defines its I/O in its own
352
- code, and the platform passes it through."""
350
+ """What `@seq.policy(...)` accrues — a policy's complete infra declaration, losslessly. `action` / `observation`
351
+ are optional (contract 0.4.14): a policy that declares none defines its I/O in its own code, and the platform passes
352
+ it through. A spec from before contract 0.5.29 reads
353
+ with its `embodiments` and `feedback` dropped (contract.retired)."""
353
354
 
354
355
  model_config = ConfigDict(extra="forbid")
355
356
 
357
+ @model_validator(mode="before")
358
+ @classmethod
359
+ def _retired(cls, data: Any) -> Any:
360
+ return dropped(data, "embodiments", "feedback")
361
+
356
362
  name: str
357
363
 
358
364
 
@@ -377,14 +383,9 @@ class PolicySpec(BaseModel):
377
383
 
378
384
  streaming: bool = Field(default=False, exclude=True)
379
385
 
380
-
381
-
382
- feedback: bool | None = None
383
-
384
386
  action: ActionContract | None = None
385
387
 
386
388
  observation: ObservationContract | None = None
387
- embodiments: dict[str, Embodiment] | None = None
388
389
 
389
390
 
390
391
 
@@ -0,0 +1,22 @@
1
+ """
2
+ Fields the wire carried once and carries no more (contract 0.5.29): what a robot is (`embodiment`, `embodiments`) and
3
+ what it was playing (`feedback`). A body from before - a spec stored when its policy was deployed, an act or a connect
4
+ an older gateway queued or an older SDK sends - still reads under extra="forbid", each of them dropped as it is read.
5
+
6
+ WHY dropped rather than kept unread: nothing reads them - an act function is handed its episode alone, and a robot sends
7
+ what it is, and what it played, with its observations - so a model that kept them would only carry them on.
8
+
9
+
10
+ """
11
+ from __future__ import annotations
12
+
13
+ from typing import Any
14
+
15
+ __all__ = ["dropped"]
16
+
17
+
18
+ def dropped(data: Any, *names: str) -> Any:
19
+ """`data` without `names`: a dict that holds any of them, a copy without them; anything else as it is."""
20
+ if isinstance(data, dict) and any(n in data for n in names):
21
+ return {k: v for k, v in data.items() if k not in names}
22
+ return data
@@ -7,8 +7,8 @@ posts them to the worker's /act unchanged → the worker hands them to the polic
7
7
  of the user's own code, never by the platform.
8
8
 
9
9
  Alongside the payload the envelope carries only what the platform itself acts on: a seed (determinism), the episode
10
- (per-episode state and `/act/episode_end`), the declared inference parameters, and — for a robot-arm preset policy with
11
- several bodies — the embodiment chosen at connect.
10
+ (per-episode state and `/act/episode_end`) and the declared inference parameters. An act from before contract 0.5.29
11
+ reads with its `embodiment` and `feedback` dropped (contract.retired).
12
12
 
13
13
  Compatibility: a worker also accepts the version-1 body (`observation` instead of `inputs`), and a policy written
14
14
  against the robot-arm preset (`infer(self, obs: Observation) -> ActionChunk`) also answers `action_chunk`, so older SDKs
@@ -18,7 +18,9 @@ from __future__ import annotations
18
18
 
19
19
  from typing import Any
20
20
 
21
- from pydantic import BaseModel, ConfigDict, Field
21
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
22
+
23
+ from sequence_base.contract.retired import dropped
22
24
 
23
25
  __all__ = ["ActRequest", "ActResponse"]
24
26
 
@@ -33,8 +35,6 @@ class ActRequest(BaseModel):
33
35
  episode_id: str | None = Field(default=None, description="The episode this call belongs to (per-episode state)")
34
36
  params: dict[str, Any] | None = Field(default=None,
35
37
  description="Values for the inference parameters the policy declares")
36
- embodiment: str | None = Field(default=None,
37
- description="Robot-arm preset only: which declared embodiment this session drives")
38
38
 
39
39
 
40
40
  plan: dict[str, Any] | None = Field(default=None,
@@ -45,10 +45,10 @@ class ActRequest(BaseModel):
45
45
  seq: int | None = Field(default=None, ge=0,
46
46
  description="The newest observation's number in its episode's stream (POST /observe)")
47
47
 
48
-
49
-
50
- feedback: dict[str, Any] | None = Field(default=None,
51
- description="What the robot was playing: left, delay, played, last")
48
+ @model_validator(mode="before")
49
+ @classmethod
50
+ def _retired(cls, data: Any) -> Any:
51
+ return dropped(data, "embodiment", "feedback")
52
52
 
53
53
 
54
54
  class ActResponse(BaseModel):
@@ -5,7 +5,7 @@ Optional, not the platform's wire. Under custom-io the worker hands a policy's `
5
5
  returns whatever it answers; this module is the shape OUR templates and benchmarks agree on, kept so they keep
6
6
  working. A policy uses it by annotating `infer(self, obs: Observation, ...) -> ActionChunk` (the worker then parses
7
7
  `inputs` into an Observation and serializes the chunk) and, if it wants them enforced, by declaring `action=` /
8
- `observation=` / `embodiments=` contracts.
8
+ `observation=` contracts.
9
9
 
10
10
  `sequence_base.contract.act` and `sequence_base.contract.io` re-export everything here, so existing imports keep
11
11
  resolving to these same classes.
@@ -277,12 +277,3 @@ class ObservationContract(BaseModel):
277
277
  return v
278
278
 
279
279
 
280
- class Embodiment(BaseModel):
281
- """One robot body a multi-embodiment policy serves: its action contract, its observation contract, and
282
- free-form metadata the policy reads (e.g. which normalisation statistics). Chosen per session at connect."""
283
-
284
- model_config = ConfigDict(extra="forbid")
285
-
286
- action: ActionContract
287
- observation: ObservationContract | None = None
288
- meta: dict[str, Any] = Field(default_factory=dict)
@@ -80,7 +80,6 @@ from sequence_base.contract.eval import (
80
80
  from sequence_base.contract.flags import seqflags_json_schema
81
81
  from sequence_base.contract.policy import (
82
82
  Camera,
83
- Embodiment,
84
83
  ObservationContract,
85
84
  ActionContract,
86
85
  Concurrency,
@@ -136,7 +135,6 @@ WIRE_MODELS: dict[str, type[BaseModel]] = {
136
135
  "ActionContract": ActionContract,
137
136
  "Camera": Camera,
138
137
  "ObservationContract": ObservationContract,
139
- "Embodiment": Embodiment,
140
138
  "PolicySpec": PolicySpec,
141
139
  "PolicyRegistration": PolicyRegistration,
142
140
 
@@ -2,19 +2,6 @@
2
2
  "additionalProperties": false,
3
3
  "description": "POST /act, version 2. `inputs` is any JSON value; the worker does not inspect it.",
4
4
  "properties": {
5
- "embodiment": {
6
- "anyOf": [
7
- {
8
- "type": "string"
9
- },
10
- {
11
- "type": "null"
12
- }
13
- ],
14
- "default": null,
15
- "description": "Robot-arm preset only: which declared embodiment this session drives",
16
- "title": "Embodiment"
17
- },
18
5
  "episode_id": {
19
6
  "anyOf": [
20
7
  {
@@ -28,20 +15,6 @@
28
15
  "description": "The episode this call belongs to (per-episode state)",
29
16
  "title": "Episode Id"
30
17
  },
31
- "feedback": {
32
- "anyOf": [
33
- {
34
- "additionalProperties": true,
35
- "type": "object"
36
- },
37
- {
38
- "type": "null"
39
- }
40
- ],
41
- "default": null,
42
- "description": "What the robot was playing: left, delay, played, last",
43
- "title": "Feedback"
44
- },
45
18
  "inputs": {
46
19
  "description": "Whatever the policy's infer() takes, exactly as the robot's code built it",
47
20
  "title": "Inputs"
@@ -107,5 +80,5 @@
107
80
  ],
108
81
  "title": "ActRequest",
109
82
  "type": "object",
110
- "x-contract-version": "0.5.28"
83
+ "x-contract-version": "0.5.29"
111
84
  }
@@ -89,5 +89,5 @@
89
89
  ],
90
90
  "title": "ActResponse",
91
91
  "type": "object",
92
- "x-contract-version": "0.5.28"
92
+ "x-contract-version": "0.5.29"
93
93
  }
@@ -99,5 +99,5 @@
99
99
  ],
100
100
  "title": "ActionChunk",
101
101
  "type": "object",
102
- "x-contract-version": "0.5.28"
102
+ "x-contract-version": "0.5.29"
103
103
  }
@@ -96,5 +96,5 @@
96
96
  ],
97
97
  "title": "ActionContract",
98
98
  "type": "object",
99
- "x-contract-version": "0.5.28"
99
+ "x-contract-version": "0.5.29"
100
100
  }
@@ -19,5 +19,5 @@
19
19
  ],
20
20
  "title": "ActionStep",
21
21
  "type": "object",
22
- "x-contract-version": "0.5.28"
22
+ "x-contract-version": "0.5.29"
23
23
  }
@@ -59,5 +59,5 @@
59
59
  },
60
60
  "title": "Actions",
61
61
  "type": "object",
62
- "x-contract-version": "0.5.28"
62
+ "x-contract-version": "0.5.29"
63
63
  }
@@ -17,5 +17,5 @@
17
17
  ],
18
18
  "title": "AdapterPair",
19
19
  "type": "object",
20
- "x-contract-version": "0.5.28"
20
+ "x-contract-version": "0.5.29"
21
21
  }
@@ -23,5 +23,5 @@
23
23
  ],
24
24
  "title": "AddLocal",
25
25
  "type": "object",
26
- "x-contract-version": "0.5.28"
26
+ "x-contract-version": "0.5.29"
27
27
  }
@@ -57,5 +57,5 @@
57
57
  },
58
58
  "title": "Autoscaler",
59
59
  "type": "object",
60
- "x-contract-version": "0.5.28"
60
+ "x-contract-version": "0.5.29"
61
61
  }
@@ -50,5 +50,5 @@
50
50
  ],
51
51
  "title": "BenchmarkConditionSpec",
52
52
  "type": "object",
53
- "x-contract-version": "0.5.28"
53
+ "x-contract-version": "0.5.29"
54
54
  }
@@ -1089,5 +1089,5 @@
1089
1089
  ],
1090
1090
  "title": "BenchmarkRegisterRequest",
1091
1091
  "type": "object",
1092
- "x-contract-version": "0.5.28"
1092
+ "x-contract-version": "0.5.29"
1093
1093
  }
@@ -471,7 +471,7 @@
471
471
  ],
472
472
  "title": "SeqFlags",
473
473
  "type": "integer",
474
- "x-contract-version": "0.5.28",
474
+ "x-contract-version": "0.5.29",
475
475
  "x-flag-names": {
476
476
  "CHECK": 65536,
477
477
  "INFER": 16,
@@ -722,5 +722,5 @@
722
722
  ],
723
723
  "title": "BenchmarkSpec",
724
724
  "type": "object",
725
- "x-contract-version": "0.5.28"
725
+ "x-contract-version": "0.5.29"
726
726
  }
@@ -40,5 +40,5 @@
40
40
  ],
41
41
  "title": "BenchmarkStatusResponse",
42
42
  "type": "object",
43
- "x-contract-version": "0.5.28"
43
+ "x-contract-version": "0.5.29"
44
44
  }
@@ -79,5 +79,5 @@
79
79
  ],
80
80
  "title": "BootstrapResponse",
81
81
  "type": "object",
82
- "x-contract-version": "0.5.28"
82
+ "x-contract-version": "0.5.29"
83
83
  }
@@ -122,5 +122,5 @@
122
122
  ],
123
123
  "title": "Camera",
124
124
  "type": "object",
125
- "x-contract-version": "0.5.28"
125
+ "x-contract-version": "0.5.29"
126
126
  }
@@ -23,5 +23,5 @@
23
23
  ],
24
24
  "title": "CodeBundle",
25
25
  "type": "object",
26
- "x-contract-version": "0.5.28"
26
+ "x-contract-version": "0.5.29"
27
27
  }