sequence-base 0.3.12__tar.gz → 0.3.14__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.3.12 → sequence_base-0.3.14}/PKG-INFO +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/pyproject.toml +6 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/__init__.py +4 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/constants/version.py +2 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/__init__.py +2 -2
- sequence_base-0.3.14/sequence_base/contract/errors.py +151 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schema_export.py +3 -2
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ActionChunk.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ActionContract.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ActionStep.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/AdapterTransform.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Autoscaler.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/BenchmarkConditionSpec.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/BenchmarkRegisterRequest.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/BenchmarkSpec.json +2 -2
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/BenchmarkStatusResponse.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/BootstrapResponse.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Camera.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ClampInfo.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/CodeBundle.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Concurrency.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Conditions.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ConnectRequest.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ConnectResponse.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/DeploymentAccepted.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/DeploymentPolicy.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/DeploymentRequest.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/DeploymentStatusResponse.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Embodiment.json +1 -1
- sequence_base-0.3.14/sequence_base/schemas/ErrorBody.json +98 -0
- sequence_base-0.3.14/sequence_base/schemas/ErrorCodes.json +130 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Estimate.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/EvalDryRunResponse.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/EvalReport.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/EvalRequest.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/EvalResponse.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ImageFrame.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ImageSpec.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ImageStepApt.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ImageStepEnv.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ImageStepRun.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ImageStepUvPip.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/InferParam.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Lease.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/LossyTransform.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/MetricAgg.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Observation.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/ObservationContract.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/PolicyRegistration.json +2 -2
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/PolicySpec.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Proprioception.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/RenderSpec.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Resources.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/RolloutResult.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/SecretCreateRequest.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/SecretInfo.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/SecretRef.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/SeqFlags.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Step.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/SuiteAgg.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/TaskAgg.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Timeouts.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/UploadTarget.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/UsageReport.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/Variant.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/VolumeAttach.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/VolumeFile.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/VolumeInfo.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/VolumeMount.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/VolumeRef.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/VolumeUploadRequest.json +1 -1
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/schemas/VolumeUploadResponse.json +1 -1
- sequence_base-0.3.14/sequence_base/schemas/WarmingError.json +90 -0
- sequence_base-0.3.12/.github/workflows/ci.yml +0 -32
- sequence_base-0.3.12/docs/platform/README.md +0 -66
- sequence_base-0.3.12/docs/platform/REVIEW.md +0 -86
- sequence_base-0.3.12/docs/platform/START.md +0 -366
- sequence_base-0.3.12/docs/platform/accounts.md +0 -162
- sequence_base-0.3.12/docs/platform/billing.md +0 -116
- sequence_base-0.3.12/docs/platform/build/BUILD_LOG.md +0 -222
- sequence_base-0.3.12/docs/platform/build/goal_sha256.json +0 -31
- sequence_base-0.3.12/docs/platform/build/gs-build-wave.js +0 -163
- sequence_base-0.3.12/docs/platform/build/gs-spec-goals.js +0 -41
- sequence_base-0.3.12/docs/platform/container.md +0 -55
- sequence_base-0.3.12/docs/platform/contracts.md +0 -233
- sequence_base-0.3.12/docs/platform/deploy/PLAN.md +0 -93
- sequence_base-0.3.12/docs/platform/deploy/PROD_REORG.md +0 -78
- sequence_base-0.3.12/docs/platform/deploy/SCHEMA_COMPAT.md +0 -38
- sequence_base-0.3.12/docs/platform/deploy/archive/sequences-gw.genseq-506918.20261001.yaml +0 -109
- sequence_base-0.3.12/docs/platform/eval.md +0 -102
- sequence_base-0.3.12/docs/platform/gateway.md +0 -80
- sequence_base-0.3.12/docs/platform/goals/A1.yaml +0 -39
- sequence_base-0.3.12/docs/platform/goals/A2.yaml +0 -26
- sequence_base-0.3.12/docs/platform/goals/A3.yaml +0 -24
- sequence_base-0.3.12/docs/platform/goals/C1.yaml +0 -32
- sequence_base-0.3.12/docs/platform/goals/C2.yaml +0 -27
- sequence_base-0.3.12/docs/platform/goals/C3.yaml +0 -22
- sequence_base-0.3.12/docs/platform/goals/C4.yaml +0 -22
- sequence_base-0.3.12/docs/platform/goals/C5.yaml +0 -34
- sequence_base-0.3.12/docs/platform/goals/G1.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/G2.yaml +0 -26
- sequence_base-0.3.12/docs/platform/goals/G3.yaml +0 -32
- sequence_base-0.3.12/docs/platform/goals/G4.yaml +0 -45
- sequence_base-0.3.12/docs/platform/goals/G5.yaml +0 -43
- sequence_base-0.3.12/docs/platform/goals/O1.yaml +0 -19
- sequence_base-0.3.12/docs/platform/goals/O2.yaml +0 -27
- sequence_base-0.3.12/docs/platform/goals/O3.yaml +0 -28
- sequence_base-0.3.12/docs/platform/goals/O4.yaml +0 -25
- sequence_base-0.3.12/docs/platform/goals/O5.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/R1.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/R2.yaml +0 -23
- sequence_base-0.3.12/docs/platform/goals/R3.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/S1.yaml +0 -32
- sequence_base-0.3.12/docs/platform/goals/S2.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/S3.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/S4.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/S5.yaml +0 -56
- sequence_base-0.3.12/docs/platform/goals/S6.yaml +0 -34
- sequence_base-0.3.12/docs/platform/goals/V1-storage.md +0 -26
- sequence_base-0.3.12/docs/platform/goals/V2-user-quotas.md +0 -27
- sequence_base-0.3.12/docs/platform/goals/W0.1.yaml +0 -30
- sequence_base-0.3.12/docs/platform/goals/W0.2.yaml +0 -21
- sequence_base-0.3.12/docs/platform/modal/README.md +0 -26
- sequence_base-0.3.12/docs/platform/modal/architecture.md +0 -27
- sequence_base-0.3.12/docs/platform/modal/connect.md +0 -41
- sequence_base-0.3.12/docs/platform/modal/cost.md +0 -52
- sequence_base-0.3.12/docs/platform/modal/custom-domain.md +0 -47
- sequence_base-0.3.12/docs/platform/modal/debugging.md +0 -42
- sequence_base-0.3.12/docs/platform/modal/goals.md +0 -92
- sequence_base-0.3.12/docs/platform/modal/limits.md +0 -50
- sequence_base-0.3.12/docs/platform/modal/plan.md +0 -65
- sequence_base-0.3.12/docs/platform/modal/white-label.md +0 -33
- sequence_base-0.3.12/docs/platform/modal/wiring.md +0 -36
- sequence_base-0.3.12/docs/platform/observability.md +0 -128
- sequence_base-0.3.12/docs/platform/references.md +0 -48
- sequence_base-0.3.12/docs/platform/sdk.md +0 -246
- sequence_base-0.3.12/sequence_base/contract/errors.py +0 -45
- sequence_base-0.3.12/sequence_base/schemas/ErrorBody.json +0 -32
- sequence_base-0.3.12/sequence_base/schemas/WarmingError.json +0 -50
- sequence_base-0.3.12/tests/test_codec_roundtrip.py +0 -133
- sequence_base-0.3.12/tests/test_contracts.py +0 -816
- sequence_base-0.3.12/tests/test_weights_parts.py +0 -62
- {sequence_base-0.3.12 → sequence_base-0.3.14}/.gitignore +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/README.md +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/auth.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/codec/__init__.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/codec/image.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/codec/resize.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/constants/__init__.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/constants/env.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/constants/headers.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/accounts.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/act.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/benchmarks.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/connect.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/deployments.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/eval.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/flags.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/io.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/policy.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/contract/volumes.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/errors/__init__.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/errors/transport.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/obs/__init__.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/obs/log.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/obs/rid.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/sequence_base/telemetry/__init__.py +0 -0
- {sequence_base-0.3.12 → sequence_base-0.3.14}/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.
|
|
3
|
+
Version: 0.3.14
|
|
4
4
|
Summary: Shared foundation for the Sequences platform — wire contract, correlation, error taxonomy, constants. Used by the robot SDK, gateway, and container harness.
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: pydantic>=2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sequence-base"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.14"
|
|
4
4
|
description = "Shared foundation for the Sequences platform — wire contract, correlation, error taxonomy, constants. Used by the robot SDK, gateway, and container harness."
|
|
5
5
|
requires-python = ">=3.11"
|
|
6
6
|
dependencies = ["pydantic>=2.0"]
|
|
@@ -18,3 +18,8 @@ build-backend = "hatchling.build"
|
|
|
18
18
|
|
|
19
19
|
[tool.hatch.build.targets.wheel]
|
|
20
20
|
packages = ["sequence_base"]
|
|
21
|
+
|
|
22
|
+
# The sdist is an allowlist: without one hatchling packs the whole repo, and 0.3.0-0.3.12 shipped the
|
|
23
|
+
# internal platform docs to PyPI.
|
|
24
|
+
[tool.hatch.build.targets.sdist]
|
|
25
|
+
include = ["/sequence_base", "/README.md", "/pyproject.toml"]
|
|
@@ -48,8 +48,10 @@ from sequence_base.contract import ( # noqa: F401 (re-export surface)
|
|
|
48
48
|
DeploymentRequest,
|
|
49
49
|
DeploymentState,
|
|
50
50
|
DeploymentStatusResponse,
|
|
51
|
+
ERRORS,
|
|
51
52
|
ErrorBody,
|
|
52
53
|
ErrorCode,
|
|
54
|
+
ErrorSpec,
|
|
53
55
|
Estimate,
|
|
54
56
|
EvalDryRunResponse,
|
|
55
57
|
EvalReport,
|
|
@@ -87,6 +89,7 @@ from sequence_base.contract import ( # noqa: F401 (re-export surface)
|
|
|
87
89
|
VolumeMount,
|
|
88
90
|
VolumeRef,
|
|
89
91
|
WarmingError,
|
|
92
|
+
code_for_status,
|
|
90
93
|
)
|
|
91
94
|
|
|
92
95
|
# the single schema-level version stamp (embedded in every exported JSON Schema)
|
|
@@ -137,7 +140,7 @@ __all__ = [
|
|
|
137
140
|
# contract 7 — volumes (uploaded checkpoints and datasets)
|
|
138
141
|
"VolumeFile", "VolumeUploadRequest", "UploadTarget", "VolumeUploadResponse", "VolumeInfo", "parse_vol",
|
|
139
142
|
# error bodies + version
|
|
140
|
-
"ErrorCode", "ErrorBody", "WarmingError", "CONTRACT_VERSION",
|
|
143
|
+
"ErrorCode", "ErrorBody", "WarmingError", "ERRORS", "ErrorSpec", "code_for_status", "CONTRACT_VERSION",
|
|
141
144
|
# obs
|
|
142
145
|
"HEADER", "new_rid", "clean", "log", "Timer", "enabled",
|
|
143
146
|
# errors (exception taxonomy)
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
# across deployments / repos can tell which version of a shape it is validating against. MUST change
|
|
5
5
|
# whenever any shared wire shape changes (a field added / removed / retyped) — that is what makes
|
|
6
6
|
# contract evolution mechanically detectable instead of eyeballed. Bump on any shape change.
|
|
7
|
-
CONTRACT_VERSION = "0.4.
|
|
7
|
+
CONTRACT_VERSION = "0.4.12" # 0.4.11 -> 0.4.12: one error definition — ErrorBody is every non-2xx body (detail, code, retryable, retry_after_s, request_id, hint, details), ErrorCode covers every case, ERRORS / ErrorCodes.json give each code its status, retryability, SDK class and CLI exit code
|
|
8
|
+
# previous: 0.4.11 # 0.4.10 -> 0.4.11: weights in named parts (weights_name, extra_weights)
|
|
8
9
|
# previous: 0.4.8 # 0.4.7 -> 0.4.8: ImageSpec.python, ImageStepRun.secrets, Resources.region, DeploymentRequest/BenchmarkRegisterRequest.image_context
|
|
9
10
|
# previous: 0.4.7 # 0.4.6 -> 0.4.7: ActionContract.bounds / max_delta / on_violation (action limits)
|
|
10
11
|
# previous: 0.4.6 # 0.4.5 -> 0.4.6: InferParam + DeploymentPolicy.params; EvalRequest.params / variants / record; BenchmarkRegisterRequest.gpu
|
|
@@ -102,7 +102,7 @@ from sequence_base.contract.volumes import (
|
|
|
102
102
|
)
|
|
103
103
|
|
|
104
104
|
# shared error bodies
|
|
105
|
-
from sequence_base.contract.errors import ErrorBody, ErrorCode, WarmingError
|
|
105
|
+
from sequence_base.contract.errors import ERRORS, ErrorBody, ErrorCode, ErrorSpec, WarmingError, code_for_status
|
|
106
106
|
|
|
107
107
|
__all__ = [
|
|
108
108
|
# contract 4
|
|
@@ -129,5 +129,5 @@ __all__ = [
|
|
|
129
129
|
"MAX_FILES", "MAX_UPLOAD_BYTES", "VolumeFile", "VolumeUploadRequest", "UploadTarget", "VolumeUploadResponse",
|
|
130
130
|
"VolumeInfo", "check_volume_name", "parse_vol",
|
|
131
131
|
# errors
|
|
132
|
-
"ErrorCode", "ErrorBody", "WarmingError",
|
|
132
|
+
"ErrorCode", "ErrorBody", "WarmingError", "ERRORS", "ErrorSpec", "code_for_status",
|
|
133
133
|
]
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared error wire types: one definition for every non-2xx response the platform sends.
|
|
3
|
+
|
|
4
|
+
Every error the gateway or a worker returns is an `ErrorBody`. `ERRORS` is the single table that
|
|
5
|
+
gives each `ErrorCode` its HTTP status, whether a retry can help, the SDK exception it becomes and
|
|
6
|
+
the `seq` CLI exit code. The gateway and the worker harness import it; the SDK, which cannot import
|
|
7
|
+
this package on a robot, carries a generated copy that a test compares against `ErrorCodes.json`.
|
|
8
|
+
That is what makes the same situation surface the same way at every entry point.
|
|
9
|
+
{gs-plans/deploy-only/errors.md "同一种情况,不管从哪个入口碰到,结果都一样"}
|
|
10
|
+
|
|
11
|
+
Distinct from `sequence_base.errors.transport`, which is the internal exception taxonomy the gateway
|
|
12
|
+
and harness raise before a response is built.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from enum import Enum
|
|
17
|
+
from typing import Any, NamedTuple
|
|
18
|
+
|
|
19
|
+
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
20
|
+
from pydantic_core import PydanticUndefined
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ErrorCode(str, Enum):
|
|
24
|
+
"""What a caller switches on. The wording of `detail` may change; a code does not."""
|
|
25
|
+
|
|
26
|
+
INVALID_REQUEST = "invalid_request"
|
|
27
|
+
PAYLOAD_TOO_LARGE = "payload_too_large"
|
|
28
|
+
UNAUTHENTICATED = "unauthenticated"
|
|
29
|
+
FORBIDDEN = "forbidden"
|
|
30
|
+
INSUFFICIENT_CREDIT = "insufficient_credit"
|
|
31
|
+
BUDGET_EXHAUSTED = "budget_exhausted"
|
|
32
|
+
NOT_FOUND = "not_found"
|
|
33
|
+
CONFLICT = "conflict"
|
|
34
|
+
GONE = "gone"
|
|
35
|
+
BUSY = "busy"
|
|
36
|
+
WARMING = "warming"
|
|
37
|
+
UNAVAILABLE = "unavailable"
|
|
38
|
+
UPSTREAM_ERROR = "upstream_error"
|
|
39
|
+
TIMEOUT = "timeout"
|
|
40
|
+
POLICY_ERROR = "policy_error"
|
|
41
|
+
INTERNAL = "internal"
|
|
42
|
+
DEPENDENCY_MISSING = "dependency_missing"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ErrorSpec(NamedTuple):
|
|
46
|
+
status: int # the HTTP status the code is sent with
|
|
47
|
+
retryable: bool # whether the identical request can succeed later without the caller changing anything
|
|
48
|
+
sdk_class: str # the sequence_ai exception it becomes
|
|
49
|
+
exit_code: int # the `seq` CLI exit code
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# Grouped by what the caller does next, not by which module failed. Exit codes: 1 internal, 2 fix the
|
|
53
|
+
# request, 3 credentials or permission, 4 missing or retired, 5 state conflict, 6 money, 7 retry later.
|
|
54
|
+
ERRORS: dict[ErrorCode, ErrorSpec] = {
|
|
55
|
+
ErrorCode.INVALID_REQUEST: ErrorSpec(400, False, "InvalidRequest", 2),
|
|
56
|
+
ErrorCode.PAYLOAD_TOO_LARGE: ErrorSpec(413, False, "InvalidRequest", 2),
|
|
57
|
+
ErrorCode.UNAUTHENTICATED: ErrorSpec(401, False, "AuthError", 3),
|
|
58
|
+
ErrorCode.FORBIDDEN: ErrorSpec(403, False, "PermissionDenied", 3),
|
|
59
|
+
ErrorCode.INSUFFICIENT_CREDIT: ErrorSpec(402, False, "OutOfCredit", 6),
|
|
60
|
+
ErrorCode.BUDGET_EXHAUSTED: ErrorSpec(402, False, "OutOfCredit", 6),
|
|
61
|
+
ErrorCode.NOT_FOUND: ErrorSpec(404, False, "NotFound", 4),
|
|
62
|
+
ErrorCode.CONFLICT: ErrorSpec(409, False, "Conflict", 5),
|
|
63
|
+
ErrorCode.GONE: ErrorSpec(410, False, "Gone", 4),
|
|
64
|
+
ErrorCode.BUSY: ErrorSpec(429, True, "Unavailable", 7),
|
|
65
|
+
ErrorCode.WARMING: ErrorSpec(503, True, "Unavailable", 7),
|
|
66
|
+
ErrorCode.UNAVAILABLE: ErrorSpec(503, True, "Unavailable", 7),
|
|
67
|
+
ErrorCode.UPSTREAM_ERROR: ErrorSpec(502, True, "Unavailable", 7),
|
|
68
|
+
ErrorCode.TIMEOUT: ErrorSpec(504, True, "Unavailable", 7),
|
|
69
|
+
ErrorCode.POLICY_ERROR: ErrorSpec(500, False, "PolicyError", 1),
|
|
70
|
+
ErrorCode.INTERNAL: ErrorSpec(500, False, "InternalError", 1),
|
|
71
|
+
ErrorCode.DEPENDENCY_MISSING: ErrorSpec(424, False, "InternalError", 1),
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# A response that carries no code (an older server, a proxy in between) is read by its status alone.
|
|
75
|
+
_CODE_FOR_STATUS: dict[int, ErrorCode] = {
|
|
76
|
+
400: ErrorCode.INVALID_REQUEST, 401: ErrorCode.UNAUTHENTICATED, 402: ErrorCode.INSUFFICIENT_CREDIT,
|
|
77
|
+
403: ErrorCode.FORBIDDEN, 404: ErrorCode.NOT_FOUND, 405: ErrorCode.INVALID_REQUEST,
|
|
78
|
+
409: ErrorCode.CONFLICT, 410: ErrorCode.GONE, 413: ErrorCode.PAYLOAD_TOO_LARGE,
|
|
79
|
+
422: ErrorCode.INVALID_REQUEST, 424: ErrorCode.DEPENDENCY_MISSING, 429: ErrorCode.BUSY,
|
|
80
|
+
500: ErrorCode.INTERNAL, 502: ErrorCode.UPSTREAM_ERROR, 503: ErrorCode.UNAVAILABLE,
|
|
81
|
+
504: ErrorCode.TIMEOUT,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def code_for_status(status: int) -> ErrorCode:
|
|
86
|
+
"""The code a bare status stands for: the table's own entry, else invalid_request for any other 4xx
|
|
87
|
+
and internal for any other 5xx."""
|
|
88
|
+
if status in _CODE_FOR_STATUS:
|
|
89
|
+
return _CODE_FOR_STATUS[status]
|
|
90
|
+
return ErrorCode.INVALID_REQUEST if 400 <= status < 500 else ErrorCode.INTERNAL
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class ErrorBody(BaseModel):
|
|
94
|
+
"""The body of every non-2xx response. `detail` stays a plain sentence (the console already reads
|
|
95
|
+
that field); everything a program needs is in `code` and `details`."""
|
|
96
|
+
|
|
97
|
+
model_config = ConfigDict(extra="forbid")
|
|
98
|
+
|
|
99
|
+
detail: str = Field(..., description="One sentence for a person. Its wording may change; switch on `code`.")
|
|
100
|
+
code: ErrorCode
|
|
101
|
+
retryable: bool = Field(..., description="Whether the identical request can succeed later. Always ERRORS[code].retryable")
|
|
102
|
+
retry_after_s: float | None = Field(default=None, description="Seconds to wait before retrying; sent with 429 and 503, mirrored in Retry-After")
|
|
103
|
+
request_id: str | None = Field(default=None, description="Quote it when reporting a problem")
|
|
104
|
+
hint: str | None = Field(default=None, description="The next step, e.g. a command to run")
|
|
105
|
+
details: dict[str, Any] = Field(default_factory=dict, description="Fields specific to the code: resource, name, reason, since, replacement, state, exception, ...")
|
|
106
|
+
|
|
107
|
+
@model_validator(mode="before")
|
|
108
|
+
@classmethod
|
|
109
|
+
def _retryable_from_table(cls, data: Any) -> Any:
|
|
110
|
+
# Filled from the table so no producer can contradict it; a body that states the opposite is refused.
|
|
111
|
+
# A subclass that fixes the code (WarmingError) is read through its default.
|
|
112
|
+
if not isinstance(data, dict):
|
|
113
|
+
return data
|
|
114
|
+
code = data.get("code")
|
|
115
|
+
if code is None:
|
|
116
|
+
default = cls.model_fields["code"].default
|
|
117
|
+
code = None if default is PydanticUndefined else default
|
|
118
|
+
if code is not None:
|
|
119
|
+
want = ERRORS[ErrorCode(code)].retryable
|
|
120
|
+
if data.get("retryable") is None:
|
|
121
|
+
data = {**data, "retryable": want}
|
|
122
|
+
elif data["retryable"] != want:
|
|
123
|
+
raise ValueError(f"retryable for {ErrorCode(code).value} is {want}")
|
|
124
|
+
return data
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def status(self) -> int:
|
|
128
|
+
return ERRORS[self.code].status
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class WarmingError(ErrorBody):
|
|
132
|
+
"""503 while a worker loads: the one error whose remedy is purely to wait `retry_after_s`. A known
|
|
133
|
+
time-to-ready goes in `details["eta_s"]`."""
|
|
134
|
+
|
|
135
|
+
code: ErrorCode = ErrorCode.WARMING
|
|
136
|
+
retry_after_s: float
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def error_codes_json_schema(contract_version: str) -> dict:
|
|
140
|
+
"""`ERRORS` as data, so a consumer that cannot import this package (the SDK on a robot) can check its
|
|
141
|
+
own copy against it: the code is a string enum, `x-errors` gives each code its status, retryability,
|
|
142
|
+
SDK class and CLI exit code."""
|
|
143
|
+
return {
|
|
144
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
145
|
+
"title": "ErrorCode",
|
|
146
|
+
"description": "Every error code the platform sends, with what each one means for the caller.",
|
|
147
|
+
"type": "string",
|
|
148
|
+
"enum": [c.value for c in ErrorCode],
|
|
149
|
+
"x-errors": {c.value: spec._asdict() for c, spec in ERRORS.items()},
|
|
150
|
+
"x-contract-version": contract_version,
|
|
151
|
+
}
|
|
@@ -57,7 +57,7 @@ from sequence_base.contract.deployments import (
|
|
|
57
57
|
Timeouts,
|
|
58
58
|
VolumeAttach,
|
|
59
59
|
)
|
|
60
|
-
from sequence_base.contract.errors import ErrorBody, WarmingError
|
|
60
|
+
from sequence_base.contract.errors import ErrorBody, WarmingError, error_codes_json_schema
|
|
61
61
|
from sequence_base.contract.volumes import (
|
|
62
62
|
UploadTarget,
|
|
63
63
|
VolumeFile,
|
|
@@ -237,9 +237,10 @@ def build_schema(model: type[BaseModel]) -> dict:
|
|
|
237
237
|
|
|
238
238
|
|
|
239
239
|
def all_schemas() -> dict[str, dict]:
|
|
240
|
-
"""Every exported schema, by filename stem — pydantic models
|
|
240
|
+
"""Every exported schema, by filename stem — pydantic models, the SeqFlags IntFlag and the error table."""
|
|
241
241
|
out: dict[str, dict] = {name: build_schema(m) for name, m in WIRE_MODELS.items()}
|
|
242
242
|
out["SeqFlags"] = seqflags_json_schema(CONTRACT_VERSION)
|
|
243
|
+
out["ErrorCodes"] = error_codes_json_schema(CONTRACT_VERSION)
|
|
243
244
|
return out
|
|
244
245
|
|
|
245
246
|
|
|
@@ -235,7 +235,7 @@
|
|
|
235
235
|
],
|
|
236
236
|
"title": "SeqFlags",
|
|
237
237
|
"type": "integer",
|
|
238
|
-
"x-contract-version": "0.4.
|
|
238
|
+
"x-contract-version": "0.4.12",
|
|
239
239
|
"x-flag-names": {
|
|
240
240
|
"CHECK": 65536,
|
|
241
241
|
"INFER": 16,
|
|
@@ -425,5 +425,5 @@
|
|
|
425
425
|
],
|
|
426
426
|
"title": "BenchmarkSpec",
|
|
427
427
|
"type": "object",
|
|
428
|
-
"x-contract-version": "0.4.
|
|
428
|
+
"x-contract-version": "0.4.12"
|
|
429
429
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$defs": {
|
|
3
|
+
"ErrorCode": {
|
|
4
|
+
"description": "What a caller switches on. The wording of `detail` may change; a code does not.",
|
|
5
|
+
"enum": [
|
|
6
|
+
"invalid_request",
|
|
7
|
+
"payload_too_large",
|
|
8
|
+
"unauthenticated",
|
|
9
|
+
"forbidden",
|
|
10
|
+
"insufficient_credit",
|
|
11
|
+
"budget_exhausted",
|
|
12
|
+
"not_found",
|
|
13
|
+
"conflict",
|
|
14
|
+
"gone",
|
|
15
|
+
"busy",
|
|
16
|
+
"warming",
|
|
17
|
+
"unavailable",
|
|
18
|
+
"upstream_error",
|
|
19
|
+
"timeout",
|
|
20
|
+
"policy_error",
|
|
21
|
+
"internal",
|
|
22
|
+
"dependency_missing"
|
|
23
|
+
],
|
|
24
|
+
"title": "ErrorCode",
|
|
25
|
+
"type": "string"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"description": "The body of every non-2xx response. `detail` stays a plain sentence (the console already reads\nthat field); everything a program needs is in `code` and `details`.",
|
|
30
|
+
"properties": {
|
|
31
|
+
"code": {
|
|
32
|
+
"$ref": "#/$defs/ErrorCode"
|
|
33
|
+
},
|
|
34
|
+
"detail": {
|
|
35
|
+
"description": "One sentence for a person. Its wording may change; switch on `code`.",
|
|
36
|
+
"title": "Detail",
|
|
37
|
+
"type": "string"
|
|
38
|
+
},
|
|
39
|
+
"details": {
|
|
40
|
+
"additionalProperties": true,
|
|
41
|
+
"description": "Fields specific to the code: resource, name, reason, since, replacement, state, exception, ...",
|
|
42
|
+
"title": "Details",
|
|
43
|
+
"type": "object"
|
|
44
|
+
},
|
|
45
|
+
"hint": {
|
|
46
|
+
"anyOf": [
|
|
47
|
+
{
|
|
48
|
+
"type": "string"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"type": "null"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"default": null,
|
|
55
|
+
"description": "The next step, e.g. a command to run",
|
|
56
|
+
"title": "Hint"
|
|
57
|
+
},
|
|
58
|
+
"request_id": {
|
|
59
|
+
"anyOf": [
|
|
60
|
+
{
|
|
61
|
+
"type": "string"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"type": "null"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"default": null,
|
|
68
|
+
"description": "Quote it when reporting a problem",
|
|
69
|
+
"title": "Request Id"
|
|
70
|
+
},
|
|
71
|
+
"retry_after_s": {
|
|
72
|
+
"anyOf": [
|
|
73
|
+
{
|
|
74
|
+
"type": "number"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"type": "null"
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"default": null,
|
|
81
|
+
"description": "Seconds to wait before retrying; sent with 429 and 503, mirrored in Retry-After",
|
|
82
|
+
"title": "Retry After S"
|
|
83
|
+
},
|
|
84
|
+
"retryable": {
|
|
85
|
+
"description": "Whether the identical request can succeed later. Always ERRORS[code].retryable",
|
|
86
|
+
"title": "Retryable",
|
|
87
|
+
"type": "boolean"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"required": [
|
|
91
|
+
"detail",
|
|
92
|
+
"code",
|
|
93
|
+
"retryable"
|
|
94
|
+
],
|
|
95
|
+
"title": "ErrorBody",
|
|
96
|
+
"type": "object",
|
|
97
|
+
"x-contract-version": "0.4.12"
|
|
98
|
+
}
|