plato-sdk-v2 2.3.4__py3-none-any.whl → 2.3.6__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
@@ -126,13 +126,15 @@ class RunConfig(BaseModel):
126
126
 
127
127
  Attributes:
128
128
  session_id: Unique Chronos session identifier
129
- callback_url: Callback URL for status updates
129
+ otel_url: OTel endpoint URL (e.g., https://chronos.plato.so/api/otel)
130
+ upload_url: Presigned S3 URL for uploading artifacts (provided by Chronos)
130
131
  plato_session: Serialized Plato session for connecting to existing VM session
131
132
  checkpoint: Configuration for automatic checkpoints after steps
132
133
  """
133
134
 
134
135
  session_id: str = ""
135
- callback_url: str = ""
136
+ otel_url: str = "" # OTel endpoint URL
137
+ upload_url: str = "" # Presigned S3 URL for uploads
136
138
  all_secrets: dict[str, str] = Field(default_factory=dict) # All secrets (world + agent)
137
139
 
138
140
  # Serialized Plato session for connecting to VM and sending heartbeats
@@ -182,7 +184,7 @@ class RunConfig(BaseModel):
182
184
  envs = []
183
185
 
184
186
  # Skip runtime fields
185
- runtime_fields = {"session_id", "callback_url", "all_secrets", "plato_session", "checkpoint", "state"}
187
+ runtime_fields = {"session_id", "otel_url", "upload_url", "all_secrets", "plato_session", "checkpoint", "state"}
186
188
 
187
189
  for field_name, prop_schema in properties.items():
188
190
  if field_name in runtime_fields:
plato/worlds/runner.py CHANGED
@@ -246,13 +246,22 @@ def _extract_agent_images_from_config(config_data: dict) -> list[str]:
246
246
  return images
247
247
 
248
248
 
249
+ class ChronosSessionInfo:
250
+ """Info returned from Chronos session creation."""
251
+
252
+ def __init__(self, public_id: str, otel_url: str, upload_url: str):
253
+ self.public_id = public_id
254
+ self.otel_url = otel_url
255
+ self.upload_url = upload_url
256
+
257
+
249
258
  async def _create_chronos_session(
250
259
  chronos_url: str,
251
260
  api_key: str,
252
261
  world_name: str,
253
262
  world_config: dict,
254
263
  plato_session_id: str | None = None,
255
- ) -> tuple[str, str]:
264
+ ) -> ChronosSessionInfo:
256
265
  """Create a session in Chronos.
257
266
 
258
267
  Args:
@@ -263,7 +272,7 @@ async def _create_chronos_session(
263
272
  plato_session_id: Optional Plato session ID if already created
264
273
 
265
274
  Returns:
266
- Tuple of (session_id, callback_url)
275
+ ChronosSessionInfo with session_id, otel_url, and upload_url
267
276
  """
268
277
  import httpx
269
278
 
@@ -282,7 +291,12 @@ async def _create_chronos_session(
282
291
  response.raise_for_status()
283
292
  data = response.json()
284
293
 
285
- return data["public_id"], data["callback_url"]
294
+ print(f"[Runner] Chronos session response: {data}")
295
+ return ChronosSessionInfo(
296
+ public_id=data["public_id"],
297
+ otel_url=data["otel_url"],
298
+ upload_url=data["upload_url"],
299
+ )
286
300
 
287
301
 
288
302
  async def _close_chronos_session(
@@ -325,7 +339,7 @@ async def _run_dev(
325
339
  1. Load and parse the config
326
340
  2. Build local agent images if --agents-dir is provided
327
341
  3. Create Plato session with all environments
328
- 4. Create Chronos session for logging/callbacks
342
+ 4. Create Chronos session for OTel traces
329
343
  5. Run the world with the session attached
330
344
 
331
345
  Requires environment variables:
@@ -408,27 +422,30 @@ async def _run_dev(
408
422
 
409
423
  # Create Chronos session (after Plato session so we can link them)
410
424
  logger.info(f"Creating Chronos session at {chronos_url}...")
411
- chronos_session_id, callback_url = await _create_chronos_session(
425
+ chronos_session = await _create_chronos_session(
412
426
  chronos_url=chronos_url,
413
427
  api_key=api_key,
414
428
  world_name=world_name,
415
429
  world_config=config_data,
416
430
  plato_session_id=plato_session_id,
417
431
  )
432
+ chronos_session_id = chronos_session.public_id
418
433
  logger.info(f"Created Chronos session: {chronos_session_id}")
419
434
  logger.info(f"View at: {chronos_url}/sessions/{chronos_session_id}")
420
435
 
421
- # Initialize logging
422
- from plato.agents import init_logging
436
+ # Update run_config with session info from Chronos
437
+ run_config.session_id = chronos_session_id
438
+ run_config.otel_url = chronos_session.otel_url
439
+ run_config.upload_url = chronos_session.upload_url
423
440
 
424
- init_logging(
425
- callback_url=callback_url,
426
- session_id=chronos_session_id,
427
- )
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}")
428
446
 
429
- # Update run_config with session info for agents
430
- run_config.session_id = chronos_session_id
431
- run_config.callback_url = callback_url
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}")
432
449
 
433
450
  # Run the world
434
451
  logger.info(f"Starting world '{world_name}'...")
@@ -446,11 +463,6 @@ async def _run_dev(
446
463
  if chronos_session_id:
447
464
  await _close_chronos_session(chronos_url, api_key, chronos_session_id)
448
465
 
449
- # Reset logging
450
- from plato.agents import reset_logging
451
-
452
- reset_logging()
453
-
454
466
 
455
467
  def _setup_colored_logging(verbose: bool = False) -> None:
456
468
  """Setup colored logging with filtered noisy loggers."""
@@ -497,11 +509,16 @@ def dev(
497
509
  world: Annotated[str, typer.Option("--world", "-w", help="World name to run")],
498
510
  config: Annotated[Path, typer.Option("--config", "-c", help="Path to config JSON file")],
499
511
  env_timeout: Annotated[
500
- int, typer.Option("--env-timeout", help="Timeout for environment creation (seconds)")
512
+ int,
513
+ typer.Option("--env-timeout", help="Timeout for environment creation (seconds)"),
501
514
  ] = 7200,
502
515
  agents_dir: Annotated[
503
516
  Path | None,
504
- typer.Option("--agents-dir", "-a", help="Directory containing agent source code (builds local images)"),
517
+ typer.Option(
518
+ "--agents-dir",
519
+ "-a",
520
+ help="Directory containing agent source code (builds local images)",
521
+ ),
505
522
  ] = None,
506
523
  verbose: Annotated[bool, typer.Option("--verbose", "-v", help="Enable verbose logging")] = False,
507
524
  ) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plato-sdk-v2
3
- Version: 2.3.4
3
+ Version: 2.3.6
4
4
  Summary: Python SDK for the Plato API
5
5
  Author-email: Plato <support@plato.so>
6
6
  License-Expression: MIT
@@ -21,6 +21,9 @@ Requires-Dist: google-genai>=1.0.0
21
21
  Requires-Dist: httpx>=0.25.0
22
22
  Requires-Dist: jinja2>=3.1.0
23
23
  Requires-Dist: openapi-pydantic>=0.5.1
24
+ Requires-Dist: opentelemetry-api>=1.20.0
25
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0
26
+ Requires-Dist: opentelemetry-sdk>=1.20.0
24
27
  Requires-Dist: pydantic-settings>=2.12.0
25
28
  Requires-Dist: pydantic>=2.0.0
26
29
  Requires-Dist: python-dotenv>=1.2.1
@@ -45,7 +48,6 @@ Description-Content-Type: text/markdown
45
48
  # Plato Python SDK
46
49
 
47
50
 
48
-
49
51
  Python SDK for the Plato platform. Uses [Harbor](https://harborframework.com) for agent execution.
50
52
 
51
53
  ## Installation
@@ -297,12 +297,13 @@ plato/_sims_generator/templates/python/errors.py.jinja,sha256=8L_FbHczBNLXJrbSlN
297
297
  plato/_sims_generator/templates/python/package_init.py.jinja,sha256=sOcJxUT0LuOWu5jOMGGKYxfCEjcYQv1hGF3n0iOA4hQ,986
298
298
  plato/_sims_generator/templates/python/tag_init.py.jinja,sha256=WB_9cv0JKIVg5TOXeSolET3tAfVg7sExjboh5jbCXz4,170
299
299
  plato/_sims_generator/templates/python/version_init.py.jinja,sha256=sGvFcYVfzXFyQDAe0PSOrg9yys93KE0XInFQNb1TvCY,179
300
- plato/agents/__init__.py,sha256=1l-Vw5SFydmPsl1toXdc2oH3eLhFwz6jtI_DKUx4vmo,2847
300
+ plato/agents/__init__.py,sha256=Cxc-HUMwRGQ4D1hHnFo9vt2AV5upPRYP4e3y8X6Hzr0,3052
301
+ plato/agents/artifacts.py,sha256=ljeI0wzsp7Q6uKqMb-k7kTb680Vizs54ohtM-d7zvOg,2929
301
302
  plato/agents/base.py,sha256=vUbPQuNSo6Ka2lIB_ZOXgi4EoAjtAD7GIj9LnNotam0,4577
302
303
  plato/agents/build.py,sha256=CNMbVQFs2_pYit1dA29Davve28Yi4c7TNK9wBB7odrE,1621
303
- plato/agents/config.py,sha256=VZVMdCmEQnoR0VkrGdScG8p6zSKVFe7BZPd2h8lKNjI,5460
304
- plato/agents/logging.py,sha256=bL3Q14YeFxWCQydGKrQzQPgKQzBoCCXy_AAQPZpBylU,16307
305
- plato/agents/runner.py,sha256=UQWg3gpYhWLnGLB6Bs595qH7nZV-ch-u5fPlkltT_kc,6812
304
+ plato/agents/config.py,sha256=CmRS6vOAg7JeqX4Hgp_KpA1YWBX_LuMicHm7SBjQEbs,5077
305
+ plato/agents/otel.py,sha256=xhsqJrfD9s3tyiSyZPFkTPS0wma71v_TS5BbGiL6lmQ,8168
306
+ plato/agents/runner.py,sha256=1qOCYVgT6m4zsRM8f0JXOYIg6smCyI-cuGZgVVae7aM,16244
306
307
  plato/agents/trajectory.py,sha256=WdiBmua0KvCrNaM3qgPI7-7B4xmSkfbP4oZ_9_8qHzU,10529
307
308
  plato/chronos/__init__.py,sha256=RHMvSrQS_-vkKOyTRuAkp2gKDP1HEuBLDnw8jcZs1Jg,739
308
309
  plato/chronos/client.py,sha256=YcOGtHWERyOD9z8LKt8bRMVL0cEwL2hiAP4qQgdZlUI,5495
@@ -321,12 +322,6 @@ plato/chronos/api/auth/__init__.py,sha256=6qao3xT8yw9-WTpUlv4tVtpWhL2EycQd3I2WKQ
321
322
  plato/chronos/api/auth/debug_auth_api_auth_debug_get.py,sha256=L1RWyQ1w7V8dyhOAU2VQlT9x0jkeng3eIvZDOv9Gl2w,881
322
323
  plato/chronos/api/auth/get_auth_status_api_auth_status_get.py,sha256=i9JzH9vPeswvbWtBAkMikepbNAyNK8jpTcALU6ScG5s,1379
323
324
  plato/chronos/api/auth/get_current_user_route_api_auth_me_get.py,sha256=w9zz7ivQpYKvV6FPIEuNHfI5BOl9bu3FYbJ5ADEuTPc,1210
324
- plato/chronos/api/callback/__init__.py,sha256=KxC9frS5-0DzwOz4eympnoTvki7MslueKfRiZNdfSYg,264
325
- plato/chronos/api/callback/push_agent_logs.py,sha256=MWL9-2qzRXnrXdUQktCAaIKHAOo8z7vPdaMOqgrJ6vI,1611
326
- plato/chronos/api/callback/update_agent_status.py,sha256=I3N2T_670f030EvoNrX9koKQL78OjHoIRbUKaIXlktk,1323
327
- plato/chronos/api/callback/upload_artifacts.py,sha256=AUg4TxFSHG6hvvSR1HyOh18eOLNuW-mtjPxXVxrWPr4,1526
328
- plato/chronos/api/callback/upload_logs_zip.py,sha256=ZwB0zn23dMtfgXjkeraUG09b6OYZ2Nbfy_j0_LKndxY,1321
329
- plato/chronos/api/callback/upload_trajectory.py,sha256=-cEktjBjzfxyMipJrUFwzqW1BAiKVX3bJYEHk33D9CU,1421
330
325
  plato/chronos/api/default/__init__.py,sha256=TCF1Fl95ZyiR9-xHzf_R2A6TNb7k59N1VfSI5PAj4Pg,72
331
326
  plato/chronos/api/default/health.py,sha256=PvBLZXdYptL9d5_BEmzUsbUjQJTNGw5E4AFryPYiruw,781
332
327
  plato/chronos/api/jobs/__init__.py,sha256=JP76_irfuFV31HOgazh7Y81GSkcunJP_eYWX8Pqq1U0,80
@@ -461,13 +456,13 @@ plato/v2/utils/__init__.py,sha256=XLeFFsjXkm9g2raMmo7Wt4QN4hhCrNZDJKnpffJ4LtM,38
461
456
  plato/v2/utils/db_cleanup.py,sha256=lnI5lsMHNHpG85Y99MaE4Rzc3618piuzhvH-uXO1zIc,8702
462
457
  plato/v2/utils/models.py,sha256=PwehSSnIRG-tM3tWL1PzZEH77ZHhIAZ9R0UPs6YknbM,1441
463
458
  plato/v2/utils/proxy_tunnel.py,sha256=8ZTd0jCGSfIHMvSv1fgEyacuISWnGPHLPbDglWroTzY,10463
464
- plato/worlds/README.md,sha256=TgG4aidude0ouJSCfY81Ev45hsUxPkO85HUIiWNqkcc,5463
459
+ plato/worlds/README.md,sha256=XFOkEA3cNNcrWkk-Cxnsl-zn-y0kvUENKQRSqFKpdqw,5479
465
460
  plato/worlds/__init__.py,sha256=ALoou3l5lXvs_YZc5eH6HdMHpvhnpzKWqz__aSC1jFc,2152
466
- plato/worlds/base.py,sha256=KsDq1TVVd4BKEFo42WodF4DPgodr00Gd1NrfzZEPqyw,25632
461
+ plato/worlds/base.py,sha256=pYBuXn7zZ3n-ys4XkEVEUL1poq1lWTNH9qYbMzWRLfE,27694
467
462
  plato/worlds/build_hook.py,sha256=KSoW0kqa5b7NyZ7MYOw2qsZ_2FkWuz0M3Ru7AKOP7Qw,3486
468
- plato/worlds/config.py,sha256=fkWoetCawIPf5xgj5EyJCvopmPPzZQAqt0Ke9P4hq5c,10845
469
- plato/worlds/runner.py,sha256=gwTBuDPoiP3aGF4UgqNKHrfv1wohr0tsex0xlcuaw8c,18202
470
- plato_sdk_v2-2.3.4.dist-info/METADATA,sha256=k70jP_81ZXfk_e5_nZQNO8Huplz6Wm3JoazP2-loCmg,8510
471
- plato_sdk_v2-2.3.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
472
- plato_sdk_v2-2.3.4.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
473
- plato_sdk_v2-2.3.4.dist-info/RECORD,,
463
+ plato/worlds/config.py,sha256=a5frj3mt06rSlT25kE-L8Q2b2MTWkR-8cUoBKpC8tG4,11036
464
+ plato/worlds/runner.py,sha256=vrgKStT8fs3HuOGcPL5obZt-BLdLlQ0CVBUQZWyOOis,19023
465
+ plato_sdk_v2-2.3.6.dist-info/METADATA,sha256=mt3gSWRwTjcgKse_WxVlNF1_bRtZjdjzWiIdJJ2ecFU,8653
466
+ plato_sdk_v2-2.3.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
467
+ plato_sdk_v2-2.3.6.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
468
+ plato_sdk_v2-2.3.6.dist-info/RECORD,,