plato-sdk-v2 2.3.6__py3-none-any.whl → 2.3.8__py3-none-any.whl
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.
- plato/agents/otel.py +77 -87
- plato/agents/runner.py +125 -288
- plato/v1/cli/sandbox.py +5 -2
- plato/v1/cli/ssh.py +21 -14
- plato/v1/cli/utils.py +32 -12
- plato/worlds/base.py +103 -92
- plato/worlds/runner.py +33 -15
- {plato_sdk_v2-2.3.6.dist-info → plato_sdk_v2-2.3.8.dist-info}/METADATA +1 -2
- {plato_sdk_v2-2.3.6.dist-info → plato_sdk_v2-2.3.8.dist-info}/RECORD +11 -11
- {plato_sdk_v2-2.3.6.dist-info → plato_sdk_v2-2.3.8.dist-info}/WHEEL +0 -0
- {plato_sdk_v2-2.3.6.dist-info → plato_sdk_v2-2.3.8.dist-info}/entry_points.txt +0 -0
plato/worlds/base.py
CHANGED
|
@@ -28,6 +28,17 @@ from plato.agents.otel import (
|
|
|
28
28
|
|
|
29
29
|
logger = logging.getLogger(__name__)
|
|
30
30
|
|
|
31
|
+
|
|
32
|
+
def _get_plato_version() -> str:
|
|
33
|
+
"""Get the installed plato SDK version."""
|
|
34
|
+
try:
|
|
35
|
+
from importlib.metadata import version
|
|
36
|
+
|
|
37
|
+
return version("plato")
|
|
38
|
+
except Exception:
|
|
39
|
+
return "unknown"
|
|
40
|
+
|
|
41
|
+
|
|
31
42
|
# Global registry of worlds
|
|
32
43
|
_WORLD_REGISTRY: dict[str, type[BaseWorld]] = {}
|
|
33
44
|
|
|
@@ -417,7 +428,7 @@ class BaseWorld(ABC, Generic[ConfigT]):
|
|
|
417
428
|
content_type=content_type,
|
|
418
429
|
)
|
|
419
430
|
|
|
420
|
-
async def _create_and_upload_checkpoint(self) -> dict[str, str]
|
|
431
|
+
async def _create_and_upload_checkpoint(self) -> tuple[dict[str, str], bool]:
|
|
421
432
|
"""Create a full checkpoint including env snapshots and state bundle.
|
|
422
433
|
|
|
423
434
|
This method:
|
|
@@ -426,7 +437,7 @@ class BaseWorld(ABC, Generic[ConfigT]):
|
|
|
426
437
|
3. Creates and uploads state bundle to S3
|
|
427
438
|
|
|
428
439
|
Returns:
|
|
429
|
-
|
|
440
|
+
Tuple of (env_snapshots dict, state_bundle_uploaded bool)
|
|
430
441
|
"""
|
|
431
442
|
# Commit state changes first
|
|
432
443
|
self._commit_state(f"Checkpoint at step {self._step_count}")
|
|
@@ -436,6 +447,8 @@ class BaseWorld(ABC, Generic[ConfigT]):
|
|
|
436
447
|
if env_snapshots is None:
|
|
437
448
|
env_snapshots = {}
|
|
438
449
|
|
|
450
|
+
state_bundle_uploaded = True # Default to True if state not enabled
|
|
451
|
+
|
|
439
452
|
# Create and upload state bundle
|
|
440
453
|
if self.config.state.enabled:
|
|
441
454
|
bundle_data = self._create_state_bundle()
|
|
@@ -446,11 +459,12 @@ class BaseWorld(ABC, Generic[ConfigT]):
|
|
|
446
459
|
)
|
|
447
460
|
if success:
|
|
448
461
|
self.logger.info(f"Uploaded state bundle at step {self._step_count}")
|
|
462
|
+
state_bundle_uploaded = True
|
|
449
463
|
else:
|
|
450
464
|
self.logger.warning(f"Failed to upload state bundle at step {self._step_count}")
|
|
451
|
-
|
|
465
|
+
state_bundle_uploaded = False
|
|
452
466
|
|
|
453
|
-
return env_snapshots
|
|
467
|
+
return env_snapshots, state_bundle_uploaded
|
|
454
468
|
|
|
455
469
|
def get_env(self, alias: str) -> Environment | None:
|
|
456
470
|
"""Get an environment by alias.
|
|
@@ -645,25 +659,35 @@ The following services are available for your use:
|
|
|
645
659
|
if config.session_id:
|
|
646
660
|
self._session_id = config.session_id
|
|
647
661
|
|
|
648
|
-
# Set environment variables for agent runners
|
|
662
|
+
# Set environment variables for agent runners (which run in Docker)
|
|
649
663
|
os.environ["SESSION_ID"] = config.session_id
|
|
650
664
|
if config.otel_url:
|
|
651
|
-
|
|
652
|
-
#
|
|
653
|
-
|
|
665
|
+
# For agents in Docker, convert localhost to host.docker.internal
|
|
666
|
+
# so they can reach the host machine's Chronos instance
|
|
667
|
+
agent_otel_url = config.otel_url
|
|
668
|
+
if "localhost" in agent_otel_url or "127.0.0.1" in agent_otel_url:
|
|
669
|
+
agent_otel_url = agent_otel_url.replace("localhost", "host.docker.internal")
|
|
670
|
+
agent_otel_url = agent_otel_url.replace("127.0.0.1", "host.docker.internal")
|
|
671
|
+
os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = agent_otel_url
|
|
672
|
+
os.environ["OTEL_EXPORTER_OTLP_PROTOCOL"] = "http/protobuf"
|
|
654
673
|
if config.upload_url:
|
|
655
674
|
os.environ["UPLOAD_URL"] = config.upload_url
|
|
656
675
|
|
|
657
|
-
# Initialize OTel tracing
|
|
658
|
-
print(f"[World] OTel URL from config: {config.otel_url!r}")
|
|
676
|
+
# Initialize OTel tracing for the world itself (runs on host, not in Docker)
|
|
659
677
|
if config.otel_url:
|
|
678
|
+
logger.debug(f"Initializing OTel tracing with endpoint: {config.otel_url}")
|
|
660
679
|
init_tracing(
|
|
661
680
|
service_name=f"world-{self.name}",
|
|
662
681
|
session_id=config.session_id,
|
|
663
682
|
otlp_endpoint=config.otel_url,
|
|
664
683
|
)
|
|
665
684
|
else:
|
|
666
|
-
|
|
685
|
+
logger.debug("No otel_url in config - OTel tracing disabled")
|
|
686
|
+
|
|
687
|
+
# Log version info (goes to OTel after init_tracing)
|
|
688
|
+
plato_version = _get_plato_version()
|
|
689
|
+
world_version = self.get_version()
|
|
690
|
+
self.logger.info(f"World version: {world_version}, Plato SDK version: {plato_version}")
|
|
667
691
|
|
|
668
692
|
# Connect to Plato session if configured (for heartbeats)
|
|
669
693
|
await self._connect_plato_session()
|
|
@@ -671,85 +695,72 @@ The following services are available for your use:
|
|
|
671
695
|
# Get tracer for spans
|
|
672
696
|
tracer = get_tracer("plato.world")
|
|
673
697
|
|
|
674
|
-
#
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
span.set_attribute("content", f"World '{self.name}' started")
|
|
698
|
+
# Create root session span that encompasses everything
|
|
699
|
+
# This ensures all child spans share the same trace_id
|
|
700
|
+
with tracer.start_as_current_span("session") as session_span:
|
|
701
|
+
session_span.set_attribute("plato.world.name", self.name)
|
|
702
|
+
session_span.set_attribute("plato.world.version", self.get_version())
|
|
703
|
+
session_span.set_attribute("plato.session.id", config.session_id)
|
|
681
704
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
# Log session end
|
|
745
|
-
with tracer.start_as_current_span("session_end") as span:
|
|
746
|
-
span.set_attribute("span.type", "session_end")
|
|
747
|
-
span.set_attribute("source", "world")
|
|
748
|
-
span.set_attribute("total_steps", self._step_count)
|
|
749
|
-
span.set_attribute("content", f"World '{self.name}' completed after {self._step_count} steps")
|
|
750
|
-
|
|
751
|
-
# Shutdown OTel tracing and clear session info
|
|
752
|
-
shutdown_tracing()
|
|
753
|
-
self._session_id = None
|
|
754
|
-
|
|
755
|
-
self.logger.info(f"World '{self.name}' completed after {self._step_count} steps")
|
|
705
|
+
try:
|
|
706
|
+
# Execute reset with OTel span
|
|
707
|
+
with tracer.start_as_current_span("reset") as reset_span:
|
|
708
|
+
obs = await self.reset()
|
|
709
|
+
obs_data = obs.model_dump() if hasattr(obs, "model_dump") else str(obs)
|
|
710
|
+
reset_span.set_attribute("plato.observation", str(obs_data)[:1000])
|
|
711
|
+
self.logger.info(f"World reset complete: {obs}")
|
|
712
|
+
|
|
713
|
+
while True:
|
|
714
|
+
self._step_count += 1
|
|
715
|
+
|
|
716
|
+
# Execute step with OTel span
|
|
717
|
+
with tracer.start_as_current_span(f"step_{self._step_count}") as step_span:
|
|
718
|
+
step_span.set_attribute("plato.step.number", self._step_count)
|
|
719
|
+
|
|
720
|
+
# Store span context for nested agent spans
|
|
721
|
+
self._current_step_id = format(step_span.get_span_context().span_id, "016x")
|
|
722
|
+
|
|
723
|
+
result = await self.step()
|
|
724
|
+
|
|
725
|
+
step_span.set_attribute("plato.step.done", result.done)
|
|
726
|
+
obs_data = (
|
|
727
|
+
result.observation.model_dump()
|
|
728
|
+
if hasattr(result.observation, "model_dump")
|
|
729
|
+
else str(result.observation)
|
|
730
|
+
)
|
|
731
|
+
step_span.set_attribute("plato.step.observation", str(obs_data)[:1000])
|
|
732
|
+
|
|
733
|
+
self.logger.info(f"Step {self._step_count}: done={result.done}")
|
|
734
|
+
|
|
735
|
+
# Create checkpoint if enabled and interval matches
|
|
736
|
+
if self.config.checkpoint.enabled and self._step_count % self.config.checkpoint.interval == 0:
|
|
737
|
+
self.logger.info(f"Creating checkpoint after step {self._step_count}")
|
|
738
|
+
with tracer.start_as_current_span("checkpoint") as checkpoint_span:
|
|
739
|
+
checkpoint_span.set_attribute("plato.checkpoint.step", self._step_count)
|
|
740
|
+
env_snapshots, state_bundle_uploaded = await self._create_and_upload_checkpoint()
|
|
741
|
+
|
|
742
|
+
checkpoint_span.set_attribute("plato.checkpoint.success", len(env_snapshots) > 0)
|
|
743
|
+
checkpoint_span.set_attribute(
|
|
744
|
+
"plato.checkpoint.state_bundle_uploaded", state_bundle_uploaded
|
|
745
|
+
)
|
|
746
|
+
|
|
747
|
+
if env_snapshots:
|
|
748
|
+
checkpoint_span.set_attribute(
|
|
749
|
+
"plato.checkpoint.environments", list(env_snapshots.keys())
|
|
750
|
+
)
|
|
751
|
+
checkpoint_span.set_attribute(
|
|
752
|
+
"plato.checkpoint.artifact_ids", list(env_snapshots.values())
|
|
753
|
+
)
|
|
754
|
+
|
|
755
|
+
if result.done:
|
|
756
|
+
break
|
|
757
|
+
|
|
758
|
+
finally:
|
|
759
|
+
await self.close()
|
|
760
|
+
await self._disconnect_plato_session()
|
|
761
|
+
|
|
762
|
+
# Shutdown OTel tracing and clear session info (outside the span)
|
|
763
|
+
shutdown_tracing()
|
|
764
|
+
self._session_id = None
|
|
765
|
+
|
|
766
|
+
self.logger.info(f"World '{self.name}' completed after {self._step_count} steps")
|
plato/worlds/runner.py
CHANGED
|
@@ -6,7 +6,6 @@ import asyncio
|
|
|
6
6
|
import json
|
|
7
7
|
import logging
|
|
8
8
|
import os
|
|
9
|
-
import platform
|
|
10
9
|
from pathlib import Path
|
|
11
10
|
from typing import Annotated
|
|
12
11
|
|
|
@@ -136,6 +135,28 @@ def list_worlds(
|
|
|
136
135
|
typer.echo(f" {name} (v{version}): {desc}")
|
|
137
136
|
|
|
138
137
|
|
|
138
|
+
def _get_docker_platform() -> str:
|
|
139
|
+
"""Get the appropriate Docker platform for the current system.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Docker platform string (e.g., "linux/arm64" or "linux/amd64")
|
|
143
|
+
"""
|
|
144
|
+
import platform as plat
|
|
145
|
+
|
|
146
|
+
system = plat.system()
|
|
147
|
+
machine = plat.machine().lower()
|
|
148
|
+
|
|
149
|
+
# On macOS with Apple Silicon (arm64/aarch64), use linux/arm64
|
|
150
|
+
if system == "Darwin" and machine in ("arm64", "aarch64"):
|
|
151
|
+
return "linux/arm64"
|
|
152
|
+
# On Linux ARM
|
|
153
|
+
elif system == "Linux" and machine in ("arm64", "aarch64"):
|
|
154
|
+
return "linux/arm64"
|
|
155
|
+
# Default to amd64 for x86_64 or other architectures
|
|
156
|
+
else:
|
|
157
|
+
return "linux/amd64"
|
|
158
|
+
|
|
159
|
+
|
|
139
160
|
async def _build_agent_image(
|
|
140
161
|
agent_name: str,
|
|
141
162
|
agents_dir: Path,
|
|
@@ -181,9 +202,17 @@ async def _build_agent_image(
|
|
|
181
202
|
target = "prod"
|
|
182
203
|
logger.info(f"Building {image_tag} (prod mode from {build_context})...")
|
|
183
204
|
|
|
205
|
+
# Detect platform for ARM Mac support
|
|
206
|
+
docker_platform = _get_docker_platform()
|
|
207
|
+
logger.info(f"Building for platform: {docker_platform}")
|
|
208
|
+
|
|
184
209
|
cmd = [
|
|
185
210
|
"docker",
|
|
186
211
|
"build",
|
|
212
|
+
"--platform",
|
|
213
|
+
docker_platform,
|
|
214
|
+
"--build-arg",
|
|
215
|
+
f"PLATFORM={docker_platform}",
|
|
187
216
|
"--target",
|
|
188
217
|
target,
|
|
189
218
|
"-t",
|
|
@@ -192,10 +221,6 @@ async def _build_agent_image(
|
|
|
192
221
|
dockerfile_abs,
|
|
193
222
|
]
|
|
194
223
|
|
|
195
|
-
# Use native platform for local dev on ARM Macs (avoids slow emulation)
|
|
196
|
-
if platform.machine() == "arm64":
|
|
197
|
-
cmd.extend(["--build-arg", "PLATFORM=linux/arm64"])
|
|
198
|
-
|
|
199
224
|
cmd.append(build_context)
|
|
200
225
|
|
|
201
226
|
logger.debug(f"Build command: {' '.join(cmd)}")
|
|
@@ -405,6 +430,7 @@ async def _run_dev(
|
|
|
405
430
|
plato = AsyncPlato()
|
|
406
431
|
session = None
|
|
407
432
|
plato_session_id: str | None = None
|
|
433
|
+
chronos_session_id: str | None = None
|
|
408
434
|
|
|
409
435
|
try:
|
|
410
436
|
if env_configs:
|
|
@@ -435,18 +461,10 @@ async def _run_dev(
|
|
|
435
461
|
|
|
436
462
|
# Update run_config with session info from Chronos
|
|
437
463
|
run_config.session_id = chronos_session_id
|
|
438
|
-
|
|
464
|
+
# Use base chronos URL for OTEL endpoint (more reliable than session-provided URL)
|
|
465
|
+
run_config.otel_url = f"{chronos_url.rstrip('/')}/api/otel"
|
|
439
466
|
run_config.upload_url = chronos_session.upload_url
|
|
440
467
|
|
|
441
|
-
# For local dev, override otel_url to use localhost directly
|
|
442
|
-
# (Chronos may return a tunnel URL that's meant for remote VMs)
|
|
443
|
-
if "localhost" in chronos_url or "127.0.0.1" in chronos_url:
|
|
444
|
-
run_config.otel_url = f"{chronos_url.rstrip('/')}/api/otel"
|
|
445
|
-
logger.info(f"Local dev: using OTel URL {run_config.otel_url}")
|
|
446
|
-
|
|
447
|
-
print(f"[Runner] run_config.otel_url = {run_config.otel_url!r}")
|
|
448
|
-
print(f"[Runner] run_config.upload_url = {run_config.upload_url!r}")
|
|
449
|
-
|
|
450
468
|
# Run the world
|
|
451
469
|
logger.info(f"Starting world '{world_name}'...")
|
|
452
470
|
world_instance = world_cls()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plato-sdk-v2
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.8
|
|
4
4
|
Summary: Python SDK for the Plato API
|
|
5
5
|
Author-email: Plato <support@plato.so>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -47,7 +47,6 @@ Description-Content-Type: text/markdown
|
|
|
47
47
|
|
|
48
48
|
# Plato Python SDK
|
|
49
49
|
|
|
50
|
-
|
|
51
50
|
Python SDK for the Plato platform. Uses [Harbor](https://harborframework.com) for agent execution.
|
|
52
51
|
|
|
53
52
|
## Installation
|
|
@@ -302,8 +302,8 @@ plato/agents/artifacts.py,sha256=ljeI0wzsp7Q6uKqMb-k7kTb680Vizs54ohtM-d7zvOg,292
|
|
|
302
302
|
plato/agents/base.py,sha256=vUbPQuNSo6Ka2lIB_ZOXgi4EoAjtAD7GIj9LnNotam0,4577
|
|
303
303
|
plato/agents/build.py,sha256=CNMbVQFs2_pYit1dA29Davve28Yi4c7TNK9wBB7odrE,1621
|
|
304
304
|
plato/agents/config.py,sha256=CmRS6vOAg7JeqX4Hgp_KpA1YWBX_LuMicHm7SBjQEbs,5077
|
|
305
|
-
plato/agents/otel.py,sha256=
|
|
306
|
-
plato/agents/runner.py,sha256=
|
|
305
|
+
plato/agents/otel.py,sha256=UOEBeMyyfbffsC3tRXlHAydoj9bXwJupA_UeLZ5h97w,8585
|
|
306
|
+
plato/agents/runner.py,sha256=Ei20Ib-Fn5XOaS6V1Rtw0UEw34XflEWaXMpazPjmnrE,6061
|
|
307
307
|
plato/agents/trajectory.py,sha256=WdiBmua0KvCrNaM3qgPI7-7B4xmSkfbP4oZ_9_8qHzU,10529
|
|
308
308
|
plato/chronos/__init__.py,sha256=RHMvSrQS_-vkKOyTRuAkp2gKDP1HEuBLDnw8jcZs1Jg,739
|
|
309
309
|
plato/chronos/client.py,sha256=YcOGtHWERyOD9z8LKt8bRMVL0cEwL2hiAP4qQgdZlUI,5495
|
|
@@ -389,9 +389,9 @@ plato/v1/cli/__init__.py,sha256=om4b7PxgsoI7rEwuQelmQkqPdhMVn53_5qEN8kvksYw,105
|
|
|
389
389
|
plato/v1/cli/agent.py,sha256=G6TV3blG_BqMDBWS-CG7GwzqoqcJTMsIKQ88jvLXb4k,43745
|
|
390
390
|
plato/v1/cli/main.py,sha256=ktPtBvMwykR7AjXmTQ6bmZkHdzpAjhX5Fq66cDbGSzA,6844
|
|
391
391
|
plato/v1/cli/pm.py,sha256=uLM6WszKqxq9Czg1FraDyWb9_INUuHZq63imvRYfRLw,49734
|
|
392
|
-
plato/v1/cli/sandbox.py,sha256=
|
|
393
|
-
plato/v1/cli/ssh.py,sha256=
|
|
394
|
-
plato/v1/cli/utils.py,sha256=
|
|
392
|
+
plato/v1/cli/sandbox.py,sha256=N7DIpXsxExtZB47tWKxp-3cV0_gLnI7C-mTKW3tTi8Y,95360
|
|
393
|
+
plato/v1/cli/ssh.py,sha256=enrf7Y01ZeRIyHDEX0Yt7up5zEe7MCvE9u8SP4Oqiz4,6926
|
|
394
|
+
plato/v1/cli/utils.py,sha256=ba7Crv4OjDmgCv4SeB8UeZDin-iOdQw_3N6fd-g5XVk,4572
|
|
395
395
|
plato/v1/cli/verify.py,sha256=7QmQwfOOkr8a51f8xfVIr2zif7wGl2E8HOZTbOaIoV0,20671
|
|
396
396
|
plato/v1/cli/world.py,sha256=yBUadOJs1QYm6Jmx_ACDzogybRq5x4B-BnTvGO_ulQk,9757
|
|
397
397
|
plato/v1/examples/doordash_tasks.py,sha256=8Sz9qx-vTmiOAiCAbrDRvZGsA1qQQBr1KHbxXdjr7OI,23233
|
|
@@ -458,11 +458,11 @@ plato/v2/utils/models.py,sha256=PwehSSnIRG-tM3tWL1PzZEH77ZHhIAZ9R0UPs6YknbM,1441
|
|
|
458
458
|
plato/v2/utils/proxy_tunnel.py,sha256=8ZTd0jCGSfIHMvSv1fgEyacuISWnGPHLPbDglWroTzY,10463
|
|
459
459
|
plato/worlds/README.md,sha256=XFOkEA3cNNcrWkk-Cxnsl-zn-y0kvUENKQRSqFKpdqw,5479
|
|
460
460
|
plato/worlds/__init__.py,sha256=ALoou3l5lXvs_YZc5eH6HdMHpvhnpzKWqz__aSC1jFc,2152
|
|
461
|
-
plato/worlds/base.py,sha256=
|
|
461
|
+
plato/worlds/base.py,sha256=kIX02gMQR43ZsZK25vZvCoNkYtICVRMeofNk-im5IRM,28215
|
|
462
462
|
plato/worlds/build_hook.py,sha256=KSoW0kqa5b7NyZ7MYOw2qsZ_2FkWuz0M3Ru7AKOP7Qw,3486
|
|
463
463
|
plato/worlds/config.py,sha256=a5frj3mt06rSlT25kE-L8Q2b2MTWkR-8cUoBKpC8tG4,11036
|
|
464
|
-
plato/worlds/runner.py,sha256=
|
|
465
|
-
plato_sdk_v2-2.3.
|
|
466
|
-
plato_sdk_v2-2.3.
|
|
467
|
-
plato_sdk_v2-2.3.
|
|
468
|
-
plato_sdk_v2-2.3.
|
|
464
|
+
plato/worlds/runner.py,sha256=2H5EV77bTYrMyI7qez0kwxOp9EApQxG19Ob9a_GTdbw,19383
|
|
465
|
+
plato_sdk_v2-2.3.8.dist-info/METADATA,sha256=GnoZAAlPmFfWxSwHFjkab7s6MmWfk8rXOvOynTb2r28,8652
|
|
466
|
+
plato_sdk_v2-2.3.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
467
|
+
plato_sdk_v2-2.3.8.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
|
|
468
|
+
plato_sdk_v2-2.3.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|