sequence-base 0.4.16__tar.gz → 0.4.18__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.16 → sequence_base-0.4.18}/PKG-INFO +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/pyproject.toml +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/__init__.py +4 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/constants/version.py +3 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/__init__.py +5 -0
- sequence_base-0.4.18/sequence_base/contract/adapters.py +181 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/deployments.py +5 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schema_export.py +2 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ActRequest.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ActResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ActionChunk.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ActionContract.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ActionStep.json +1 -1
- sequence_base-0.4.18/sequence_base/schemas/AdapterPair.json +21 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/AddLocal.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Autoscaler.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/BenchmarkConditionSpec.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/BenchmarkRegisterRequest.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/BenchmarkSpec.json +2 -2
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/BenchmarkStatusResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/BootstrapResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Camera.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/CodeBundle.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Concurrency.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Conditions.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ConnectRequest.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ConnectResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/DeploymentAccepted.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/DeploymentPolicy.json +14 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/DeploymentRequest.json +14 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/DeploymentStatusResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Embodiment.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ErrorBody.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ErrorCodes.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Estimate.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/EvalDryRunResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/EvalReport.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/EvalRequest.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/EvalResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageFrame.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageSpec.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageStepAddLocal.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageStepApt.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageStepEnv.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageStepRun.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageStepTemplateFiles.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ImageStepUvPip.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/InferParam.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Lease.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/MetricAgg.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Observation.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ObservationContract.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/PolicyRegistration.json +2 -2
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/PolicySpec.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Proprioception.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/RenderSpec.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/ReplaySpec.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Resources.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/RolloutResult.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/SecretCreateRequest.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/SecretInfo.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/SecretRef.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/SeqFlags.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Step.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/TaskAgg.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/TemplateFiles.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Timeouts.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/UploadTarget.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/Variant.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/VolumeFile.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/VolumeInfo.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/VolumeMount.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/VolumeRef.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/VolumeUploadRequest.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/VolumeUploadResponse.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/schemas/WarmingError.json +1 -1
- {sequence_base-0.4.16 → sequence_base-0.4.18}/.gitignore +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/README.md +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/auth.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/codec/__init__.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/codec/image.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/constants/__init__.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/constants/headers.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/constants/limits.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/accounts.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/act.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/benchmarks.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/connect.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/errors.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/eval.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/flags.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/io.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/policy.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/templates.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/volumes.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/contract/wire.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/errors/__init__.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/errors/transport.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/obs/__init__.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/obs/log.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/obs/rid.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/presets/__init__.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/presets/frames.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/presets/robot_arm.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/sequence_base/telemetry/__init__.py +0 -0
- {sequence_base-0.4.16 → sequence_base-0.4.18}/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.
|
|
3
|
+
Version: 0.4.18
|
|
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.
|
|
3
|
+
version = "0.4.18"
|
|
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"]
|
|
@@ -33,6 +33,8 @@ from sequence_base.contract import (
|
|
|
33
33
|
parse_vol,
|
|
34
34
|
TEMPLATE_SCHEME,
|
|
35
35
|
parse_template,
|
|
36
|
+
AdapterPair,
|
|
37
|
+
parse_pairs,
|
|
36
38
|
ActionChunk,
|
|
37
39
|
ActionContract,
|
|
38
40
|
ActionSpace,
|
|
@@ -148,6 +150,8 @@ __all__ = [
|
|
|
148
150
|
|
|
149
151
|
"TEMPLATE_SCHEME", "parse_template",
|
|
150
152
|
|
|
153
|
+
"AdapterPair", "parse_pairs",
|
|
154
|
+
|
|
151
155
|
"ErrorCode", "ErrorBody", "WarmingError", "ERRORS", "ErrorSpec", "code_for_status", "CONTRACT_VERSION",
|
|
152
156
|
"MAX_ENVS", "MAX_USD", "TASK_DESCRIPTION_MAX",
|
|
153
157
|
|
|
@@ -94,6 +94,9 @@ from sequence_base.contract.accounts import (
|
|
|
94
94
|
from sequence_base.contract.templates import TEMPLATE_SCHEME, parse_template
|
|
95
95
|
|
|
96
96
|
|
|
97
|
+
from sequence_base.contract.adapters import AdapterPair, parse_pairs
|
|
98
|
+
|
|
99
|
+
|
|
97
100
|
from sequence_base.contract.volumes import (
|
|
98
101
|
MAX_FILES,
|
|
99
102
|
MAX_UPLOAD_BYTES,
|
|
@@ -137,5 +140,7 @@ __all__ = [
|
|
|
137
140
|
|
|
138
141
|
"TEMPLATE_SCHEME", "parse_template",
|
|
139
142
|
|
|
143
|
+
"AdapterPair", "parse_pairs",
|
|
144
|
+
|
|
140
145
|
"ErrorCode", "ErrorBody", "WarmingError", "ERRORS", "ErrorSpec", "code_for_status",
|
|
141
146
|
]
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""
|
|
2
|
+
An adapter's pairs - the benchmark → policy pairs a registered adapter converts between.
|
|
3
|
+
|
|
4
|
+
In one sentence: an adapter's author writes in its code which pairs its conversion is for - `@seq.adapter(pairs=[
|
|
5
|
+
(benchmark, policy), ...])`, each side an account's name, `template:<name>` (anything made from that template, at any
|
|
6
|
+
version) or `*` (any one), or `pairs="any"` for every pair → `seq deploy` registers them with the version → as an eval
|
|
7
|
+
starts, the gateway matches the eval's benchmark and policy against them (match) and refuses the rest before anything
|
|
8
|
+
runs. The rules are defined once, here: the SDK reads them (the decorator, `seq adapter check`) and so does the
|
|
9
|
+
gateway (registration, the eval's check, which adapters fit a pair), so what can be chosen is what runs.
|
|
10
|
+
WHY in the code, with the version: which pairs a conversion is for is part of the conversion - changing them is a new
|
|
11
|
+
version, and an eval keeps the version it ran. WHY by name and never by version: a benchmark's or a policy's I/O
|
|
12
|
+
seldom changes with its version, and pinned pairs would make every upgrade a new adapter. WHY a pair need not exist
|
|
13
|
+
yet: an adapter may come before the policy it feeds; names are matched as an eval starts.
|
|
14
|
+
{the user 10-19, through TEST USER: "you need to specify which benchmark and which policy you want the conversion to
|
|
15
|
+
be and then you can specify multiple … you can only apply those that are stated here as the pairs"; "We should have
|
|
16
|
+
the option to open to all"}
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import re
|
|
22
|
+
from typing import Any, Iterable, Literal, Union
|
|
23
|
+
|
|
24
|
+
from pydantic import BaseModel, ConfigDict
|
|
25
|
+
|
|
26
|
+
ANY = "any"
|
|
27
|
+
WILDCARD = "*"
|
|
28
|
+
TEMPLATE = "template:"
|
|
29
|
+
MAX_PAIRS = 64
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
_NAME = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]{0,63}")
|
|
34
|
+
_TEMPLATE_NAME = re.compile(r"[a-z0-9][a-z0-9-]{0,63}")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AdapterPair(BaseModel):
|
|
38
|
+
"""One pair an adapter converts between: its benchmark side and its policy side, each an account's name,
|
|
39
|
+
`template:<name>` or `*`."""
|
|
40
|
+
|
|
41
|
+
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
42
|
+
|
|
43
|
+
benchmark: str
|
|
44
|
+
policy: str
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
Pairs = Union[Literal["any"], list[AdapterPair]]
|
|
48
|
+
|
|
49
|
+
_EXAMPLE = 'pairs=[("libero-10", "my-pi05"), ("template:libero-spatial", "*")], or pairs="any"'
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _side(value: Any, which: str, i: int) -> str:
|
|
53
|
+
if not isinstance(value, str) or not value.strip():
|
|
54
|
+
raise ValueError(f"pair {i}: its {which} is {value!r}, not a name")
|
|
55
|
+
side = value.strip()
|
|
56
|
+
if side == WILDCARD:
|
|
57
|
+
return side
|
|
58
|
+
if side.startswith(TEMPLATE):
|
|
59
|
+
if not _TEMPLATE_NAME.fullmatch(side[len(TEMPLATE):]):
|
|
60
|
+
raise ValueError(f"pair {i}: {which} {value!r}: a template is template:<name>, the name `seq init` takes "
|
|
61
|
+
"(lowercase letters, digits or '-'), e.g. template:libero-10")
|
|
62
|
+
return side
|
|
63
|
+
if not _NAME.fullmatch(side):
|
|
64
|
+
raise ValueError(f"pair {i}: {which} {value!r} is no name: 1-64 letters, digits, '.', '_' or '-', starting "
|
|
65
|
+
"with a letter or digit - or template:<name>, or *")
|
|
66
|
+
return side
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def parse_pairs(value: Any) -> Pairs:
|
|
70
|
+
"""`"any"`, or the pairs as [(benchmark, policy), ...] or [{"benchmark", "policy"}, ...] → "any" or [AdapterPair,
|
|
71
|
+
...] in their order, each once. Raises ValueError saying which pair and which side is wrong; None and [] are wrong
|
|
72
|
+
too - an adapter says which pairs it is for, or "any"."""
|
|
73
|
+
if isinstance(value, str):
|
|
74
|
+
if value == ANY:
|
|
75
|
+
return ANY
|
|
76
|
+
raise ValueError(f"pairs is {value!r}: write the (benchmark, policy) pairs the adapter converts between - "
|
|
77
|
+
f"{_EXAMPLE}")
|
|
78
|
+
if value is None:
|
|
79
|
+
raise ValueError(f"the adapter declares no pairs: say which benchmark → policy pairs it converts between - "
|
|
80
|
+
f"{_EXAMPLE}")
|
|
81
|
+
try:
|
|
82
|
+
items = list(value)
|
|
83
|
+
except TypeError:
|
|
84
|
+
raise ValueError(f"pairs is {value!r}, not a list of (benchmark, policy) pairs - {_EXAMPLE}") from None
|
|
85
|
+
if not items:
|
|
86
|
+
raise ValueError(f"pairs is empty: name at least one (benchmark, policy) pair - {_EXAMPLE}")
|
|
87
|
+
out: list[AdapterPair] = []
|
|
88
|
+
for i, item in enumerate(items, 1):
|
|
89
|
+
if isinstance(item, AdapterPair):
|
|
90
|
+
bench, policy = item.benchmark, item.policy
|
|
91
|
+
elif isinstance(item, dict) and set(item) == {"benchmark", "policy"}:
|
|
92
|
+
bench, policy = item["benchmark"], item["policy"]
|
|
93
|
+
elif isinstance(item, (list, tuple)) and len(item) == 2:
|
|
94
|
+
bench, policy = item
|
|
95
|
+
else:
|
|
96
|
+
raise ValueError(f"pair {i} is {item!r}: a pair is (benchmark, policy)")
|
|
97
|
+
pair = AdapterPair(benchmark=_side(bench, "benchmark", i), policy=_side(policy, "policy", i))
|
|
98
|
+
if pair not in out:
|
|
99
|
+
out.append(pair)
|
|
100
|
+
if len(out) > MAX_PAIRS:
|
|
101
|
+
raise ValueError(f"{len(out)} pairs; at most {MAX_PAIRS} - template:<name> or * names many at once")
|
|
102
|
+
return out
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def as_json(pairs: Pairs | None) -> str | list[dict] | None:
|
|
106
|
+
"""The pairs as the wire, the API and the table carry them: "any", [{"benchmark", "policy"}, ...], or None (a
|
|
107
|
+
version registered before pairs)."""
|
|
108
|
+
if pairs is None or pairs == ANY:
|
|
109
|
+
return pairs
|
|
110
|
+
return [p.model_dump() for p in pairs]
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _stored(pairs: Any) -> Pairs | None:
|
|
114
|
+
"""Pairs as kept (as_json's form) or as parsed; None for none - never raises on what parse_pairs once accepted."""
|
|
115
|
+
if pairs is None or pairs == ANY:
|
|
116
|
+
return pairs
|
|
117
|
+
return [p if isinstance(p, AdapterPair) else AdapterPair(**p) for p in pairs]
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def image_templates(image: Any) -> set[str]:
|
|
121
|
+
"""The templates an image installs the files of - each `template_files` step's template, the line `seq init` writes
|
|
122
|
+
into a template's entry file and a user who edits the code keeps: what makes a benchmark or a policy one of the
|
|
123
|
+
template's for `template:<name>`. `image`: an ImageSpec, or its dict as a request or a stored spec carries it."""
|
|
124
|
+
if image is None:
|
|
125
|
+
return set()
|
|
126
|
+
steps = image.get("steps") if isinstance(image, dict) else getattr(image, "steps", None)
|
|
127
|
+
out: set[str] = set()
|
|
128
|
+
for step in steps or ():
|
|
129
|
+
files = step.get("template_files") if isinstance(step, dict) else getattr(step, "template_files", None)
|
|
130
|
+
name = files.get("template") if isinstance(files, dict) else getattr(files, "template", None)
|
|
131
|
+
if isinstance(name, str) and name:
|
|
132
|
+
out.add(name)
|
|
133
|
+
return out
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def side_matches(side: str, name: str, templates: Iterable[str] = ()) -> bool:
|
|
137
|
+
"""Whether one side of a pair is this benchmark or policy: `*`; `template:<t>` for one made from t; or its name."""
|
|
138
|
+
if side == WILDCARD:
|
|
139
|
+
return True
|
|
140
|
+
if side.startswith(TEMPLATE):
|
|
141
|
+
return side[len(TEMPLATE):] in set(templates or ())
|
|
142
|
+
return side == name
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _rank_side(side: str) -> int:
|
|
146
|
+
return 3 if side == WILDCARD else 1 if side.startswith(TEMPLATE) else 0
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def rank(hit: AdapterPair | str) -> int:
|
|
150
|
+
"""How specific a matching pair is, the most specific lowest: name and name 0, name and template 1, template and
|
|
151
|
+
template 2, a side `*` 3 and over, "any" 7 - the order an eval's adapters are offered in."""
|
|
152
|
+
if hit == ANY:
|
|
153
|
+
return 7
|
|
154
|
+
return _rank_side(hit.benchmark) + _rank_side(hit.policy)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def match(pairs: Any, benchmark: tuple[str, Iterable[str]],
|
|
158
|
+
policy: tuple[str, Iterable[str]]) -> AdapterPair | str | None:
|
|
159
|
+
"""The pair of `pairs` that lets `benchmark` and `policy` - each (its name in the account, the templates it is
|
|
160
|
+
made from) - run with the adapter: the most specific one (rank); "any" for an adapter open to every pair; None
|
|
161
|
+
when none does, and for no pairs (a version registered before pairs)."""
|
|
162
|
+
pairs = _stored(pairs)
|
|
163
|
+
if pairs is None:
|
|
164
|
+
return None
|
|
165
|
+
if pairs == ANY:
|
|
166
|
+
return ANY
|
|
167
|
+
(bench_name, bench_templates), (policy_name, policy_templates) = benchmark, policy
|
|
168
|
+
hits = [p for p in pairs if side_matches(p.benchmark, bench_name, bench_templates)
|
|
169
|
+
and side_matches(p.policy, policy_name, policy_templates)]
|
|
170
|
+
return min(hits, key=rank) if hits else None
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def describe(pairs: Any) -> list[str]:
|
|
174
|
+
"""The pairs as lines a person reads: ["any"], or ["template:libero-10 → template:pi05-libero", ...]; [] for
|
|
175
|
+
none."""
|
|
176
|
+
pairs = _stored(pairs)
|
|
177
|
+
if pairs is None:
|
|
178
|
+
return []
|
|
179
|
+
if pairs == ANY:
|
|
180
|
+
return [ANY]
|
|
181
|
+
return [f"{p.benchmark} → {p.policy}" for p in pairs]
|
|
@@ -197,6 +197,11 @@ class DeploymentPolicy(BaseModel):
|
|
|
197
197
|
|
|
198
198
|
models: list[str] | None = Field(default=None, max_length=16)
|
|
199
199
|
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
plan_every_s: float | None = Field(default=None, gt=0)
|
|
204
|
+
|
|
200
205
|
@model_validator(mode="after")
|
|
201
206
|
def _param_names(self) -> "DeploymentPolicy":
|
|
202
207
|
for name in self.params or {}:
|
|
@@ -57,6 +57,7 @@ from sequence_base.contract.deployments import (
|
|
|
57
57
|
Resources,
|
|
58
58
|
Timeouts,
|
|
59
59
|
)
|
|
60
|
+
from sequence_base.contract.adapters import AdapterPair
|
|
60
61
|
from sequence_base.contract.errors import ErrorBody, WarmingError, error_codes_json_schema
|
|
61
62
|
from sequence_base.contract.volumes import (
|
|
62
63
|
UploadTarget,
|
|
@@ -163,6 +164,7 @@ WIRE_MODELS: dict[str, type[BaseModel]] = {
|
|
|
163
164
|
"TaskAgg": TaskAgg,
|
|
164
165
|
"MetricAgg": MetricAgg,
|
|
165
166
|
"EvalReport": EvalReport,
|
|
167
|
+
"AdapterPair": AdapterPair,
|
|
166
168
|
|
|
167
169
|
"SecretRef": SecretRef,
|
|
168
170
|
"SecretCreateRequest": SecretCreateRequest,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"additionalProperties": false,
|
|
3
|
+
"description": "One pair an adapter converts between: its benchmark side and its policy side, each an account's name,\n`template:<name>` or `*`.",
|
|
4
|
+
"properties": {
|
|
5
|
+
"benchmark": {
|
|
6
|
+
"title": "Benchmark",
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"policy": {
|
|
10
|
+
"title": "Policy",
|
|
11
|
+
"type": "string"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"required": [
|
|
15
|
+
"benchmark",
|
|
16
|
+
"policy"
|
|
17
|
+
],
|
|
18
|
+
"title": "AdapterPair",
|
|
19
|
+
"type": "object",
|
|
20
|
+
"x-contract-version": "0.5.17"
|
|
21
|
+
}
|
|
@@ -367,7 +367,7 @@
|
|
|
367
367
|
],
|
|
368
368
|
"title": "SeqFlags",
|
|
369
369
|
"type": "integer",
|
|
370
|
-
"x-contract-version": "0.5.
|
|
370
|
+
"x-contract-version": "0.5.17",
|
|
371
371
|
"x-flag-names": {
|
|
372
372
|
"CHECK": 65536,
|
|
373
373
|
"INFER": 16,
|
|
@@ -616,5 +616,5 @@
|
|
|
616
616
|
],
|
|
617
617
|
"title": "BenchmarkSpec",
|
|
618
618
|
"type": "object",
|
|
619
|
-
"x-contract-version": "0.5.
|
|
619
|
+
"x-contract-version": "0.5.17"
|
|
620
620
|
}
|
|
@@ -468,6 +468,19 @@
|
|
|
468
468
|
"default": null,
|
|
469
469
|
"title": "Params"
|
|
470
470
|
},
|
|
471
|
+
"plan_every_s": {
|
|
472
|
+
"anyOf": [
|
|
473
|
+
{
|
|
474
|
+
"exclusiveMinimum": 0,
|
|
475
|
+
"type": "number"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"type": "null"
|
|
479
|
+
}
|
|
480
|
+
],
|
|
481
|
+
"default": null,
|
|
482
|
+
"title": "Plan Every S"
|
|
483
|
+
},
|
|
471
484
|
"secrets": {
|
|
472
485
|
"items": {
|
|
473
486
|
"$ref": "#/$defs/SecretRef"
|
|
@@ -486,5 +499,5 @@
|
|
|
486
499
|
],
|
|
487
500
|
"title": "DeploymentPolicy",
|
|
488
501
|
"type": "object",
|
|
489
|
-
"x-contract-version": "0.5.
|
|
502
|
+
"x-contract-version": "0.5.17"
|
|
490
503
|
}
|
|
@@ -486,6 +486,19 @@
|
|
|
486
486
|
"default": null,
|
|
487
487
|
"title": "Params"
|
|
488
488
|
},
|
|
489
|
+
"plan_every_s": {
|
|
490
|
+
"anyOf": [
|
|
491
|
+
{
|
|
492
|
+
"exclusiveMinimum": 0,
|
|
493
|
+
"type": "number"
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"type": "null"
|
|
497
|
+
}
|
|
498
|
+
],
|
|
499
|
+
"default": null,
|
|
500
|
+
"title": "Plan Every S"
|
|
501
|
+
},
|
|
489
502
|
"secrets": {
|
|
490
503
|
"items": {
|
|
491
504
|
"$ref": "#/$defs/SecretRef"
|
|
@@ -1138,5 +1151,5 @@
|
|
|
1138
1151
|
],
|
|
1139
1152
|
"title": "DeploymentRequest",
|
|
1140
1153
|
"type": "object",
|
|
1141
|
-
"x-contract-version": "0.5.
|
|
1154
|
+
"x-contract-version": "0.5.17"
|
|
1142
1155
|
}
|
|
@@ -778,7 +778,7 @@
|
|
|
778
778
|
],
|
|
779
779
|
"title": "SeqFlags",
|
|
780
780
|
"type": "integer",
|
|
781
|
-
"x-contract-version": "0.5.
|
|
781
|
+
"x-contract-version": "0.5.17",
|
|
782
782
|
"x-flag-names": {
|
|
783
783
|
"CHECK": 65536,
|
|
784
784
|
"INFER": 16,
|
|
@@ -878,5 +878,5 @@
|
|
|
878
878
|
],
|
|
879
879
|
"title": "PolicyRegistration",
|
|
880
880
|
"type": "object",
|
|
881
|
-
"x-contract-version": "0.5.
|
|
881
|
+
"x-contract-version": "0.5.17"
|
|
882
882
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|