plato-sdk-v2 2.1.16__py3-none-any.whl → 2.2.1__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/worlds/config.py CHANGED
@@ -7,8 +7,16 @@ from typing import Any
7
7
 
8
8
  from pydantic import BaseModel, Field
9
9
 
10
+ from plato._generated.models import (
11
+ EnvFromArtifact,
12
+ EnvFromResource,
13
+ EnvFromSimulator,
14
+ )
10
15
  from plato.v2.async_.session import SerializedSession
11
16
 
17
+ # Union type for environment configurations
18
+ EnvConfig = EnvFromArtifact | EnvFromSimulator | EnvFromResource
19
+
12
20
 
13
21
  class AgentConfig(BaseModel):
14
22
  """Configuration for an agent.
@@ -46,10 +54,28 @@ class Secret:
46
54
  self.required = required
47
55
 
48
56
 
57
+ class Env:
58
+ """Annotation marker for environment fields.
59
+
60
+ Environments are VMs that run alongside the world's runtime.
61
+ They can be specified by artifact ID, simulator name, or resource config.
62
+
63
+ Usage:
64
+ gitea: Annotated[EnvConfig, Env(description="Git server")] = EnvFromArtifact(
65
+ artifact_id="abc123",
66
+ alias="gitea",
67
+ )
68
+ """
69
+
70
+ def __init__(self, description: str = "", required: bool = True):
71
+ self.description = description
72
+ self.required = required
73
+
74
+
49
75
  class RunConfig(BaseModel):
50
76
  """Base configuration for running a world.
51
77
 
52
- Subclass this with your world-specific fields, agents, and secrets:
78
+ Subclass this with your world-specific fields, agents, secrets, and envs:
53
79
 
54
80
  class CodeWorldConfig(RunConfig):
55
81
  # World-specific fields
@@ -62,6 +88,12 @@ class RunConfig(BaseModel):
62
88
  # Secrets (typed)
63
89
  git_token: Annotated[str | None, Secret(description="GitHub token")] = None
64
90
 
91
+ # Environments (typed)
92
+ gitea: Annotated[EnvConfig, Env(description="Git server")] = EnvFromArtifact(
93
+ artifact_id="abc123",
94
+ alias="gitea",
95
+ )
96
+
65
97
  Attributes:
66
98
  session_id: Unique Chronos session identifier
67
99
  callback_url: Callback URL for status updates
@@ -79,16 +111,16 @@ class RunConfig(BaseModel):
79
111
  model_config = {"extra": "allow"}
80
112
 
81
113
  @classmethod
82
- def get_field_annotations(cls) -> dict[str, Agent | Secret | None]:
83
- """Get Agent/Secret annotations for each field."""
84
- result: dict[str, Agent | Secret | None] = {}
114
+ def get_field_annotations(cls) -> dict[str, Agent | Secret | Env | None]:
115
+ """Get Agent/Secret/Env annotations for each field."""
116
+ result: dict[str, Agent | Secret | Env | None] = {}
85
117
 
86
118
  for field_name, field_info in cls.model_fields.items():
87
119
  marker = None
88
120
 
89
121
  # Pydantic stores Annotated metadata in field_info.metadata
90
122
  for meta in field_info.metadata:
91
- if isinstance(meta, (Agent, Secret)):
123
+ if isinstance(meta, (Agent, Secret, Env)):
92
124
  marker = meta
93
125
  break
94
126
 
@@ -98,7 +130,7 @@ class RunConfig(BaseModel):
98
130
 
99
131
  @classmethod
100
132
  def get_json_schema(cls) -> dict:
101
- """Get JSON schema with agents and secrets separated."""
133
+ """Get JSON schema with agents, secrets, and envs separated."""
102
134
  # Get full Pydantic schema
103
135
  full_schema = cls.model_json_schema()
104
136
  full_schema.pop("title", None)
@@ -110,6 +142,7 @@ class RunConfig(BaseModel):
110
142
  world_properties = {}
111
143
  agents = []
112
144
  secrets = []
145
+ envs = []
113
146
 
114
147
  # Skip runtime fields
115
148
  runtime_fields = {"session_id", "callback_url", "all_secrets", "plato_session"}
@@ -136,6 +169,26 @@ class RunConfig(BaseModel):
136
169
  "required": marker.required,
137
170
  }
138
171
  )
172
+ elif isinstance(marker, Env):
173
+ # Get default value for this env field
174
+ field_info = cls.model_fields.get(field_name)
175
+ default_value = None
176
+ if field_info and field_info.default is not None:
177
+ # Serialize the default EnvConfig to dict
178
+ default_env = field_info.default
179
+ if hasattr(default_env, "model_dump"):
180
+ default_value = default_env.model_dump()
181
+ elif isinstance(default_env, dict):
182
+ default_value = default_env
183
+
184
+ envs.append(
185
+ {
186
+ "name": field_name,
187
+ "description": marker.description,
188
+ "required": marker.required,
189
+ "default": default_value,
190
+ }
191
+ )
139
192
  else:
140
193
  world_properties[field_name] = prop_schema
141
194
 
@@ -149,8 +202,26 @@ class RunConfig(BaseModel):
149
202
  "required": required,
150
203
  "agents": agents,
151
204
  "secrets": secrets,
205
+ "envs": envs,
152
206
  }
153
207
 
208
+ def get_envs(self) -> list[EnvConfig]:
209
+ """Get all environment configurations from this config.
210
+
211
+ Returns:
212
+ List of EnvConfig objects (EnvFromArtifact, EnvFromSimulator, or EnvFromResource)
213
+ """
214
+ annotations = self.get_field_annotations()
215
+ envs: list[EnvConfig] = []
216
+
217
+ for field_name, marker in annotations.items():
218
+ if isinstance(marker, Env):
219
+ value = getattr(self, field_name, None)
220
+ if value is not None:
221
+ envs.append(value)
222
+
223
+ return envs
224
+
154
225
  @classmethod
155
226
  def from_file(cls, path: str | Path) -> RunConfig:
156
227
  """Load config from a JSON file."""
@@ -177,6 +248,9 @@ class RunConfig(BaseModel):
177
248
  # Handle secrets dict -> individual secret fields
178
249
  secrets_dict = data.pop("secrets", {})
179
250
 
251
+ # Handle envs dict -> individual env fields
252
+ envs_dict = data.pop("envs", {})
253
+
180
254
  # Merge world_config into top-level
181
255
  parsed.update(world_config)
182
256
  parsed.update(data)
@@ -191,8 +265,24 @@ class RunConfig(BaseModel):
191
265
  parsed[field_name] = AgentConfig(image=str(agent_data))
192
266
  elif isinstance(marker, Secret) and field_name in secrets_dict:
193
267
  parsed[field_name] = secrets_dict[field_name]
268
+ elif isinstance(marker, Env) and field_name in envs_dict:
269
+ env_data = envs_dict[field_name]
270
+ if isinstance(env_data, dict):
271
+ parsed[field_name] = _parse_env_config(env_data)
272
+ else:
273
+ parsed[field_name] = env_data
194
274
 
195
275
  # Store all secrets for agent use
196
276
  parsed["all_secrets"] = secrets_dict
197
277
 
198
278
  return cls(**parsed)
279
+
280
+
281
+ def _parse_env_config(data: dict) -> EnvConfig:
282
+ """Parse an env config dict into the appropriate type."""
283
+ if "artifact_id" in data:
284
+ return EnvFromArtifact(**data)
285
+ elif "sim_config" in data:
286
+ return EnvFromResource(**data)
287
+ else:
288
+ return EnvFromSimulator(**data)
plato/worlds/runner.py CHANGED
@@ -3,13 +3,15 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
+ import json
6
7
  import logging
8
+ import os
7
9
  from pathlib import Path
8
10
  from typing import Annotated
9
11
 
10
12
  import typer
11
13
 
12
- from plato.worlds.config import RunConfig
14
+ from plato.worlds.config import EnvConfig, RunConfig
13
15
 
14
16
  app = typer.Typer(
15
17
  name="plato-world-runner",
@@ -133,6 +135,123 @@ def list_worlds(
133
135
  typer.echo(f" {name} (v{version}): {desc}")
134
136
 
135
137
 
138
+ async def _run_dev(
139
+ world_name: str,
140
+ config_path: Path,
141
+ env_timeout: int = 600,
142
+ ) -> None:
143
+ """Run a world locally with automatic environment creation.
144
+
145
+ This mimics what Chronos does but runs locally for debugging:
146
+ 1. Load and parse the config
147
+ 2. Create Plato session with all environments
148
+ 3. Run the world with the session attached
149
+ """
150
+ from plato.v2 import AsyncPlato
151
+ from plato.worlds.base import get_world
152
+
153
+ discover_worlds()
154
+
155
+ world_cls = get_world(world_name)
156
+ if world_cls is None:
157
+ from plato.worlds.base import get_registered_worlds
158
+
159
+ available = list(get_registered_worlds().keys())
160
+ raise ValueError(f"World '{world_name}' not found. Available: {available}")
161
+
162
+ # Load config
163
+ config_class = world_cls.get_config_class()
164
+ with open(config_path) as f:
165
+ config_data = json.load(f)
166
+
167
+ # Parse the config to get typed access
168
+ run_config = config_class._from_dict(config_data.copy())
169
+
170
+ # Get environment configs from the parsed config
171
+ env_configs: list[EnvConfig] = run_config.get_envs()
172
+
173
+ # Create Plato client
174
+ plato = AsyncPlato()
175
+ session = None
176
+
177
+ try:
178
+ if env_configs:
179
+ logger.info(f"Creating {len(env_configs)} environments...")
180
+ session = await plato.sessions.create(envs=env_configs, timeout=env_timeout)
181
+ logger.info(f"Created Plato session: {session.session_id}")
182
+ logger.info(f"Environments: {[e.alias for e in session.envs]}")
183
+
184
+ # Serialize and add to config
185
+ serialized = session.dump()
186
+ run_config.plato_session = serialized
187
+ else:
188
+ logger.info("No environments defined for this world")
189
+
190
+ # Run the world
191
+ logger.info(f"Starting world '{world_name}'...")
192
+ world_instance = world_cls()
193
+ await world_instance.run(run_config)
194
+
195
+ finally:
196
+ # Cleanup
197
+ if session:
198
+ logger.info("Closing Plato session...")
199
+ await session.close()
200
+ await plato.close()
201
+
202
+
203
+ @app.command("dev")
204
+ def dev(
205
+ world: Annotated[str, typer.Option("--world", "-w", help="World name to run")],
206
+ config: Annotated[Path, typer.Option("--config", "-c", help="Path to config JSON file")],
207
+ env_timeout: Annotated[int, typer.Option("--env-timeout", help="Timeout for environment creation (seconds)")] = 600,
208
+ verbose: Annotated[bool, typer.Option("--verbose", "-v", help="Enable verbose logging")] = False,
209
+ ) -> None:
210
+ """Run a world locally for development/debugging.
211
+
212
+ This creates Plato environments automatically (like Chronos does)
213
+ and runs the world with the session attached.
214
+
215
+ Example config.json:
216
+ {
217
+ "repository_url": "https://github.com/user/repo",
218
+ "prompt": "Fix the bug in main.py",
219
+ "agents": {
220
+ "coder": {
221
+ "image": "openhands:latest",
222
+ "config": {"model_name": "claude-sonnet-4"}
223
+ }
224
+ },
225
+ "secrets": {
226
+ "anthropic_api_key": "sk-..."
227
+ }
228
+ }
229
+
230
+ Environment variables:
231
+ PLATO_API_KEY: API key for Plato (required)
232
+ """
233
+ # Setup logging
234
+ log_level = logging.DEBUG if verbose else logging.INFO
235
+ logging.basicConfig(
236
+ level=log_level,
237
+ format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
238
+ )
239
+
240
+ if not config.exists():
241
+ typer.echo(f"Error: Config file not found: {config}", err=True)
242
+ raise typer.Exit(1)
243
+
244
+ if not os.environ.get("PLATO_API_KEY"):
245
+ typer.echo("Error: PLATO_API_KEY environment variable required", err=True)
246
+ raise typer.Exit(1)
247
+
248
+ try:
249
+ asyncio.run(_run_dev(world, config, env_timeout))
250
+ except Exception as e:
251
+ logger.exception(f"World execution failed: {e}")
252
+ raise typer.Exit(1)
253
+
254
+
136
255
  def main() -> None:
137
256
  """CLI entry point."""
138
257
  app()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plato-sdk-v2
3
- Version: 2.1.16
3
+ Version: 2.2.1
4
4
  Summary: Python SDK for the Plato API
5
5
  Author-email: Plato <support@plato.so>
6
6
  License-Expression: MIT
@@ -283,10 +283,13 @@ plato/_generated/api/v2/user/get_current_user.py,sha256=tvamtbWTEkeeNUBLSPqZIcCG
283
283
  plato/_generated/api/version/__init__.py,sha256=dQXTYrXjD1RZcvWwnlqXWAZ-eAV-V-6JSNuY7uaca7o,70
284
284
  plato/_generated/api/version/check.py,sha256=HTVNw0oi9gbvX4pOVoH4y4JywCxdl1pJTCk2PjJFwJ4,778
285
285
  plato/_generated/models/__init__.py,sha256=VGsTMYUCCqa7r_tl5m--dwjy7viYAN20nU2HhVAibcU,154130
286
- plato/_sims_generator/__init__.py,sha256=Cg8atlEoWsd5nf0qLz3_EbHxFVFtBwPDDUZbx3jxRrc,1125
286
+ plato/_sims_generator/__init__.py,sha256=Km4QOl9wxjQ5dgpdhk9QnBFJFFc9eq3rPbMWIQRjIn0,1602
287
287
  plato/_sims_generator/cli.py,sha256=mzolN-dxfMkVAdA-vC0esnai-cGg-i4ozOw8dACefV4,2709
288
+ plato/_sims_generator/instruction.py,sha256=Na9M-jIdBPhp_fLuBPTicoFnWriRyi8YiZ-eQBj64HI,6644
288
289
  plato/_sims_generator/parser.py,sha256=BbgRYllqYf7H76JyMfe7LYo1we-kh7YEOxUwrYT3shc,38347
289
290
  plato/_sims_generator/python.py,sha256=ZYZJeOhGhYV95iB2_G-stQHaIv5sQj0jo3GXSLb6SdA,18295
291
+ plato/_sims_generator/templates/instruction/helpers.py.jinja,sha256=kJ8lhVLPygjMh8l-In9rLtFci6Bxg3zVoz5BZFfLKms,4937
292
+ plato/_sims_generator/templates/instruction/init.py.jinja,sha256=oabz8xKdkz9SjRBYwg_GoHZdz1ZrhHXOOEazw2pOczQ,879
290
293
  plato/_sims_generator/templates/python/api_init.py.jinja,sha256=HYNtVsiGU91IzhBtBA3qlLv8b3U5kZbmW-FqdZ9F7mQ,188
291
294
  plato/_sims_generator/templates/python/client.py.jinja,sha256=H99L4kgRfTwJs3DOC9P-DcGtHNYBDNxcOvtedWEgWYM,19755
292
295
  plato/_sims_generator/templates/python/endpoint.py.jinja,sha256=1ToZiS8w_aZydVBhNt5KxLIbCo3toWCi4NPjLAmhVy4,12478
@@ -300,7 +303,7 @@ plato/agents/build.py,sha256=CNMbVQFs2_pYit1dA29Davve28Yi4c7TNK9wBB7odrE,1621
300
303
  plato/agents/config.py,sha256=VZVMdCmEQnoR0VkrGdScG8p6zSKVFe7BZPd2h8lKNjI,5460
301
304
  plato/agents/logging.py,sha256=z9rDlGPbrpcTS8PephbK2rDqT7thC1KyLkua4ypUkv4,12210
302
305
  plato/agents/runner.py,sha256=rOWYTSAhdola_FdrbviP955NBusNtBUy-q_c5fDA9to,5123
303
- plato/agents/trajectory.py,sha256=ayXEMCfYvIuXU2JkQWfPOVO9JywNSx8Kf6Ztrgsdh-I,10441
306
+ plato/agents/trajectory.py,sha256=WdiBmua0KvCrNaM3qgPI7-7B4xmSkfbP4oZ_9_8qHzU,10529
304
307
  plato/chronos/__init__.py,sha256=RHMvSrQS_-vkKOyTRuAkp2gKDP1HEuBLDnw8jcZs1Jg,739
305
308
  plato/chronos/client.py,sha256=YcOGtHWERyOD9z8LKt8bRMVL0cEwL2hiAP4qQgdZlUI,5495
306
309
  plato/chronos/errors.py,sha256=xqQIQB43nAL5urF8qc_1KUJql7KCnspULOFHLNnf83M,4199
@@ -369,32 +372,34 @@ plato/chronos/api/worlds/create_world.py,sha256=H6yl5QIazNXgryOR5rvscSIMf8Y9kjc6
369
372
  plato/chronos/api/worlds/delete_world.py,sha256=UETu3Zk0e2VkDdAyMilv1ev-0g_j-oujH1Dc8DBqQOc,1239
370
373
  plato/chronos/api/worlds/get_world.py,sha256=eHTM1U5JiNTaZwYLh7x4QVBoRQeI5kaJ9o6xSi4-nos,1356
371
374
  plato/chronos/api/worlds/list_worlds.py,sha256=hBAuGb69tlasyn-kV_LNr9x6Rr7SHhST5hXJn1uqMf8,1253
372
- plato/chronos/models/__init__.py,sha256=Iyh5srlL4oqsviCnjk9xHW7g0BjgJR4lAthFkZoXafs,21008
375
+ plato/chronos/models/__init__.py,sha256=5Hil8v_jFX1YU6LpOfqyJM4WV867Ckv6CX052Q4SCso,20996
373
376
  plato/sims/README.md,sha256=FIbJhNVNAV-SO6dq_cXX3Rg0C7HdQCfEY9YxGlkCmsM,6902
374
377
  plato/sims/__init__.py,sha256=tnoCGKZwNx6h22tEWLujdpLv6K4PpFU2RnDOhL1o-Uc,1494
375
378
  plato/sims/agent_helpers.py,sha256=kITvQywoTCS8mGhro3jZWuPJHDlje-UZujhjoahqhd0,10291
376
- plato/sims/cli.py,sha256=ySG5TNh9L2E-bgP0Jv4sbewReaoPw5jDYFAQk_jubuw,46093
379
+ plato/sims/cli.py,sha256=lvdc_fSyNVmXvblFaE0saiVPdTpoR8Tlh9NN2LCBrd8,52704
377
380
  plato/sims/generate_clients.py,sha256=nEe39v3UOcks-ggv5jomcwN33R5U9n8MDNCpHoZ2lDg,5958
378
- plato/sims/registry.py,sha256=_xtjcI4HHGBsJ4c0kzxK90U2B_h6FK-5FAoAwyWZokQ,8777
381
+ plato/sims/registry.py,sha256=1LHW1SMJJNYIvn0zY9BPkHo4yHpdDAk7BxTYw1HpweY,11963
379
382
  plato/v1/__init__.py,sha256=t1Ejb7YCFOVSKZL9hJ0UsmEE1mULDvO__f75dz1UueQ,197
380
383
  plato/v1/audit_ui.py,sha256=zYYufJKn7291uCNb_59ItmDTYsPr7YLshBFwcAwl1LQ,10990
381
384
  plato/v1/cli.py,sha256=iEt58vvW7ab9YH0CLcBHvf4653fk1gcEdij4HZc10YY,269
382
385
  plato/v1/config.py,sha256=Zc5qGBcR8UfLuZrfQhkZ5cUmV_9pPKHPyKpU0SNysGY,667
383
386
  plato/v1/exceptions.py,sha256=BS5A0NLZ2FgL6YVaIL-c8FXASTsOpuKrF3_Pb0tad6w,109
384
- plato/v1/flow_executor.py,sha256=DrpcWECW120P6WlS2Ol7AVcGHgKiJ-BFmYQi1_fdENw,19010
387
+ plato/v1/flow_executor.py,sha256=rHYPPG4XPdq00Ty7_c4r7dZ-LixtUrEV3KEg1i-Owto,19720
385
388
  plato/v1/sandbox_sdk.py,sha256=5-ESB3spe4BFGn1dVfgSWwKyfQeeUokPWsmbti3obOY,41854
386
- plato/v1/sdk.py,sha256=b-mDCwVtxWbVsHEZ1x5m1kJ4Hxs57Y7l-UBR2aUP0dY,33323
387
- plato/v1/sync_env.py,sha256=qClrMAe5CNj6KX8lDhHJi7GIToDkm00o8KNAYfJMf_Q,24793
388
- plato/v1/sync_flow_executor.py,sha256=NTRKtlAeuFct6kKWRQ4LsRwnGC1Yo58ICN91dDzOjBg,18523
389
- plato/v1/sync_sdk.py,sha256=ztAvqR5yW_ALj8g97K6U-jSQzwzVNVKWlGZ-tdMUP_M,25620
389
+ plato/v1/sdk.py,sha256=zNcYgANeMZG8r9AH3POJhJ11UQcOvdsLfUFABoB1cwg,33382
390
+ plato/v1/sync_env.py,sha256=UIfDpx3nPHBNWzahSddvol0SvfK9vU4mr3MOIOPCGr8,24878
391
+ plato/v1/sync_flow_executor.py,sha256=kgvNYOtA9FHeNfP7qb8ZPUIlTsfIss_Z98W8uX5veck,19233
392
+ plato/v1/sync_sdk.py,sha256=2sedg1QJiSxr1I3kCyfaLAnlAgHlbblc3QQP_47O30k,25697
390
393
  plato/v1/cli/__init__.py,sha256=om4b7PxgsoI7rEwuQelmQkqPdhMVn53_5qEN8kvksYw,105
391
- plato/v1/cli/agent.py,sha256=GUPDx6iZlGlW3q8QC863Vdrpe5_f6PBtcNo5vYipaEI,43329
392
- plato/v1/cli/main.py,sha256=ktPtBvMwykR7AjXmTQ6bmZkHdzpAjhX5Fq66cDbGSzA,6844
393
- plato/v1/cli/pm.py,sha256=sIrh7qVyL-GOI8cgCUDFO2StXCxaKkCpGoN2waMqiyw,47579
394
- plato/v1/cli/sandbox.py,sha256=r4VrZxfGLwLdmZyylw07dQ70glvsyBg3j7S_qU6UrRs,87801
394
+ plato/v1/cli/agent.py,sha256=G6TV3blG_BqMDBWS-CG7GwzqoqcJTMsIKQ88jvLXb4k,43745
395
+ plato/v1/cli/main.py,sha256=ZBF9J82Cp6TB-1mLkabJryxP44yNAYJoKE8K7LUNQng,6916
396
+ plato/v1/cli/pm.py,sha256=uLM6WszKqxq9Czg1FraDyWb9_INUuHZq63imvRYfRLw,49734
397
+ plato/v1/cli/sandbox.py,sha256=7VoiDIL6u2_8wZI4sj9J6CyI8IMfjHmHOp8FPiXs-3U,89411
398
+ plato/v1/cli/sim.py,sha256=qF3H2RqMS96kQX8MwDpqXskZhpM4YFSgb283wcsMbfQ,266
395
399
  plato/v1/cli/ssh.py,sha256=pePHD0lFPwSkATZYSannpFtHfJWKImAdLyS2463aRRw,6287
396
400
  plato/v1/cli/utils.py,sha256=be-llK6T6NHnIQl_Kfs-8EPu9JhIuZ_k9tJ3Ts-AKt4,3887
397
- plato/v1/cli/world.py,sha256=f-65n70-V2EBcYs9hbYqCXVT8n2xm7opIgmB5Z6yi3Y,9580
401
+ plato/v1/cli/verify.py,sha256=WZFxAqjpgq8vA0tc32g0VsNQjSZ1S0n4o_QoHQBkmsI,48404
402
+ plato/v1/cli/world.py,sha256=yBUadOJs1QYm6Jmx_ACDzogybRq5x4B-BnTvGO_ulQk,9757
398
403
  plato/v1/examples/doordash_tasks.py,sha256=8Sz9qx-vTmiOAiCAbrDRvZGsA1qQQBr1KHbxXdjr7OI,23233
399
404
  plato/v1/examples/loadtest.py,sha256=ZsQYNN_fZjE7CbrbVJb4KDc0OLaH7b66iPrEHDhuw0U,5609
400
405
  plato/v1/examples/test_env.py,sha256=8kUISbZyMi0Xh9HK7Il1okKQyz0Iq-vAKWgzC8kqUfU,4513
@@ -433,7 +438,7 @@ plato/v1/extensions/envgen-recorder/sessions.js,sha256=IrW0elMYYh4cUEmNZiHC-XhFL
433
438
  plato/v1/extensions/envgen-recorder/styles.css,sha256=NbpKw4NSbYw6RVDOn4zpNwwVnjFQtKIene2MZBz9kb0,5359
434
439
  plato/v1/models/__init__.py,sha256=rnv5oO0RQ_mbnv_0FxvCWpCnSKmBePoYoIQ0h1LuKE8,813
435
440
  plato/v1/models/build_models.py,sha256=zcRwg2pzU5GFDp_Qi7g0UCVNGkOtXTlHNvq_6gm5mJc,10201
436
- plato/v1/models/env.py,sha256=UClRO8wgpZutcwGsAc1Sk3tnZDucQkkT-qH_WluX77o,30958
441
+ plato/v1/models/env.py,sha256=UZgdjZrIkODeuTLTHaIyUqUJM83S8YYY_RbYqDeYjDk,31043
437
442
  plato/v1/models/flow.py,sha256=bkleb7-OR6V5tzPtggf0ZJhHZQwnktCYr1C-ONpRzwE,6920
438
443
  plato/v1/models/sandbox.py,sha256=yRN036G91tFAXGxU1ni7zCU1o7U1N8nI0mjLlBRDoSk,3478
439
444
  plato/v1/models/task.py,sha256=QXwdFpDM_NLjRpQSK6duibXJXFAPZ8-PpyuLWZC5o4I,4897
@@ -446,24 +451,24 @@ plato/v2/async_/artifact.py,sha256=JBWVQeVaZhkU2qn_knyzyA7wd5iQ8qxfLQ_l9GPhgYs,1
446
451
  plato/v2/async_/client.py,sha256=GVgAgNN5gsDME8iV0zxqnwbsVS93J6cknOcq_VXwYN8,4209
447
452
  plato/v2/async_/environment.py,sha256=Dv_4QuQx5vLVp1m1mJR2fXybvbhz-Q4gLtZecCdyFT8,4622
448
453
  plato/v2/async_/flow_executor.py,sha256=Tl4nRu1ZPWJFNNxyTGy-PxvebZEUD18ZDaz8T2chtzU,14188
449
- plato/v2/async_/session.py,sha256=ThlDOvkh7fR-58xt7RZUYnXSMqhF7juF72NOUgFAyCk,35439
454
+ plato/v2/async_/session.py,sha256=3EL4SX1kiYDKd981dRWDZsEu1WtJOXkvbAdw3B5o_EI,35426
450
455
  plato/v2/sync/__init__.py,sha256=_WigxuehCC8A2yRy4mSaMQmIZhS0Gch4hhZC1VHyYXs,310
451
456
  plato/v2/sync/artifact.py,sha256=wTLC-tugG128wLvh-JqNPb0zsw5FXEJlZNahurSWink,1169
452
457
  plato/v2/sync/client.py,sha256=Q9fS1BF4KxTMMnceMwCMlb5dNFZ6LA4gsXWNLgsL2eE,3870
453
458
  plato/v2/sync/environment.py,sha256=EJS_MBXHQgdOYztmnvcDPyQV1Z0dV6BA-7UEJ_Z-bgE,3878
454
459
  plato/v2/sync/flow_executor.py,sha256=N41-WCWIJVcCR2UmPUEiK7roNacYoeONkRXpR7lUgT8,13941
455
- plato/v2/sync/session.py,sha256=PWOgJmmXU1EoqSPQ_Omdtq4p7uTrRtA7CwTqhlUnDnI,27113
460
+ plato/v2/sync/session.py,sha256=jl0leH3wENQCcOXQruqBcxhb47yo_9QBsdMMktgpnnw,27101
456
461
  plato/v2/utils/__init__.py,sha256=XLeFFsjXkm9g2raMmo7Wt4QN4hhCrNZDJKnpffJ4LtM,38
457
462
  plato/v2/utils/db_cleanup.py,sha256=lnI5lsMHNHpG85Y99MaE4Rzc3618piuzhvH-uXO1zIc,8702
458
463
  plato/v2/utils/models.py,sha256=PwehSSnIRG-tM3tWL1PzZEH77ZHhIAZ9R0UPs6YknbM,1441
459
464
  plato/v2/utils/proxy_tunnel.py,sha256=8ZTd0jCGSfIHMvSv1fgEyacuISWnGPHLPbDglWroTzY,10463
460
465
  plato/worlds/README.md,sha256=TgG4aidude0ouJSCfY81Ev45hsUxPkO85HUIiWNqkcc,5463
461
- plato/worlds/__init__.py,sha256=0ogDVw5GEk4OT7FSD0Z7SrafTn_TBdo8DOU_v6ncbd4,1478
462
- plato/worlds/base.py,sha256=vLAHkYpYg4kl7LgftQ0uC6xXhASVqREogn6msNWA6Hk,9650
466
+ plato/worlds/__init__.py,sha256=crzpXFh4XD8eS4pYFTEUf3XgUf0wapFPT4npAu8sWwk,2078
467
+ plato/worlds/base.py,sha256=McV2QAuHYztSMfG8EXQML1kEPbdeADLt8tgiYpH35n4,10751
463
468
  plato/worlds/build_hook.py,sha256=KSoW0kqa5b7NyZ7MYOw2qsZ_2FkWuz0M3Ru7AKOP7Qw,3486
464
- plato/worlds/config.py,sha256=-K1dnlRL5I-DNYEoc1I4cKIsTw53X_1QrRY2SWJvRiQ,6256
465
- plato/worlds/runner.py,sha256=r9B2BxBae8_dM7y5cJf9xhThp_I1Qvf_tlPq2rs8qC8,4013
466
- plato_sdk_v2-2.1.16.dist-info/METADATA,sha256=5S_mx4Iij8UNv8od9y6b3n8T00t6gFzM01-1wS-rLdg,8509
467
- plato_sdk_v2-2.1.16.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
468
- plato_sdk_v2-2.1.16.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
469
- plato_sdk_v2-2.1.16.dist-info/RECORD,,
469
+ plato/worlds/config.py,sha256=ggDcySspfeFry2KBUwhgnS6Po2KssYzwZNIDmVeGhPQ,9460
470
+ plato/worlds/runner.py,sha256=07fKyPYxem1vIKfPRo4le7eKWTkY3euDXugObVyAsf4,7858
471
+ plato_sdk_v2-2.2.1.dist-info/METADATA,sha256=zDXdIASeuEZ8QC8Ku-XdYnV17lLghEF__8MTbURQTWg,8508
472
+ plato_sdk_v2-2.2.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
473
+ plato_sdk_v2-2.2.1.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
474
+ plato_sdk_v2-2.2.1.dist-info/RECORD,,