plato-sdk-v2 2.5.1__py3-none-any.whl → 2.6.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.
Files changed (52) hide show
  1. plato/_generated/__init__.py +1 -1
  2. plato/_generated/api/v1/evals/get_scores_by_user.py +7 -0
  3. plato/_generated/api/v1/testcases/get_testcases.py +14 -0
  4. plato/_generated/api/v2/sessions/setup_sandbox.py +2 -2
  5. plato/_generated/models/__init__.py +42 -2
  6. plato/agents/runner.py +2 -33
  7. plato/chronos/api/admin/__init__.py +17 -0
  8. plato/chronos/api/admin/clear_database_api_admin_clear_db_post.py +57 -0
  9. plato/chronos/api/admin/sync_agents_api_admin_sync_agents_post.py +67 -0
  10. plato/chronos/api/admin/sync_all_api_admin_sync_all_post.py +67 -0
  11. plato/chronos/api/admin/sync_runtimes_api_admin_sync_runtimes_post.py +67 -0
  12. plato/chronos/api/admin/sync_worlds_api_admin_sync_worlds_post.py +67 -0
  13. plato/chronos/api/agents/list_agents.py +5 -5
  14. plato/chronos/api/checkpoints/__init__.py +8 -0
  15. plato/chronos/api/checkpoints/list_checkpoints.py +52 -0
  16. plato/chronos/api/checkpoints/preview_checkpoint.py +74 -0
  17. plato/chronos/api/events/__init__.py +8 -0
  18. plato/chronos/api/events/get_session_event.py +68 -0
  19. plato/chronos/api/events/list_session_events.py +62 -0
  20. plato/chronos/api/jobs/launch_job.py +8 -2
  21. plato/chronos/api/otel/__init__.py +8 -0
  22. plato/chronos/api/otel/get_session_traces_api_otel_sessions__session_id__traces_get.py +56 -0
  23. plato/chronos/api/otel/receive_traces_api_otel_v1_traces_post.py +49 -0
  24. plato/chronos/api/registry/list_registry_agents_api_registry_agents_get.py +5 -5
  25. plato/chronos/api/runtimes/__init__.py +2 -1
  26. plato/chronos/api/runtimes/get_runtime_logs.py +61 -0
  27. plato/chronos/api/sessions/__init__.py +24 -1
  28. plato/chronos/api/sessions/close_session.py +66 -0
  29. plato/chronos/api/sessions/complete_session.py +74 -0
  30. plato/chronos/api/sessions/create_session.py +69 -0
  31. plato/chronos/api/sessions/get_session.py +20 -2
  32. plato/chronos/api/sessions/get_session_bash_logs_download.py +61 -0
  33. plato/chronos/api/sessions/get_session_envs.py +62 -0
  34. plato/chronos/api/sessions/get_session_live_logs.py +62 -0
  35. plato/chronos/api/sessions/get_session_logs.py +3 -3
  36. plato/chronos/api/sessions/get_session_status.py +62 -0
  37. plato/chronos/api/sessions/list_sessions.py +20 -2
  38. plato/chronos/api/sessions/list_tags.py +80 -0
  39. plato/chronos/api/sessions/update_session_tags.py +68 -0
  40. plato/chronos/models/__init__.py +241 -196
  41. plato/v1/cli/chronos.py +66 -4
  42. plato/v2/__init__.py +8 -0
  43. plato/v2/async_/__init__.py +4 -0
  44. plato/v2/async_/chronos.py +419 -0
  45. plato/v2/sync/__init__.py +3 -0
  46. plato/v2/sync/chronos.py +419 -0
  47. plato/worlds/base.py +3 -3
  48. plato/worlds/config.py +3 -7
  49. {plato_sdk_v2-2.5.1.dist-info → plato_sdk_v2-2.6.1.dist-info}/METADATA +1 -1
  50. {plato_sdk_v2-2.5.1.dist-info → plato_sdk_v2-2.6.1.dist-info}/RECORD +52 -25
  51. {plato_sdk_v2-2.5.1.dist-info → plato_sdk_v2-2.6.1.dist-info}/WHEEL +0 -0
  52. {plato_sdk_v2-2.5.1.dist-info → plato_sdk_v2-2.6.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,69 @@
1
+ """Create Session"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato.chronos.errors import raise_for_status
10
+ from plato.chronos.models import CreateSessionRequest, CreateSessionResponse
11
+
12
+
13
+ def _build_request_args(
14
+ body: CreateSessionRequest,
15
+ x_api_key: str | None = None,
16
+ ) -> dict[str, Any]:
17
+ """Build request arguments."""
18
+ url = "/api/sessions"
19
+
20
+ headers: dict[str, str] = {}
21
+ if x_api_key is not None:
22
+ headers["X-API-Key"] = x_api_key
23
+
24
+ return {
25
+ "method": "POST",
26
+ "url": url,
27
+ "json": body.model_dump(mode="json", exclude_none=True),
28
+ "headers": headers,
29
+ }
30
+
31
+
32
+ def sync(
33
+ client: httpx.Client,
34
+ body: CreateSessionRequest,
35
+ x_api_key: str | None = None,
36
+ ) -> CreateSessionResponse:
37
+ """Create a new session for dev/testing.
38
+
39
+ This creates a chronos session record that can receive OTel traces.
40
+ Used by plato-world-runner dev mode to get a real session in chronos."""
41
+
42
+ request_args = _build_request_args(
43
+ body=body,
44
+ x_api_key=x_api_key,
45
+ )
46
+
47
+ response = client.request(**request_args)
48
+ raise_for_status(response)
49
+ return CreateSessionResponse.model_validate(response.json())
50
+
51
+
52
+ async def asyncio(
53
+ client: httpx.AsyncClient,
54
+ body: CreateSessionRequest,
55
+ x_api_key: str | None = None,
56
+ ) -> CreateSessionResponse:
57
+ """Create a new session for dev/testing.
58
+
59
+ This creates a chronos session record that can receive OTel traces.
60
+ Used by plato-world-runner dev mode to get a real session in chronos."""
61
+
62
+ request_args = _build_request_args(
63
+ body=body,
64
+ x_api_key=x_api_key,
65
+ )
66
+
67
+ response = await client.request(**request_args)
68
+ raise_for_status(response)
69
+ return CreateSessionResponse.model_validate(response.json())
@@ -12,11 +12,16 @@ from plato.chronos.models import SessionResponse
12
12
 
13
13
  def _build_request_args(
14
14
  public_id: str,
15
+ reveal_secrets: bool | None = False,
15
16
  x_api_key: str | None = None,
16
17
  ) -> dict[str, Any]:
17
18
  """Build request arguments."""
18
19
  url = f"/api/sessions/{public_id}"
19
20
 
21
+ params: dict[str, Any] = {}
22
+ if reveal_secrets is not None:
23
+ params["reveal_secrets"] = reveal_secrets
24
+
20
25
  headers: dict[str, str] = {}
21
26
  if x_api_key is not None:
22
27
  headers["X-API-Key"] = x_api_key
@@ -24,6 +29,7 @@ def _build_request_args(
24
29
  return {
25
30
  "method": "GET",
26
31
  "url": url,
32
+ "params": params,
27
33
  "headers": headers,
28
34
  }
29
35
 
@@ -31,12 +37,18 @@ def _build_request_args(
31
37
  def sync(
32
38
  client: httpx.Client,
33
39
  public_id: str,
40
+ reveal_secrets: bool | None = False,
34
41
  x_api_key: str | None = None,
35
42
  ) -> SessionResponse:
36
- """Get a session by public ID."""
43
+ """Get a session by public ID.
44
+
45
+ Args:
46
+ public_id: Session public ID
47
+ reveal_secrets: If true, decrypt and return actual secret values"""
37
48
 
38
49
  request_args = _build_request_args(
39
50
  public_id=public_id,
51
+ reveal_secrets=reveal_secrets,
40
52
  x_api_key=x_api_key,
41
53
  )
42
54
 
@@ -48,12 +60,18 @@ def sync(
48
60
  async def asyncio(
49
61
  client: httpx.AsyncClient,
50
62
  public_id: str,
63
+ reveal_secrets: bool | None = False,
51
64
  x_api_key: str | None = None,
52
65
  ) -> SessionResponse:
53
- """Get a session by public ID."""
66
+ """Get a session by public ID.
67
+
68
+ Args:
69
+ public_id: Session public ID
70
+ reveal_secrets: If true, decrypt and return actual secret values"""
54
71
 
55
72
  request_args = _build_request_args(
56
73
  public_id=public_id,
74
+ reveal_secrets=reveal_secrets,
57
75
  x_api_key=x_api_key,
58
76
  )
59
77
 
@@ -0,0 +1,61 @@
1
+ """Get Session Bash Logs Download"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato.chronos.errors import raise_for_status
10
+
11
+
12
+ def _build_request_args(
13
+ public_id: str,
14
+ x_api_key: str | None = None,
15
+ ) -> dict[str, Any]:
16
+ """Build request arguments."""
17
+ url = f"/api/sessions/{public_id}/bash-logs-download"
18
+
19
+ headers: dict[str, str] = {}
20
+ if x_api_key is not None:
21
+ headers["X-API-Key"] = x_api_key
22
+
23
+ return {
24
+ "method": "GET",
25
+ "url": url,
26
+ "headers": headers,
27
+ }
28
+
29
+
30
+ def sync(
31
+ client: httpx.Client,
32
+ public_id: str,
33
+ x_api_key: str | None = None,
34
+ ) -> Any:
35
+ """Download the session's bash/execution logs directly."""
36
+
37
+ request_args = _build_request_args(
38
+ public_id=public_id,
39
+ x_api_key=x_api_key,
40
+ )
41
+
42
+ response = client.request(**request_args)
43
+ raise_for_status(response)
44
+ return response.json()
45
+
46
+
47
+ async def asyncio(
48
+ client: httpx.AsyncClient,
49
+ public_id: str,
50
+ x_api_key: str | None = None,
51
+ ) -> Any:
52
+ """Download the session's bash/execution logs directly."""
53
+
54
+ request_args = _build_request_args(
55
+ public_id=public_id,
56
+ x_api_key=x_api_key,
57
+ )
58
+
59
+ response = await client.request(**request_args)
60
+ raise_for_status(response)
61
+ return response.json()
@@ -0,0 +1,62 @@
1
+ """Get Session Envs"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato.chronos.errors import raise_for_status
10
+ from plato.chronos.models import SessionEnvsResponse
11
+
12
+
13
+ def _build_request_args(
14
+ public_id: str,
15
+ x_api_key: str | None = None,
16
+ ) -> dict[str, Any]:
17
+ """Build request arguments."""
18
+ url = f"/api/sessions/{public_id}/envs"
19
+
20
+ headers: dict[str, str] = {}
21
+ if x_api_key is not None:
22
+ headers["X-API-Key"] = x_api_key
23
+
24
+ return {
25
+ "method": "GET",
26
+ "url": url,
27
+ "headers": headers,
28
+ }
29
+
30
+
31
+ def sync(
32
+ client: httpx.Client,
33
+ public_id: str,
34
+ x_api_key: str | None = None,
35
+ ) -> SessionEnvsResponse:
36
+ """Get env info (job IDs, aliases) from Plato for a session."""
37
+
38
+ request_args = _build_request_args(
39
+ public_id=public_id,
40
+ x_api_key=x_api_key,
41
+ )
42
+
43
+ response = client.request(**request_args)
44
+ raise_for_status(response)
45
+ return SessionEnvsResponse.model_validate(response.json())
46
+
47
+
48
+ async def asyncio(
49
+ client: httpx.AsyncClient,
50
+ public_id: str,
51
+ x_api_key: str | None = None,
52
+ ) -> SessionEnvsResponse:
53
+ """Get env info (job IDs, aliases) from Plato for a session."""
54
+
55
+ request_args = _build_request_args(
56
+ public_id=public_id,
57
+ x_api_key=x_api_key,
58
+ )
59
+
60
+ response = await client.request(**request_args)
61
+ raise_for_status(response)
62
+ return SessionEnvsResponse.model_validate(response.json())
@@ -0,0 +1,62 @@
1
+ """Get Session Live Logs"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato.chronos.errors import raise_for_status
10
+ from plato.chronos.models import LiveLogsResponse
11
+
12
+
13
+ def _build_request_args(
14
+ public_id: str,
15
+ x_api_key: str | None = None,
16
+ ) -> dict[str, Any]:
17
+ """Build request arguments."""
18
+ url = f"/api/sessions/{public_id}/live-logs"
19
+
20
+ headers: dict[str, str] = {}
21
+ if x_api_key is not None:
22
+ headers["X-API-Key"] = x_api_key
23
+
24
+ return {
25
+ "method": "GET",
26
+ "url": url,
27
+ "headers": headers,
28
+ }
29
+
30
+
31
+ def sync(
32
+ client: httpx.Client,
33
+ public_id: str,
34
+ x_api_key: str | None = None,
35
+ ) -> LiveLogsResponse:
36
+ """Get live execution logs from the VM via SSH."""
37
+
38
+ request_args = _build_request_args(
39
+ public_id=public_id,
40
+ x_api_key=x_api_key,
41
+ )
42
+
43
+ response = client.request(**request_args)
44
+ raise_for_status(response)
45
+ return LiveLogsResponse.model_validate(response.json())
46
+
47
+
48
+ async def asyncio(
49
+ client: httpx.AsyncClient,
50
+ public_id: str,
51
+ x_api_key: str | None = None,
52
+ ) -> LiveLogsResponse:
53
+ """Get live execution logs from the VM via SSH."""
54
+
55
+ request_args = _build_request_args(
56
+ public_id=public_id,
57
+ x_api_key=x_api_key,
58
+ )
59
+
60
+ response = await client.request(**request_args)
61
+ raise_for_status(response)
62
+ return LiveLogsResponse.model_validate(response.json())
@@ -12,7 +12,7 @@ from plato.chronos.models import SessionLogsResponse
12
12
 
13
13
  def _build_request_args(
14
14
  public_id: str,
15
- limit: int | None = 100,
15
+ limit: int | None = 10000,
16
16
  x_api_key: str | None = None,
17
17
  ) -> dict[str, Any]:
18
18
  """Build request arguments."""
@@ -37,7 +37,7 @@ def _build_request_args(
37
37
  def sync(
38
38
  client: httpx.Client,
39
39
  public_id: str,
40
- limit: int | None = 100,
40
+ limit: int | None = 10000,
41
41
  x_api_key: str | None = None,
42
42
  ) -> SessionLogsResponse:
43
43
  """Get logs/events for a session."""
@@ -56,7 +56,7 @@ def sync(
56
56
  async def asyncio(
57
57
  client: httpx.AsyncClient,
58
58
  public_id: str,
59
- limit: int | None = 100,
59
+ limit: int | None = 10000,
60
60
  x_api_key: str | None = None,
61
61
  ) -> SessionLogsResponse:
62
62
  """Get logs/events for a session."""
@@ -0,0 +1,62 @@
1
+ """Get Session Status"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato.chronos.errors import raise_for_status
10
+ from plato.chronos.models import SessionStatusResponse
11
+
12
+
13
+ def _build_request_args(
14
+ public_id: str,
15
+ x_api_key: str | None = None,
16
+ ) -> dict[str, Any]:
17
+ """Build request arguments."""
18
+ url = f"/api/sessions/{public_id}/status"
19
+
20
+ headers: dict[str, str] = {}
21
+ if x_api_key is not None:
22
+ headers["X-API-Key"] = x_api_key
23
+
24
+ return {
25
+ "method": "GET",
26
+ "url": url,
27
+ "headers": headers,
28
+ }
29
+
30
+
31
+ def sync(
32
+ client: httpx.Client,
33
+ public_id: str,
34
+ x_api_key: str | None = None,
35
+ ) -> SessionStatusResponse:
36
+ """Get just the status of a session (lightweight endpoint)."""
37
+
38
+ request_args = _build_request_args(
39
+ public_id=public_id,
40
+ x_api_key=x_api_key,
41
+ )
42
+
43
+ response = client.request(**request_args)
44
+ raise_for_status(response)
45
+ return SessionStatusResponse.model_validate(response.json())
46
+
47
+
48
+ async def asyncio(
49
+ client: httpx.AsyncClient,
50
+ public_id: str,
51
+ x_api_key: str | None = None,
52
+ ) -> SessionStatusResponse:
53
+ """Get just the status of a session (lightweight endpoint)."""
54
+
55
+ request_args = _build_request_args(
56
+ public_id=public_id,
57
+ x_api_key=x_api_key,
58
+ )
59
+
60
+ response = await client.request(**request_args)
61
+ raise_for_status(response)
62
+ return SessionStatusResponse.model_validate(response.json())
@@ -11,11 +11,16 @@ from plato.chronos.models import SessionListResponse
11
11
 
12
12
 
13
13
  def _build_request_args(
14
+ tag: str | None = None,
14
15
  x_api_key: str | None = None,
15
16
  ) -> dict[str, Any]:
16
17
  """Build request arguments."""
17
18
  url = "/api/sessions"
18
19
 
20
+ params: dict[str, Any] = {}
21
+ if tag is not None:
22
+ params["tag"] = tag
23
+
19
24
  headers: dict[str, str] = {}
20
25
  if x_api_key is not None:
21
26
  headers["X-API-Key"] = x_api_key
@@ -23,17 +28,24 @@ def _build_request_args(
23
28
  return {
24
29
  "method": "GET",
25
30
  "url": url,
31
+ "params": params,
26
32
  "headers": headers,
27
33
  }
28
34
 
29
35
 
30
36
  def sync(
31
37
  client: httpx.Client,
38
+ tag: str | None = None,
32
39
  x_api_key: str | None = None,
33
40
  ) -> SessionListResponse:
34
- """List all sessions for the org."""
41
+ """List all sessions for the org, optionally filtered by tag.
42
+
43
+ Tag filtering uses ltree for hierarchical matching:
44
+ - 'project' matches 'project', 'project.foo', 'project.foo.bar'
45
+ - 'project.foo' matches 'project.foo', 'project.foo.bar'"""
35
46
 
36
47
  request_args = _build_request_args(
48
+ tag=tag,
37
49
  x_api_key=x_api_key,
38
50
  )
39
51
 
@@ -44,11 +56,17 @@ def sync(
44
56
 
45
57
  async def asyncio(
46
58
  client: httpx.AsyncClient,
59
+ tag: str | None = None,
47
60
  x_api_key: str | None = None,
48
61
  ) -> SessionListResponse:
49
- """List all sessions for the org."""
62
+ """List all sessions for the org, optionally filtered by tag.
63
+
64
+ Tag filtering uses ltree for hierarchical matching:
65
+ - 'project' matches 'project', 'project.foo', 'project.foo.bar'
66
+ - 'project.foo' matches 'project.foo', 'project.foo.bar'"""
50
67
 
51
68
  request_args = _build_request_args(
69
+ tag=tag,
52
70
  x_api_key=x_api_key,
53
71
  )
54
72
 
@@ -0,0 +1,80 @@
1
+ """List Tags"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato.chronos.errors import raise_for_status
10
+ from plato.chronos.models import TagsListResponse
11
+
12
+
13
+ def _build_request_args(
14
+ q: str | None = None,
15
+ limit: int | None = 10,
16
+ x_api_key: str | None = None,
17
+ ) -> dict[str, Any]:
18
+ """Build request arguments."""
19
+ url = "/api/sessions/tags"
20
+
21
+ params: dict[str, Any] = {}
22
+ if q is not None:
23
+ params["q"] = q
24
+ if limit is not None:
25
+ params["limit"] = limit
26
+
27
+ headers: dict[str, str] = {}
28
+ if x_api_key is not None:
29
+ headers["X-API-Key"] = x_api_key
30
+
31
+ return {
32
+ "method": "GET",
33
+ "url": url,
34
+ "params": params,
35
+ "headers": headers,
36
+ }
37
+
38
+
39
+ def sync(
40
+ client: httpx.Client,
41
+ q: str | None = None,
42
+ limit: int | None = 10,
43
+ x_api_key: str | None = None,
44
+ ) -> TagsListResponse:
45
+ """Search unique tags for the org with ltree hierarchical matching.
46
+
47
+ Uses ltree for hierarchical tags with '.' separator.
48
+ Search matches tags containing the query as a substring or ancestor/descendant."""
49
+
50
+ request_args = _build_request_args(
51
+ q=q,
52
+ limit=limit,
53
+ x_api_key=x_api_key,
54
+ )
55
+
56
+ response = client.request(**request_args)
57
+ raise_for_status(response)
58
+ return TagsListResponse.model_validate(response.json())
59
+
60
+
61
+ async def asyncio(
62
+ client: httpx.AsyncClient,
63
+ q: str | None = None,
64
+ limit: int | None = 10,
65
+ x_api_key: str | None = None,
66
+ ) -> TagsListResponse:
67
+ """Search unique tags for the org with ltree hierarchical matching.
68
+
69
+ Uses ltree for hierarchical tags with '.' separator.
70
+ Search matches tags containing the query as a substring or ancestor/descendant."""
71
+
72
+ request_args = _build_request_args(
73
+ q=q,
74
+ limit=limit,
75
+ x_api_key=x_api_key,
76
+ )
77
+
78
+ response = await client.request(**request_args)
79
+ raise_for_status(response)
80
+ return TagsListResponse.model_validate(response.json())
@@ -0,0 +1,68 @@
1
+ """Update Session Tags"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato.chronos.errors import raise_for_status
10
+ from plato.chronos.models import SessionResponse, UpdateTagsRequest
11
+
12
+
13
+ def _build_request_args(
14
+ public_id: str,
15
+ body: UpdateTagsRequest,
16
+ x_api_key: str | None = None,
17
+ ) -> dict[str, Any]:
18
+ """Build request arguments."""
19
+ url = f"/api/sessions/{public_id}/tags"
20
+
21
+ headers: dict[str, str] = {}
22
+ if x_api_key is not None:
23
+ headers["X-API-Key"] = x_api_key
24
+
25
+ return {
26
+ "method": "PATCH",
27
+ "url": url,
28
+ "json": body.model_dump(mode="json", exclude_none=True),
29
+ "headers": headers,
30
+ }
31
+
32
+
33
+ def sync(
34
+ client: httpx.Client,
35
+ public_id: str,
36
+ body: UpdateTagsRequest,
37
+ x_api_key: str | None = None,
38
+ ) -> SessionResponse:
39
+ """Update tags for a session."""
40
+
41
+ request_args = _build_request_args(
42
+ public_id=public_id,
43
+ body=body,
44
+ x_api_key=x_api_key,
45
+ )
46
+
47
+ response = client.request(**request_args)
48
+ raise_for_status(response)
49
+ return SessionResponse.model_validate(response.json())
50
+
51
+
52
+ async def asyncio(
53
+ client: httpx.AsyncClient,
54
+ public_id: str,
55
+ body: UpdateTagsRequest,
56
+ x_api_key: str | None = None,
57
+ ) -> SessionResponse:
58
+ """Update tags for a session."""
59
+
60
+ request_args = _build_request_args(
61
+ public_id=public_id,
62
+ body=body,
63
+ x_api_key=x_api_key,
64
+ )
65
+
66
+ response = await client.request(**request_args)
67
+ raise_for_status(response)
68
+ return SessionResponse.model_validate(response.json())