plato-sdk-v2 2.1.11__py3-none-any.whl → 2.2.4__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/runner.py CHANGED
@@ -3,13 +3,16 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
+ import json
6
7
  import logging
8
+ import os
9
+ import platform
7
10
  from pathlib import Path
8
11
  from typing import Annotated
9
12
 
10
13
  import typer
11
14
 
12
- from plato.worlds.config import RunConfig
15
+ from plato.worlds.config import EnvConfig, RunConfig
13
16
 
14
17
  app = typer.Typer(
15
18
  name="plato-world-runner",
@@ -133,6 +136,341 @@ def list_worlds(
133
136
  typer.echo(f" {name} (v{version}): {desc}")
134
137
 
135
138
 
139
+ async def _build_agent_image(
140
+ agent_name: str,
141
+ agents_dir: Path,
142
+ plato_client_root: Path | None = None,
143
+ ) -> bool:
144
+ """Build a local agent Docker image.
145
+
146
+ Args:
147
+ agent_name: Name of the agent (e.g., "openhands")
148
+ agents_dir: Directory containing agent subdirectories
149
+ plato_client_root: Root of plato-client repo (for dev builds), or None for prod builds
150
+
151
+ Returns:
152
+ True if build succeeded, False otherwise
153
+ """
154
+ import subprocess
155
+
156
+ # Resolve paths to absolute
157
+ agents_dir = agents_dir.expanduser().resolve()
158
+ agent_path = agents_dir / agent_name
159
+ dockerfile_path = agent_path / "Dockerfile"
160
+
161
+ if not dockerfile_path.exists():
162
+ logger.warning(f"No Dockerfile found for agent '{agent_name}' at {dockerfile_path}")
163
+ return False
164
+
165
+ image_tag = f"{agent_name}:latest"
166
+
167
+ # Determine build context and target
168
+ if plato_client_root:
169
+ plato_client_root = plato_client_root.expanduser().resolve()
170
+
171
+ if plato_client_root and plato_client_root.exists():
172
+ # Dev build from plato-client root (includes local python-sdk)
173
+ build_context = str(plato_client_root)
174
+ dockerfile_abs = str(dockerfile_path)
175
+ target = "dev"
176
+ logger.info(f"Building {image_tag} (dev mode from {build_context})...")
177
+ else:
178
+ # Prod build from agent directory
179
+ build_context = str(agent_path)
180
+ dockerfile_abs = str(dockerfile_path)
181
+ target = "prod"
182
+ logger.info(f"Building {image_tag} (prod mode from {build_context})...")
183
+
184
+ cmd = [
185
+ "docker",
186
+ "build",
187
+ "--target",
188
+ target,
189
+ "-t",
190
+ image_tag,
191
+ "-f",
192
+ dockerfile_abs,
193
+ ]
194
+
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
+ cmd.append(build_context)
200
+
201
+ logger.debug(f"Build command: {' '.join(cmd)}")
202
+
203
+ result = subprocess.run(cmd, capture_output=True, text=True)
204
+
205
+ if result.returncode != 0:
206
+ logger.error(f"Failed to build {image_tag}:\n{result.stderr}")
207
+ return False
208
+
209
+ logger.info(f"Successfully built {image_tag}")
210
+ return True
211
+
212
+
213
+ def _extract_agent_images_from_config(config_data: dict) -> list[str]:
214
+ """Extract agent image names from config data.
215
+
216
+ Args:
217
+ config_data: Raw config dictionary
218
+
219
+ Returns:
220
+ List of image names (without tags) that are local (not from a registry)
221
+ """
222
+ images = []
223
+
224
+ # Check agents section
225
+ agents = config_data.get("agents", {})
226
+ for agent_config in agents.values():
227
+ if isinstance(agent_config, dict):
228
+ image = agent_config.get("image", "")
229
+ # Only include local images (no registry prefix like ghcr.io/)
230
+ if image and "/" not in image.split(":")[0]:
231
+ # Extract name without tag
232
+ name = image.split(":")[0]
233
+ if name not in images:
234
+ images.append(name)
235
+
236
+ # Also check direct coder/verifier fields
237
+ for field in ["coder", "verifier"]:
238
+ agent_config = config_data.get(field, {})
239
+ if isinstance(agent_config, dict):
240
+ image = agent_config.get("image", "")
241
+ if image and "/" not in image.split(":")[0]:
242
+ name = image.split(":")[0]
243
+ if name not in images:
244
+ images.append(name)
245
+
246
+ return images
247
+
248
+
249
+ async def _run_dev(
250
+ world_name: str,
251
+ config_path: Path,
252
+ env_timeout: int = 600,
253
+ chronos_url: str | None = None,
254
+ api_key: str | None = None,
255
+ agents_dir: Path | None = None,
256
+ ) -> None:
257
+ """Run a world locally with automatic environment creation.
258
+
259
+ This mimics what Chronos does but runs locally for debugging:
260
+ 1. Load and parse the config
261
+ 2. Build local agent images if --agents-dir is provided
262
+ 3. Create Plato session with all environments
263
+ 4. Optionally initialize Chronos logging for callbacks
264
+ 5. Run the world with the session attached
265
+
266
+ Args:
267
+ world_name: Name of the world to run
268
+ config_path: Path to the config JSON file
269
+ env_timeout: Timeout for environment creation (seconds)
270
+ chronos_url: Optional Chronos base URL for sending log events
271
+ api_key: Optional Plato API key (used for Chronos session creation)
272
+ agents_dir: Optional directory containing agent source code
273
+ """
274
+ from uuid import uuid4
275
+
276
+ from plato.v2 import AsyncPlato
277
+ from plato.worlds.base import get_world
278
+
279
+ discover_worlds()
280
+
281
+ world_cls = get_world(world_name)
282
+ if world_cls is None:
283
+ from plato.worlds.base import get_registered_worlds
284
+
285
+ available = list(get_registered_worlds().keys())
286
+ raise ValueError(f"World '{world_name}' not found. Available: {available}")
287
+
288
+ # Load config
289
+ config_class = world_cls.get_config_class()
290
+ with open(config_path) as f:
291
+ config_data = json.load(f)
292
+
293
+ # Parse the config to get typed access
294
+ run_config = config_class._from_dict(config_data.copy())
295
+
296
+ # Build local agent images if agents_dir is provided
297
+ if agents_dir:
298
+ # Resolve agents_dir to absolute path
299
+ agents_dir = agents_dir.expanduser().resolve()
300
+ agent_images = _extract_agent_images_from_config(config_data)
301
+ if agent_images:
302
+ logger.info(f"Building local agent images: {agent_images}")
303
+ # Determine if we're in a plato-client repo for dev builds
304
+ # (agents_dir is something like /path/to/plato-client/agents)
305
+ plato_client_root = agents_dir.parent if agents_dir.name == "agents" else None
306
+ for agent_name in agent_images:
307
+ success = await _build_agent_image(agent_name, agents_dir, plato_client_root)
308
+ if not success:
309
+ raise RuntimeError(f"Failed to build agent image: {agent_name}")
310
+ else:
311
+ logger.info("No local agent images found in config")
312
+
313
+ # Get environment configs from the parsed config
314
+ env_configs: list[EnvConfig] = run_config.get_envs()
315
+
316
+ # Create Plato client
317
+ plato = AsyncPlato()
318
+ session = None
319
+
320
+ # Initialize Chronos logging if URL provided
321
+ chronos_session_id: str | None = None
322
+ if chronos_url:
323
+ from plato.agents import init_logging
324
+
325
+ chronos_session_id = f"dev-{uuid4().hex[:8]}"
326
+ callback_url = f"{chronos_url.rstrip('/')}/api/v1/callback"
327
+ init_logging(
328
+ callback_url=callback_url,
329
+ session_id=chronos_session_id,
330
+ )
331
+ logger.info(f"Chronos logging enabled: {callback_url} (session: {chronos_session_id})")
332
+
333
+ # Update run_config with session info for agents
334
+ run_config.session_id = chronos_session_id
335
+ run_config.callback_url = callback_url
336
+
337
+ try:
338
+ if env_configs:
339
+ logger.info(f"Creating {len(env_configs)} environments...")
340
+ session = await plato.sessions.create(envs=env_configs, timeout=env_timeout)
341
+ logger.info(f"Created Plato session: {session.session_id}")
342
+ logger.info(f"Environments: {[e.alias for e in session.envs]}")
343
+
344
+ # Serialize and add to config
345
+ serialized = session.dump()
346
+ run_config.plato_session = serialized
347
+ else:
348
+ logger.info("No environments defined for this world")
349
+
350
+ # Run the world
351
+ logger.info(f"Starting world '{world_name}'...")
352
+ world_instance = world_cls()
353
+ await world_instance.run(run_config)
354
+
355
+ finally:
356
+ # Cleanup
357
+ if session:
358
+ logger.info("Closing Plato session...")
359
+ await session.close()
360
+ await plato.close()
361
+
362
+ # Reset logging
363
+ if chronos_url:
364
+ from plato.agents import reset_logging
365
+
366
+ reset_logging()
367
+
368
+
369
+ def _setup_colored_logging(verbose: bool = False) -> None:
370
+ """Setup colored logging with filtered noisy loggers."""
371
+ log_level = logging.DEBUG if verbose else logging.INFO
372
+
373
+ # Define colors for different log levels
374
+ colors = {
375
+ "DEBUG": "\033[36m", # Cyan
376
+ "INFO": "\033[32m", # Green
377
+ "WARNING": "\033[33m", # Yellow
378
+ "ERROR": "\033[31m", # Red
379
+ "CRITICAL": "\033[35m", # Magenta
380
+ }
381
+ reset = "\033[0m"
382
+
383
+ class ColoredFormatter(logging.Formatter):
384
+ def format(self, record: logging.LogRecord) -> str:
385
+ color = colors.get(record.levelname, "")
386
+ record.levelname = f"{color}{record.levelname}{reset}"
387
+ record.name = f"\033[34m{record.name}{reset}" # Blue for logger name
388
+ return super().format(record)
389
+
390
+ # Create handler with colored formatter
391
+ handler = logging.StreamHandler()
392
+ handler.setFormatter(
393
+ ColoredFormatter(
394
+ "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
395
+ datefmt="%H:%M:%S",
396
+ )
397
+ )
398
+
399
+ # Configure root logger
400
+ root_logger = logging.getLogger()
401
+ root_logger.setLevel(log_level)
402
+ root_logger.handlers = [handler]
403
+
404
+ # Silence noisy HTTP loggers
405
+ for noisy_logger in ["httpcore", "httpx", "urllib3", "hpack"]:
406
+ logging.getLogger(noisy_logger).setLevel(logging.WARNING)
407
+
408
+
409
+ @app.command("dev")
410
+ def dev(
411
+ world: Annotated[str, typer.Option("--world", "-w", help="World name to run")],
412
+ config: Annotated[Path, typer.Option("--config", "-c", help="Path to config JSON file")],
413
+ env_timeout: Annotated[int, typer.Option("--env-timeout", help="Timeout for environment creation (seconds)")] = 600,
414
+ chronos_url: Annotated[
415
+ str | None, typer.Option("--chronos-url", help="Chronos base URL for log events (e.g., http://localhost:8000)")
416
+ ] = None,
417
+ api_key: Annotated[str | None, typer.Option("--api-key", help="Plato API key for Chronos authentication")] = None,
418
+ agents_dir: Annotated[
419
+ Path | None,
420
+ typer.Option("--agents-dir", "-a", help="Directory containing agent source code (builds local images)"),
421
+ ] = None,
422
+ verbose: Annotated[bool, typer.Option("--verbose", "-v", help="Enable verbose logging")] = False,
423
+ ) -> None:
424
+ """Run a world locally for development/debugging.
425
+
426
+ This creates Plato environments automatically (like Chronos does)
427
+ and runs the world with the session attached.
428
+
429
+ Optionally sends log events to a Chronos server for real-time monitoring.
430
+
431
+ Example config.json:
432
+ {
433
+ "instruction": "Create a git repo and upload files to S3",
434
+ "coder": {
435
+ "image": "openhands:latest",
436
+ "config": {"model_name": "gemini/gemini-3-flash-preview"}
437
+ },
438
+ "secrets": {
439
+ "gemini_api_key": "..."
440
+ }
441
+ }
442
+
443
+ Environment variables:
444
+ PLATO_API_KEY: API key for Plato (required)
445
+
446
+ Examples:
447
+ # Basic usage
448
+ plato-world-runner dev -w code -c config.json
449
+
450
+ # With local agent builds (from plato-client repo)
451
+ plato-world-runner dev -w code -c config.json --agents-dir ~/plato-client/agents
452
+
453
+ # With Chronos logging
454
+ plato-world-runner dev -w code -c config.json --chronos-url http://localhost:8000
455
+ """
456
+ # Setup colored logging with filtered noisy loggers
457
+ _setup_colored_logging(verbose)
458
+
459
+ if not config.exists():
460
+ typer.echo(f"Error: Config file not found: {config}", err=True)
461
+ raise typer.Exit(1)
462
+
463
+ if not os.environ.get("PLATO_API_KEY"):
464
+ typer.echo("Error: PLATO_API_KEY environment variable required", err=True)
465
+ raise typer.Exit(1)
466
+
467
+ try:
468
+ asyncio.run(_run_dev(world, config, env_timeout, chronos_url, api_key, agents_dir))
469
+ except Exception as e:
470
+ logger.exception(f"World execution failed: {e}")
471
+ raise typer.Exit(1)
472
+
473
+
136
474
  def main() -> None:
137
475
  """CLI entry point."""
138
476
  app()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plato-sdk-v2
3
- Version: 2.1.11
3
+ Version: 2.2.4
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
@@ -294,13 +297,13 @@ plato/_sims_generator/templates/python/errors.py.jinja,sha256=8L_FbHczBNLXJrbSlN
294
297
  plato/_sims_generator/templates/python/package_init.py.jinja,sha256=sOcJxUT0LuOWu5jOMGGKYxfCEjcYQv1hGF3n0iOA4hQ,986
295
298
  plato/_sims_generator/templates/python/tag_init.py.jinja,sha256=WB_9cv0JKIVg5TOXeSolET3tAfVg7sExjboh5jbCXz4,170
296
299
  plato/_sims_generator/templates/python/version_init.py.jinja,sha256=sGvFcYVfzXFyQDAe0PSOrg9yys93KE0XInFQNb1TvCY,179
297
- plato/agents/__init__.py,sha256=byhtkrMNBDT8lUtryZK_Ov6u-gtnRvyex2OUGKVAy30,2656
300
+ plato/agents/__init__.py,sha256=qslIFTVSe1yFeTRCKr8Z-mInWarj2HDbNZV4u6AiXek,2755
298
301
  plato/agents/base.py,sha256=vUbPQuNSo6Ka2lIB_ZOXgi4EoAjtAD7GIj9LnNotam0,4577
299
302
  plato/agents/build.py,sha256=CNMbVQFs2_pYit1dA29Davve28Yi4c7TNK9wBB7odrE,1621
300
- plato/agents/callback.py,sha256=9ziAH72HX6CDvMy_IrzzvSOlFDnhdz2TDG4hCmbc8IU,8188
301
303
  plato/agents/config.py,sha256=VZVMdCmEQnoR0VkrGdScG8p6zSKVFe7BZPd2h8lKNjI,5460
302
- plato/agents/runner.py,sha256=4kFa0kzuqo7QCYS3yxvXZspS2RHici0kTgdDyo1Vo78,11237
303
- plato/agents/trajectory.py,sha256=ayXEMCfYvIuXU2JkQWfPOVO9JywNSx8Kf6Ztrgsdh-I,10441
304
+ plato/agents/logging.py,sha256=z9rDlGPbrpcTS8PephbK2rDqT7thC1KyLkua4ypUkv4,12210
305
+ plato/agents/runner.py,sha256=YoqG1QdNScIjSSH0vPgnm42LlqeAeVsFT01VL77ony0,5565
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=bRDwzwYJWMfWeJanASgnSTknGDWIfry7zllSw0t5CLo,7110
466
+ plato/worlds/__init__.py,sha256=crzpXFh4XD8eS4pYFTEUf3XgUf0wapFPT4npAu8sWwk,2078
467
+ plato/worlds/base.py,sha256=254kR0YmRaaOyenDC1jlRhNlEsENgUpcq-crkWJcRe8,15200
463
468
  plato/worlds/build_hook.py,sha256=KSoW0kqa5b7NyZ7MYOw2qsZ_2FkWuz0M3Ru7AKOP7Qw,3486
464
- plato/worlds/config.py,sha256=RDBGhZRFJNshFVO-1H8xDcqxzUqahlSJtoo-eQpavgs,6242
465
- plato/worlds/runner.py,sha256=r9B2BxBae8_dM7y5cJf9xhThp_I1Qvf_tlPq2rs8qC8,4013
466
- plato_sdk_v2-2.1.11.dist-info/METADATA,sha256=LpA0Df50RgEhaVXKFcLjs9druTQTQ9Mp6f6brZl_rTc,8509
467
- plato_sdk_v2-2.1.11.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
468
- plato_sdk_v2-2.1.11.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
469
- plato_sdk_v2-2.1.11.dist-info/RECORD,,
469
+ plato/worlds/config.py,sha256=ggDcySspfeFry2KBUwhgnS6Po2KssYzwZNIDmVeGhPQ,9460
470
+ plato/worlds/runner.py,sha256=RNnWFQ7rfEWE7TQ_tqgLHgLm1a4VxtP0mR7beALx4f0,15781
471
+ plato_sdk_v2-2.2.4.dist-info/METADATA,sha256=hUWIc47BNWlYMW32HWQEeSNixo7licBxYJ0G9lnvhaU,8508
472
+ plato_sdk_v2-2.2.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
473
+ plato_sdk_v2-2.2.4.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
474
+ plato_sdk_v2-2.2.4.dist-info/RECORD,,