simulo-interfaces 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {simulo_interfaces-0.3.0/src/simulo_interfaces.egg-info → simulo_interfaces-0.4.0}/PKG-INFO +1 -1
  2. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/pyproject.toml +1 -1
  3. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/__init__.py +9 -0
  4. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/submit.py +96 -0
  5. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0/src/simulo_interfaces.egg-info}/PKG-INFO +1 -1
  6. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/MANIFEST.in +0 -0
  7. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/PYPI.md +0 -0
  8. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/setup.cfg +0 -0
  9. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/__init__.py +0 -0
  10. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/exceptions.py +0 -0
  11. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/ids.py +0 -0
  12. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/app.py +0 -0
  13. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/asset.py +0 -0
  14. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/callbacks.py +0 -0
  15. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/debug.py +0 -0
  16. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/domain.py +0 -0
  17. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/enums.py +0 -0
  18. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/runs.py +0 -0
  19. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/runtime.py +0 -0
  20. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/platform/volume.py +0 -0
  21. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/py.typed +0 -0
  22. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/__init__.py +0 -0
  23. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/anomaly.py +0 -0
  24. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/components.py +0 -0
  25. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/env.py +0 -0
  26. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/player.py +0 -0
  27. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/policy.py +0 -0
  28. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/scenario.py +0 -0
  29. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/task.py +0 -0
  30. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/tensors.py +0 -0
  31. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo/interfaces/runtime/trainer.py +0 -0
  32. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo_interfaces.egg-info/SOURCES.txt +0 -0
  33. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo_interfaces.egg-info/dependency_links.txt +0 -0
  34. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo_interfaces.egg-info/requires.txt +0 -0
  35. {simulo_interfaces-0.3.0 → simulo_interfaces-0.4.0}/src/simulo_interfaces.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo-interfaces
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simulo-interfaces"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package."
9
9
  readme = "PYPI.md"
10
10
  requires-python = ">=3.11"
@@ -38,11 +38,15 @@ from simulo.interfaces.platform.submit import (
38
38
  MAX_LOG_TOTAL_BYTES,
39
39
  MAX_PACKAGE_BYTES,
40
40
  MAX_RESULT_BYTES,
41
+ MAX_SEED_REF_CHARS,
41
42
  MODEL_KINDS,
42
43
  PACKAGE_ARCHIVE_ROUTE_TEMPLATE,
43
44
  PACKAGES_ROUTE,
44
45
  RESERVED_RUNTIME_ENV_KEYS,
45
46
  RESERVED_RUNTIME_ENV_PREFIXES,
47
+ SEED_JOB_REF_GRAMMAR,
48
+ SEED_SOURCE_CONFLICT_CODE,
49
+ SEED_SOURCE_FIELDS,
46
50
  WORKER_CLAIM_ROUTE,
47
51
  WORKER_JOB_COMPLETE_ROUTE_TEMPLATE,
48
52
  WORKER_JOB_HEARTBEAT_ROUTE_TEMPLATE,
@@ -110,6 +114,11 @@ __all__ = [
110
114
  "RecordingRecord",
111
115
  "RESERVED_RUNTIME_ENV_KEYS",
112
116
  "RESERVED_RUNTIME_ENV_PREFIXES",
117
+ # explicit-run-intent plan: submit-time seed source (additive)
118
+ "SEED_SOURCE_FIELDS",
119
+ "SEED_SOURCE_CONFLICT_CODE",
120
+ "SEED_JOB_REF_GRAMMAR",
121
+ "MAX_SEED_REF_CHARS",
113
122
  # protocols
114
123
  "RuntimeProtocol",
115
124
  "AssetProtocol",
@@ -83,6 +83,49 @@ platform-standard shape: ``{"error": {"code": ..., "message": ..., "request_id":
83
83
  with the *existing* record rather than creating a second job — a client
84
84
  retry (e.g. after a dropped response) must not double-submit.
85
85
 
86
+ **Seed source (explicit-run-intent plan, additive):** the request body
87
+ optionally carries one of two further top-level fields, both **siblings of
88
+ ``args`` — never nested inside it, and never written into the package
89
+ manifest**::
90
+
91
+ {"package_id": "...", "job_name": "train_cartpole", "args": {...},
92
+ "seed_from_job_id": "<job-id>[:latest]"}
93
+
94
+ This placement is load-bearing, not stylistic: ``args``' canonical JSON is
95
+ what the client hashes (together with the source digest and job name) to
96
+ derive ``package_id`` (``_client/manifest.py``), so a seed reference living
97
+ inside ``args`` would make re-running the exact same package bytes with a
98
+ *different* seed register as a *different* package — collapsing package
99
+ identity (content-addressed, immutable) into job identity (per-submit,
100
+ mutable). ``viewstream`` (the worker's ``_child_env``) already follows this
101
+ same package-≠-job placement rule; these two fields are the same shape.
102
+ Consumers of this contract MUST build the seed fields onto the request
103
+ exactly the way ``create_job`` builds ``viewstream`` today — as extra keys
104
+ set directly on the top-level body dict — and MUST NOT fold them into the
105
+ ``args`` mapping that gets hashed.
106
+
107
+ :data:`SEED_SOURCE_FIELDS` pins the two field names:
108
+
109
+ - ``seed_from_job_id`` (``str``) — continue training from another job's
110
+ checkpoint. A bare job id selects that job's ``best.pt``; suffixing
111
+ ``:latest`` (``"<job-id>:latest"``) selects ``latest.pt`` instead — the
112
+ suffix lives inside this one string; there is no separate "kind" field.
113
+ - ``seed_from_model_id`` (``str``) — continue from one exact
114
+ :class:`ModelRecord` artifact, pinned by id.
115
+
116
+ Both default to (and an old client that predates this field pair always
117
+ sends) absent/``None`` — a **fresh run**, the new default with no
118
+ exceptions: an un-upgraded client that omits both fields degrades to
119
+ exactly the semantics this plan wants, with zero change to the bytes it
120
+ already sends. The two are **mutually exclusive**: a request setting both
121
+ is rejected whole, ``422`` :data:`SEED_SOURCE_CONFLICT_CODE`
122
+ (``"seed_source_conflict"``) — the server never silently prefers one over
123
+ the other. Further validation of the referenced job/model (org membership,
124
+ terminal status, artifact kind) is server-side business logic layered on
125
+ top of this wire shape, not defined by this module — see the
126
+ explicit-run-intent plan's "Server validation" section
127
+ (``context/implementation-plans/explicit-run-intent-plan.md``).
128
+
86
129
  ## Client-facing: recordings
87
130
 
88
131
  * :data:`JOB_RECORDINGS_ROUTE_TEMPLATE` (``GET``) — paginated envelope of
@@ -298,6 +341,59 @@ JOB_MODEL_DOWNLOAD_ROUTE_TEMPLATE = "/v1/jobs/{job_id}/models/{model_id}/downloa
298
341
  #: There is deliberately no separate ``*_SUBMIT_ROUTE`` constant here — see
299
342
  #: the module docstring's "Client-facing: package submit + job create" section.
300
343
 
344
+ #: The two mutually-exclusive, optional ``POST /v1/jobs`` body fields — both
345
+ #: **siblings of ``args``**, never nested inside it — that seed a fresh job's
346
+ #: starting checkpoint from another job's or model's already-uploaded
347
+ #: artifact (explicit-run-intent plan). Neither set = a fresh run, the
348
+ #: default and the only behavior an old client (unaware of this pair) can
349
+ #: produce. Setting both in the same request is rejected whole as
350
+ #: :data:`SEED_SOURCE_CONFLICT_CODE`. Full field-by-field semantics live in
351
+ #: the module docstring's "Client-facing: package submit + job create"
352
+ #: section, above — this tuple exists so PRs building against this contract
353
+ #: (control plane request validation, the thin client's ``--from`` flag —
354
+ #: which resolves a job-ref + artifact name to a concrete ``model_id``, so no
355
+ #: UUID ever reaches a human) import one pinned pair of literal names instead
356
+ #: of re-typing them. There is deliberately no ``--from-model`` CLI flag.
357
+ SEED_SOURCE_FIELDS = ("seed_from_job_id", "seed_from_model_id")
358
+
359
+ #: Grammar of the ``seed_from_job_id`` value (the ``seed_from_model_id`` value
360
+ #: is a bare model id, no suffix). Pinned here because BOTH sides parse it and
361
+ #: a divergence is silent: the client would accept a value the server rejects
362
+ #: (a wasted package build + archive upload for a typo), or reject one the
363
+ #: server accepts.
364
+ #:
365
+ #: ``<job-ref>[:<kind>]`` — ``job-ref`` is a full job UUID or an unambiguous
366
+ #: id prefix; ``kind`` is one of :data:`MODEL_KINDS`, compared **lowercased
367
+ #: after stripping surrounding whitespace**. Rules, in the order both sides
368
+ #: apply them:
369
+ #:
370
+ #: * ``":" not in value`` → the whole value is the ref; ``kind`` defaults to
371
+ #: ``MODEL_KINDS[0]`` (``"best"``). ``":"`` is not in the UUID/prefix
372
+ #: alphabet, so its presence is an unambiguous suffix signal.
373
+ #: * otherwise split on the LAST ``":"`` (``rpartition``) and reject — never
374
+ #: silently fall back — when EITHER side is empty (``":latest"`` is not a
375
+ #: ref named ``latest``; ``"8b52:"`` is not an implicit ``:best``) or when
376
+ #: ``kind`` is outside :data:`MODEL_KINDS`.
377
+ #:
378
+ #: A value violating this grammar is ``422`` ``seed_artifact_invalid``.
379
+ SEED_JOB_REF_GRAMMAR = "<job-ref>[:best|:latest]"
380
+
381
+ #: Server-pinned max length of either :data:`SEED_SOURCE_FIELDS` value on the
382
+ #: wire (the control plane's Pydantic ``max_length``). A client MUST check
383
+ #: this before packaging: a longer value is otherwise packaged and uploaded
384
+ #: only to be rejected by generic schema validation, whose envelope carries
385
+ #: none of the seed error codes a client maps to friendly copy.
386
+ MAX_SEED_REF_CHARS = 80
387
+
388
+ #: Error code (``POST /v1/jobs``, ``422``) when a request sets BOTH
389
+ #: :data:`SEED_SOURCE_FIELDS` in the same body. Pinned as a constant — unlike
390
+ #: this module's other wire error codes (e.g. ``lease_lost``,
391
+ #: ``log_offset_gap``), which are documented as literal strings only —
392
+ #: because both the control plane raising it and the thin client's seed-source
393
+ #: mutual-exclusion check need to switch on this exact string; a bare literal
394
+ #: risks silent drift between the two.
395
+ SEED_SOURCE_CONFLICT_CODE = "seed_source_conflict"
396
+
301
397
  # --------------------------------------------------------------------------
302
398
  # Worker-facing routes (bearer = static WORKER_TOKEN, constant-time compare;
303
399
  # empty server-side config disables every route below, fail-closed)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo-interfaces
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Type contracts for the Simulo SDK. Installed automatically as a dependency of the simulo package.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause