simulo 0.30.0__tar.gz → 0.31.1__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.
- {simulo-0.30.0/src/simulo.egg-info → simulo-0.31.1}/PKG-INFO +8 -5
- {simulo-0.30.0 → simulo-0.31.1}/PYPI.md +7 -4
- {simulo-0.30.0 → simulo-0.31.1}/pyproject.toml +1 -1
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/cli.py +39 -17
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/templates/__init__.py +3 -2
- simulo-0.31.1/src/simulo/_client/templates/training/preview.py.tmpl +10 -0
- {simulo-0.30.0 → simulo-0.31.1/src/simulo.egg-info}/PKG-INFO +8 -5
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo.egg-info/SOURCES.txt +1 -0
- {simulo-0.30.0 → simulo-0.31.1}/MANIFEST.in +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/setup.cfg +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/__init__.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/__init__.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/_arguments.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/_mounts.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/_runner.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/_secure_downloads.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/app.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/asset.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/asset_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/asset_package.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/asset_pins.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/builtin_aliases.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/bundle.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/cancel_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/config.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/credentials.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/discovery.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/export_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/facades.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/http.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/identity_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/install_samples.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/jobs_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/learning.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/login.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/mode.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/onnx_bundle.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/outputs.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/packaging.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/policies_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/preflight_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/preflight_render.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/preview_report.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/registry.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/runtime.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/runtime_display.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/stub.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/submit_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/templates/training/play.py.tmpl +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/templates/training/simuloignore.tmpl +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/templates/training/task.py.tmpl +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/templates/training/train.py.tmpl +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/view_fragment.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/view_session_api.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/_client/volume.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/callbacks.py +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo/py.typed +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo.egg-info/dependency_links.txt +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo.egg-info/entry_points.txt +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo.egg-info/requires.txt +0 -0
- {simulo-0.30.0 → simulo-0.31.1}/src/simulo.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simulo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.31.1
|
|
4
4
|
Summary: Python SDK and CLI for cloud-native robotics simulation, reinforcement learning, and robot policy training on managed GPUs.
|
|
5
5
|
Author-email: Simulo Team <team@simulo.ai>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -92,14 +92,17 @@ Simulo requires Python 3.11 or newer. One installation provides both the
|
|
|
92
92
|
simulo create mybot
|
|
93
93
|
simulo login
|
|
94
94
|
cd mybot
|
|
95
|
+
simulo run preview.py --frozen --strict-assets
|
|
95
96
|
simulo run train.py --frozen --strict-assets
|
|
97
|
+
simulo run play.py --policy policy_<job>:best --frozen --strict-assets
|
|
96
98
|
```
|
|
97
99
|
|
|
98
100
|
`simulo create` writes a complete starter application to your machine without
|
|
99
|
-
requiring a login or network connection. It creates `task.py`, `
|
|
100
|
-
|
|
101
|
-
asset
|
|
102
|
-
|
|
101
|
+
requiring a login or network connection. It creates `task.py`, `preview.py`,
|
|
102
|
+
`train.py`, `play.py`, and `.simuloignore`. Run `preview.py` first as a separate
|
|
103
|
+
job to check the validated cartpole asset in its task, run `train.py` to train a
|
|
104
|
+
PPO policy, then pass that policy to `play.py`. `simulo run` packages the source,
|
|
105
|
+
resolves and pins its assets, submits the job, and follows its cloud logs.
|
|
103
106
|
|
|
104
107
|
## Explore robotics samples
|
|
105
108
|
|
|
@@ -36,14 +36,17 @@ Simulo requires Python 3.11 or newer. One installation provides both the
|
|
|
36
36
|
simulo create mybot
|
|
37
37
|
simulo login
|
|
38
38
|
cd mybot
|
|
39
|
+
simulo run preview.py --frozen --strict-assets
|
|
39
40
|
simulo run train.py --frozen --strict-assets
|
|
41
|
+
simulo run play.py --policy policy_<job>:best --frozen --strict-assets
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
`simulo create` writes a complete starter application to your machine without
|
|
43
|
-
requiring a login or network connection. It creates `task.py`, `
|
|
44
|
-
|
|
45
|
-
asset
|
|
46
|
-
|
|
45
|
+
requiring a login or network connection. It creates `task.py`, `preview.py`,
|
|
46
|
+
`train.py`, `play.py`, and `.simuloignore`. Run `preview.py` first as a separate
|
|
47
|
+
job to check the validated cartpole asset in its task, run `train.py` to train a
|
|
48
|
+
PPO policy, then pass that policy to `play.py`. `simulo run` packages the source,
|
|
49
|
+
resolves and pins its assets, submits the job, and follows its cloud logs.
|
|
47
50
|
|
|
48
51
|
## Explore robotics samples
|
|
49
52
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simulo"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.31.1"
|
|
8
8
|
description = "Python SDK and CLI for cloud-native robotics simulation, reinforcement learning, and robot policy training on managed GPUs."
|
|
9
9
|
readme = "PYPI.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -27,7 +27,8 @@ default stays out of submitted ``args`` and preserves the no-flags
|
|
|
27
27
|
``package_id``.
|
|
28
28
|
|
|
29
29
|
``simulo create <name> [--dir PATH] [--force]`` scaffolds a training app folder
|
|
30
|
-
(``<name>/task.py``, ``<name>/
|
|
30
|
+
(``<name>/task.py``, ``<name>/preview.py``, ``<name>/train.py``,
|
|
31
|
+
``<name>/play.py``, and ``<name>/.simuloignore``) from a
|
|
31
32
|
starter template bundled INSIDE this wheel as package data (loaded via
|
|
32
33
|
``importlib.resources``, not a path relative to this repo). This is the ONLY
|
|
33
34
|
delivery vehicle for a starter app: the repo's ``demos/`` directory sits outside
|
|
@@ -672,6 +673,14 @@ def _resolve_client_context() -> tuple[str, Optional[str]]:
|
|
|
672
673
|
return base_url, token
|
|
673
674
|
|
|
674
675
|
|
|
676
|
+
def _client_with_fresh_token(client: JobsApiClient) -> JobsApiClient:
|
|
677
|
+
"""Return a client with current stored credentials, preserving its target."""
|
|
678
|
+
creds = credentials.try_get_valid_credentials(base_url=client.base_url)
|
|
679
|
+
if creds is None:
|
|
680
|
+
return client
|
|
681
|
+
return JobsApiClient(client.base_url, token=str(creds["access_token"]))
|
|
682
|
+
|
|
683
|
+
|
|
675
684
|
def _is_uuid_text(value: Any) -> bool:
|
|
676
685
|
try:
|
|
677
686
|
UUID(str(value))
|
|
@@ -1469,10 +1478,16 @@ def _follow_and_report(handle: JobHandle, app_path: str) -> int:
|
|
|
1469
1478
|
job_ref = str(getattr(handle, "public_id", None) or handle.job_id)
|
|
1470
1479
|
exit_code = _drain_logs(client, job_ref, follow=True, scope=JOB_SCOPE_MINE)
|
|
1471
1480
|
if handle.job_type is JobType.PREVIEW:
|
|
1481
|
+
client = _client_with_fresh_token(client)
|
|
1472
1482
|
return _report_preview(client, job_ref, display_id, app_path, fallback_exit_code=exit_code)
|
|
1473
1483
|
if exit_code == 0:
|
|
1474
1484
|
if handle.job_type is JobType.TRAIN:
|
|
1475
|
-
|
|
1485
|
+
client = _client_with_fresh_token(client)
|
|
1486
|
+
_print_training_next_steps(
|
|
1487
|
+
PoliciesApiClient(client.base_url, token=client._token),
|
|
1488
|
+
handle,
|
|
1489
|
+
app_path,
|
|
1490
|
+
)
|
|
1476
1491
|
elif handle.job_type is JobType.PLAY:
|
|
1477
1492
|
print(f"Next: simulo recordings {display_id}")
|
|
1478
1493
|
return exit_code
|
|
@@ -1565,12 +1580,11 @@ def _checkpoint_iteration(handle: JobHandle, checkpoint_ref: str) -> Optional[in
|
|
|
1565
1580
|
return None
|
|
1566
1581
|
|
|
1567
1582
|
|
|
1568
|
-
def _print_training_next_steps(handle: JobHandle, app_path: str) -> None:
|
|
1583
|
+
def _print_training_next_steps(client: PoliciesApiClient, handle: JobHandle, app_path: str) -> None:
|
|
1569
1584
|
"""Print the sealed policy's checkpoints and the three canonical next steps."""
|
|
1570
|
-
assert handle.base_url is not None
|
|
1571
1585
|
policy_id = str(policy_id_for_job(_handle_display_id(handle)))
|
|
1572
1586
|
try:
|
|
1573
|
-
record =
|
|
1587
|
+
record = client.get_policy(policy_id)
|
|
1574
1588
|
except http.HttpError:
|
|
1575
1589
|
return
|
|
1576
1590
|
rendered: list[str] = []
|
|
@@ -2385,6 +2399,7 @@ def _wait_for_job(client: JobsApiClient, job_id: str, *, scope: str = JOB_SCOPE_
|
|
|
2385
2399
|
"""Poll until ``job_id`` exists — lets a user arm the tail BEFORE the job is created."""
|
|
2386
2400
|
waiting_announced = False
|
|
2387
2401
|
while True:
|
|
2402
|
+
client = _client_with_fresh_token(client)
|
|
2388
2403
|
try:
|
|
2389
2404
|
return client.get_job(job_id, scope=scope)
|
|
2390
2405
|
except JobsApiHTTPError as exc:
|
|
@@ -2413,6 +2428,7 @@ def _wait_for_latest_job(client: JobsApiClient) -> dict[str, Any]:
|
|
|
2413
2428
|
"""
|
|
2414
2429
|
waiting_announced = False
|
|
2415
2430
|
while True:
|
|
2431
|
+
client = _client_with_fresh_token(client)
|
|
2416
2432
|
try:
|
|
2417
2433
|
latest = client.get_latest_job()
|
|
2418
2434
|
except JobsApiHTTPError as exc:
|
|
@@ -2607,6 +2623,8 @@ def _drain_logs(
|
|
|
2607
2623
|
post-``simulo run`` default follow — one follow loop, one
|
|
2608
2624
|
exit-code-mirrors-outcome rule.
|
|
2609
2625
|
"""
|
|
2626
|
+
if follow:
|
|
2627
|
+
client = _client_with_fresh_token(client)
|
|
2610
2628
|
offset = 0
|
|
2611
2629
|
if tail_lines is not None:
|
|
2612
2630
|
try:
|
|
@@ -2632,6 +2650,8 @@ def _drain_logs(
|
|
|
2632
2650
|
# Not honored (old server): the loop below simply continues the full
|
|
2633
2651
|
# history from where the server's offset-0 answer left off.
|
|
2634
2652
|
while True:
|
|
2653
|
+
if follow:
|
|
2654
|
+
client = _client_with_fresh_token(client)
|
|
2635
2655
|
try:
|
|
2636
2656
|
chunk, offset, status, _ = client.get_log_chunk(job_id, offset, scope=scope)
|
|
2637
2657
|
except JobsApiHTTPError as exc:
|
|
@@ -2769,9 +2789,9 @@ def _cmd_result(args: argparse.Namespace) -> int:
|
|
|
2769
2789
|
announced on stderr.
|
|
2770
2790
|
A job whose run announced typed outputs gets a second
|
|
2771
2791
|
stderr line, ``⚠ 1 anomaly (non_finite_reward)`` (:func:`_outputs_flag_summary`)
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2792
|
+
while built-in training results omit anomaly-capture paths. Those paths
|
|
2793
|
+
are exposed through the recordings and outputs commands instead. Both
|
|
2794
|
+
lines print to
|
|
2775
2795
|
stderr so stdout stays pure result JSON for pipelines. Best-effort: for
|
|
2776
2796
|
an explicit JOB_ID this needs one extra ``get_job`` call, and a failure
|
|
2777
2797
|
there (e.g. an older control plane) skips both lines rather than failing a
|
|
@@ -5074,11 +5094,9 @@ def _validate_app_name(name: str) -> None:
|
|
|
5074
5094
|
)
|
|
5075
5095
|
|
|
5076
5096
|
|
|
5077
|
-
#: The
|
|
5078
|
-
#: "Next steps"
|
|
5079
|
-
|
|
5080
|
-
#: executes each printed command verbatim against a fresh scaffold.
|
|
5081
|
-
_TEMPLATE_NEXT_RUN_COMMAND = "simulo run train.py"
|
|
5097
|
+
#: The ``simulo run`` commands a fresh scaffold user should type before policy
|
|
5098
|
+
#: playback, in order, printed as the "Next steps" lines by ``_cmd_create``.
|
|
5099
|
+
_TEMPLATE_NEXT_RUN_COMMANDS = ("simulo run preview.py", "simulo run train.py")
|
|
5082
5100
|
|
|
5083
5101
|
|
|
5084
5102
|
def _cmd_create(args: argparse.Namespace) -> int:
|
|
@@ -5091,7 +5109,7 @@ def _cmd_create(args: argparse.Namespace) -> int:
|
|
|
5091
5109
|
``{{APP_NAME}}`` token. No network call, no auth.
|
|
5092
5110
|
|
|
5093
5111
|
A pre-existing, non-empty target folder is refused unless ``--force`` (which
|
|
5094
|
-
prints the
|
|
5112
|
+
prints the filenames it overwrote — a destructive action stays visible in
|
|
5095
5113
|
the output); an existing EMPTY folder (or no folder at all) needs no
|
|
5096
5114
|
``--force``. Every filesystem failure writing the scaffold — including a bad
|
|
5097
5115
|
``--dir`` that names an existing FILE rather than a directory (``mkdir``
|
|
@@ -5153,7 +5171,8 @@ def _cmd_create(args: argparse.Namespace) -> int:
|
|
|
5153
5171
|
print(f"{verb} app in {target_dir}/ ({written}).")
|
|
5154
5172
|
print("Next steps:")
|
|
5155
5173
|
print(f" cd {target_dir}")
|
|
5156
|
-
|
|
5174
|
+
for command in _TEMPLATE_NEXT_RUN_COMMANDS:
|
|
5175
|
+
print(f" {command}")
|
|
5157
5176
|
print(" simulo run play.py --policy policy_<job>:best # after training")
|
|
5158
5177
|
return 0
|
|
5159
5178
|
|
|
@@ -8145,10 +8164,13 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
8145
8164
|
|
|
8146
8165
|
create = sub.add_parser(
|
|
8147
8166
|
"create",
|
|
8148
|
-
description=
|
|
8167
|
+
description=(
|
|
8168
|
+
"Scaffold task.py, preview.py, train.py, play.py, and .simuloignore "
|
|
8169
|
+
"without network access or authentication."
|
|
8170
|
+
),
|
|
8149
8171
|
help=(
|
|
8150
8172
|
"Scaffold a new Simulo app folder from a starter template shipped inside this wheel "
|
|
8151
|
-
"(writes task.py, train.py, play.py, and .simuloignore; no network, no auth)."
|
|
8173
|
+
"(writes task.py, preview.py, train.py, play.py, and .simuloignore; no network, no auth)."
|
|
8152
8174
|
),
|
|
8153
8175
|
)
|
|
8154
8176
|
create.add_argument(
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The repo's ``demos/`` tree lives outside the packaged ``src/`` layout and never
|
|
4
4
|
reaches a real ``pip install simulo`` user — this package is the fix. The
|
|
5
|
-
``training/`` directory holds the
|
|
6
|
-
``task.py.tmpl``, ``train.py.tmpl``,
|
|
5
|
+
``training/`` directory holds the five files created by ``simulo create``:
|
|
6
|
+
``task.py.tmpl``, ``preview.py.tmpl``, ``train.py.tmpl``, ``play.py.tmpl``,
|
|
7
|
+
and ``simuloignore.tmpl``.
|
|
7
8
|
|
|
8
9
|
The ``.tmpl`` suffix is load-bearing, not cosmetic: these files contain
|
|
9
10
|
``import torch`` and other content that is not a valid, importable module on
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Check the robot inside the task before training; this preview makes no policy."""
|
|
2
|
+
|
|
3
|
+
import simulo
|
|
4
|
+
|
|
5
|
+
from task import StarterTask, app
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@app.job(type="preview", system=simulo.SystemType.TIER_1, timeout=15 * 60)
|
|
9
|
+
def preview(num_envs: int = 16, checks: str = "all"):
|
|
10
|
+
return simulo.preview(StarterTask(), num_envs=num_envs, checks=checks, video=True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simulo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.31.1
|
|
4
4
|
Summary: Python SDK and CLI for cloud-native robotics simulation, reinforcement learning, and robot policy training on managed GPUs.
|
|
5
5
|
Author-email: Simulo Team <team@simulo.ai>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -92,14 +92,17 @@ Simulo requires Python 3.11 or newer. One installation provides both the
|
|
|
92
92
|
simulo create mybot
|
|
93
93
|
simulo login
|
|
94
94
|
cd mybot
|
|
95
|
+
simulo run preview.py --frozen --strict-assets
|
|
95
96
|
simulo run train.py --frozen --strict-assets
|
|
97
|
+
simulo run play.py --policy policy_<job>:best --frozen --strict-assets
|
|
96
98
|
```
|
|
97
99
|
|
|
98
100
|
`simulo create` writes a complete starter application to your machine without
|
|
99
|
-
requiring a login or network connection. It creates `task.py`, `
|
|
100
|
-
|
|
101
|
-
asset
|
|
102
|
-
|
|
101
|
+
requiring a login or network connection. It creates `task.py`, `preview.py`,
|
|
102
|
+
`train.py`, `play.py`, and `.simuloignore`. Run `preview.py` first as a separate
|
|
103
|
+
job to check the validated cartpole asset in its task, run `train.py` to train a
|
|
104
|
+
PPO policy, then pass that policy to `play.py`. `simulo run` packages the source,
|
|
105
|
+
resolves and pins its assets, submits the job, and follows its cloud logs.
|
|
103
106
|
|
|
104
107
|
## Explore robotics samples
|
|
105
108
|
|
|
@@ -53,6 +53,7 @@ src/simulo/_client/view_session_api.py
|
|
|
53
53
|
src/simulo/_client/volume.py
|
|
54
54
|
src/simulo/_client/templates/__init__.py
|
|
55
55
|
src/simulo/_client/templates/training/play.py.tmpl
|
|
56
|
+
src/simulo/_client/templates/training/preview.py.tmpl
|
|
56
57
|
src/simulo/_client/templates/training/simuloignore.tmpl
|
|
57
58
|
src/simulo/_client/templates/training/task.py.tmpl
|
|
58
59
|
src/simulo/_client/templates/training/train.py.tmpl
|
|
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
|
|
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
|