plato-sdk-v2 2.6.2__py3-none-any.whl → 2.7.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 (32) hide show
  1. plato/_generated/__init__.py +1 -1
  2. plato/_generated/api/v2/__init__.py +2 -1
  3. plato/_generated/api/v2/networks/__init__.py +23 -0
  4. plato/_generated/api/v2/networks/add_member.py +75 -0
  5. plato/_generated/api/v2/networks/create_network.py +70 -0
  6. plato/_generated/api/v2/networks/delete_network.py +68 -0
  7. plato/_generated/api/v2/networks/get_network.py +69 -0
  8. plato/_generated/api/v2/networks/list_members.py +69 -0
  9. plato/_generated/api/v2/networks/list_networks.py +74 -0
  10. plato/_generated/api/v2/networks/remove_member.py +73 -0
  11. plato/_generated/api/v2/networks/update_member.py +80 -0
  12. plato/_generated/api/v2/sessions/__init__.py +4 -0
  13. plato/_generated/api/v2/sessions/add_ssh_key.py +81 -0
  14. plato/_generated/api/v2/sessions/connect_network.py +89 -0
  15. plato/_generated/models/__init__.py +145 -24
  16. plato/v1/cli/agent.py +45 -52
  17. plato/v1/cli/chronos.py +46 -58
  18. plato/v1/cli/main.py +14 -25
  19. plato/v1/cli/pm.py +129 -98
  20. plato/v1/cli/proxy.py +343 -0
  21. plato/v1/cli/sandbox.py +421 -425
  22. plato/v1/cli/ssh.py +12 -167
  23. plato/v1/cli/verify.py +79 -55
  24. plato/v1/cli/world.py +13 -12
  25. plato/v2/async_/client.py +24 -2
  26. plato/v2/async_/session.py +48 -0
  27. plato/v2/sync/client.py +24 -2
  28. plato/v2/sync/session.py +48 -0
  29. {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/METADATA +1 -1
  30. {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/RECORD +32 -20
  31. {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/WHEEL +0 -0
  32. {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,81 @@
1
+ """Add Ssh Key"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato._generated.errors import raise_for_status
10
+ from plato._generated.models import AddSSHKeyRequest, AddSSHKeyResponse
11
+
12
+
13
+ def _build_request_args(
14
+ session_id: str,
15
+ body: AddSSHKeyRequest,
16
+ authorization: str | None = None,
17
+ x_api_key: str | None = None,
18
+ ) -> dict[str, Any]:
19
+ """Build request arguments."""
20
+ url = f"/api/v2/sessions/{session_id}/add_ssh_key"
21
+
22
+ headers: dict[str, str] = {}
23
+ if authorization is not None:
24
+ headers["authorization"] = authorization
25
+ if x_api_key is not None:
26
+ headers["X-API-Key"] = x_api_key
27
+
28
+ return {
29
+ "method": "POST",
30
+ "url": url,
31
+ "json": body.model_dump(mode="json", exclude_none=True),
32
+ "headers": headers,
33
+ }
34
+
35
+
36
+ def sync(
37
+ client: httpx.Client,
38
+ session_id: str,
39
+ body: AddSSHKeyRequest,
40
+ authorization: str | None = None,
41
+ x_api_key: str | None = None,
42
+ ) -> AddSSHKeyResponse:
43
+ """Add an SSH public key to all VMs in a session.
44
+
45
+ This allows the user to SSH into VMs using their own key pair.
46
+ The key is added to the specified user's authorized_keys file."""
47
+
48
+ request_args = _build_request_args(
49
+ session_id=session_id,
50
+ body=body,
51
+ authorization=authorization,
52
+ x_api_key=x_api_key,
53
+ )
54
+
55
+ response = client.request(**request_args)
56
+ raise_for_status(response)
57
+ return AddSSHKeyResponse.model_validate(response.json())
58
+
59
+
60
+ async def asyncio(
61
+ client: httpx.AsyncClient,
62
+ session_id: str,
63
+ body: AddSSHKeyRequest,
64
+ authorization: str | None = None,
65
+ x_api_key: str | None = None,
66
+ ) -> AddSSHKeyResponse:
67
+ """Add an SSH public key to all VMs in a session.
68
+
69
+ This allows the user to SSH into VMs using their own key pair.
70
+ The key is added to the specified user's authorized_keys file."""
71
+
72
+ request_args = _build_request_args(
73
+ session_id=session_id,
74
+ body=body,
75
+ authorization=authorization,
76
+ x_api_key=x_api_key,
77
+ )
78
+
79
+ response = await client.request(**request_args)
80
+ raise_for_status(response)
81
+ return AddSSHKeyResponse.model_validate(response.json())
@@ -0,0 +1,89 @@
1
+ """Connect Network"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+ from plato._generated.errors import raise_for_status
10
+ from plato._generated.models import ConnectNetworkRequest
11
+
12
+
13
+ def _build_request_args(
14
+ session_id: str,
15
+ body: ConnectNetworkRequest,
16
+ authorization: str | None = None,
17
+ x_api_key: str | None = None,
18
+ ) -> dict[str, Any]:
19
+ """Build request arguments."""
20
+ url = f"/api/v2/sessions/{session_id}/connect_network"
21
+
22
+ headers: dict[str, str] = {}
23
+ if authorization is not None:
24
+ headers["authorization"] = authorization
25
+ if x_api_key is not None:
26
+ headers["X-API-Key"] = x_api_key
27
+
28
+ return {
29
+ "method": "POST",
30
+ "url": url,
31
+ "json": body.model_dump(mode="json", exclude_none=True),
32
+ "headers": headers,
33
+ }
34
+
35
+
36
+ def sync(
37
+ client: httpx.Client,
38
+ session_id: str,
39
+ body: ConnectNetworkRequest,
40
+ authorization: str | None = None,
41
+ x_api_key: str | None = None,
42
+ ) -> dict[str, Any]:
43
+ """Connect all jobs in a session to a WireGuard network.
44
+
45
+ Must be called after all jobs are ready (have worker assignments).
46
+ Pre-generates WireGuard keys and configures full mesh networking.
47
+
48
+ Args:
49
+ host_only: If True, force WireGuard to run on worker instead of in VM.
50
+ Useful for VMs without WireGuard tools or for testing."""
51
+
52
+ request_args = _build_request_args(
53
+ session_id=session_id,
54
+ body=body,
55
+ authorization=authorization,
56
+ x_api_key=x_api_key,
57
+ )
58
+
59
+ response = client.request(**request_args)
60
+ raise_for_status(response)
61
+ return response.json()
62
+
63
+
64
+ async def asyncio(
65
+ client: httpx.AsyncClient,
66
+ session_id: str,
67
+ body: ConnectNetworkRequest,
68
+ authorization: str | None = None,
69
+ x_api_key: str | None = None,
70
+ ) -> dict[str, Any]:
71
+ """Connect all jobs in a session to a WireGuard network.
72
+
73
+ Must be called after all jobs are ready (have worker assignments).
74
+ Pre-generates WireGuard keys and configures full mesh networking.
75
+
76
+ Args:
77
+ host_only: If True, force WireGuard to run on worker instead of in VM.
78
+ Useful for VMs without WireGuard tools or for testing."""
79
+
80
+ request_args = _build_request_args(
81
+ session_id=session_id,
82
+ body=body,
83
+ authorization=authorization,
84
+ x_api_key=x_api_key,
85
+ )
86
+
87
+ response = await client.request(**request_args)
88
+ raise_for_status(response)
89
+ return response.json()
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: tmpwzer8yl7.json
3
- # timestamp: 2026-01-26T01:31:41+00:00
2
+ # filename: tmph5p8qjzo.json
3
+ # timestamp: 2026-01-28T09:03:29+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -18,6 +18,14 @@ class ActiveSessionResponse(BaseModel):
18
18
  status: Annotated[str | None, Field(title="Status")] = None
19
19
 
20
20
 
21
+ class AddMemberRequest(BaseModel):
22
+ model_config = ConfigDict(
23
+ extra="allow",
24
+ )
25
+ job_id: Annotated[str, Field(title="Job Id")]
26
+ alias: Annotated[str | None, Field(title="Alias")] = None
27
+
28
+
21
29
  class ReviewType(Enum):
22
30
  env = "env"
23
31
  data = "data"
@@ -40,6 +48,38 @@ class AddReviewRequest(BaseModel):
40
48
  comments: Annotated[str | None, Field(title="Comments")] = None
41
49
 
42
50
 
51
+ class AddSSHKeyRequest(BaseModel):
52
+ model_config = ConfigDict(
53
+ extra="allow",
54
+ )
55
+ public_key: Annotated[str, Field(title="Public Key")]
56
+ """
57
+ SSH public key in OpenSSH format
58
+ """
59
+ username: Annotated[str | None, Field(title="Username")] = "root"
60
+ """
61
+ Username to add the key for (default: root)
62
+ """
63
+
64
+
65
+ class AddSSHKeyResult(BaseModel):
66
+ model_config = ConfigDict(
67
+ extra="allow",
68
+ )
69
+ success: Annotated[bool, Field(title="Success")]
70
+ """
71
+ Whether the key was added successfully
72
+ """
73
+ error: Annotated[str | None, Field(title="Error")] = None
74
+ """
75
+ Error message if the operation failed
76
+ """
77
+ output: Annotated[str | None, Field(title="Output")] = None
78
+ """
79
+ Command output (stdout)
80
+ """
81
+
82
+
43
83
  class AgentInfo(BaseModel):
44
84
  model_config = ConfigDict(
45
85
  extra="allow",
@@ -590,6 +630,13 @@ class CloseSessionResponse(BaseModel):
590
630
  """
591
631
 
592
632
 
633
+ class ConnectNetworkRequest(BaseModel):
634
+ model_config = ConfigDict(
635
+ extra="allow",
636
+ )
637
+ host_only: Annotated[bool | None, Field(title="Host Only")] = False
638
+
639
+
593
640
  class ConnectRoutingInfoResult(BaseModel):
594
641
  model_config = ConfigDict(
595
642
  extra="allow",
@@ -794,6 +841,25 @@ class CreateEnvRequest(BaseModel):
794
841
  timeout: Annotated[int | None, Field(title="Timeout")] = 1800
795
842
 
796
843
 
844
+ class CreateNetworkRequest(BaseModel):
845
+ model_config = ConfigDict(
846
+ extra="allow",
847
+ )
848
+ session_id: Annotated[str, Field(title="Session Id")]
849
+ name: Annotated[str | None, Field(title="Name")] = None
850
+
851
+
852
+ class CreateNetworkResponse(BaseModel):
853
+ model_config = ConfigDict(
854
+ extra="allow",
855
+ )
856
+ session_id: Annotated[str, Field(title="Session Id")]
857
+ name: Annotated[str | None, Field(title="Name")] = None
858
+ subnet: Annotated[str, Field(title="Subnet")]
859
+ dns_suffix: Annotated[str, Field(title="Dns Suffix")]
860
+ status: Annotated[str, Field(title="Status")]
861
+
862
+
797
863
  class CreateOrgApiKeyRequest(BaseModel):
798
864
  model_config = ConfigDict(
799
865
  extra="allow",
@@ -1536,6 +1602,10 @@ class JobInfo(BaseModel):
1536
1602
  """
1537
1603
  Job status
1538
1604
  """
1605
+ status_reason: Annotated[str | None, Field(title="Status Reason")] = None
1606
+ """
1607
+ Job status reason
1608
+ """
1539
1609
 
1540
1610
 
1541
1611
  class JobInfoResponse(BaseModel):
@@ -1686,6 +1756,31 @@ class NavigateStep(BaseModel):
1686
1756
  """
1687
1757
 
1688
1758
 
1759
+ class NetworkMemberResponse(BaseModel):
1760
+ model_config = ConfigDict(
1761
+ extra="allow",
1762
+ )
1763
+ job_id: Annotated[str, Field(title="Job Id")]
1764
+ alias: Annotated[str | None, Field(title="Alias")] = None
1765
+ dns_name: Annotated[str | None, Field(title="Dns Name")] = None
1766
+ wireguard_ip: Annotated[str | None, Field(title="Wireguard Ip")] = None
1767
+ status: Annotated[str, Field(title="Status")]
1768
+ joined_at: Annotated[str | None, Field(title="Joined At")] = None
1769
+
1770
+
1771
+ class NetworkResponse(BaseModel):
1772
+ model_config = ConfigDict(
1773
+ extra="allow",
1774
+ )
1775
+ session_id: Annotated[str, Field(title="Session Id")]
1776
+ name: Annotated[str | None, Field(title="Name")] = None
1777
+ subnet: Annotated[str, Field(title="Subnet")]
1778
+ dns_suffix: Annotated[str, Field(title="Dns Suffix")]
1779
+ status: Annotated[str, Field(title="Status")]
1780
+ member_count: Annotated[int, Field(title="Member Count")]
1781
+ created_at: Annotated[str | None, Field(title="Created At")] = None
1782
+
1783
+
1689
1784
  class NodeBuildConfig(BaseModel):
1690
1785
  model_config = ConfigDict(
1691
1786
  extra="allow",
@@ -1698,13 +1793,11 @@ class NodeBuildConfig(BaseModel):
1698
1793
  """
1699
1794
  SSH public key for VM access. Derived from private key if not set.
1700
1795
  """
1701
- ecr_enabled: Annotated[bool | None, Field(title="Ecr Enabled")] = True
1702
- """
1703
- Whether to use ECR for base images. Disable for local builds.
1704
- """
1705
- default_image: Annotated[str | None, Field(title="Default Image")] = "plato-ubuntu-22.04"
1796
+ default_image: Annotated[str | None, Field(title="Default Image")] = (
1797
+ "383806609161.dkr.ecr.us-west-1.amazonaws.com/vm/rootfs/plato-ubuntu-22.04:1.1.0"
1798
+ )
1706
1799
  """
1707
- Default base image name for VM builds (e.g., 'plato-ubuntu-22.04', 'dind').
1800
+ Default VM image URL with tag (e.g., 'ecr-url/repo:tag').
1708
1801
  """
1709
1802
 
1710
1803
 
@@ -1726,20 +1819,6 @@ class NodeNatsConfig(BaseModel):
1726
1819
  subject_prefix: Annotated[str | None, Field(title="Subject Prefix")] = "firecracker"
1727
1820
 
1728
1821
 
1729
- class NodeNebulaConfig(BaseModel):
1730
- model_config = ConfigDict(
1731
- extra="allow",
1732
- )
1733
- lighthouse_upstream: Annotated[str | None, Field(title="Lighthouse Upstream")] = "100.64.1.1:4242"
1734
- """
1735
- Nebula lighthouse upstream address (host:port) for mesh connectivity.
1736
- """
1737
- lighthouse_ip: Annotated[str | None, Field(title="Lighthouse Ip")] = "100.64.1.1"
1738
- """
1739
- Nebula lighthouse mesh IP address.
1740
- """
1741
-
1742
-
1743
1822
  class NodePolicyConfig(BaseModel):
1744
1823
  model_config = ConfigDict(
1745
1824
  extra="allow",
@@ -1798,6 +1877,16 @@ class NodeS3Config(BaseModel):
1798
1877
  """
1799
1878
 
1800
1879
 
1880
+ class NodeSessionNetworkConfig(BaseModel):
1881
+ model_config = ConfigDict(
1882
+ extra="allow",
1883
+ )
1884
+ enabled: Annotated[bool | None, Field(title="Enabled")] = False
1885
+ """
1886
+ Enable session networking (WireGuard-based VM-to-VM communication).
1887
+ """
1888
+
1889
+
1801
1890
  class NodeSnapshotStoreConfig(BaseModel):
1802
1891
  model_config = ConfigDict(
1803
1892
  extra="allow",
@@ -1846,6 +1935,10 @@ class NodeSnapshotStoreConfig(BaseModel):
1846
1935
  """
1847
1936
  Local storage root for snapshot-store data.
1848
1937
  """
1938
+ dedup_rootfs: Annotated[bool | None, Field(title="Dedup Rootfs")] = False
1939
+ """
1940
+ Enable rootfs-level dedup via snapshot-store FUSE mount instead of file copy.
1941
+ """
1849
1942
 
1850
1943
 
1851
1944
  class NodeStatusResponse(BaseModel):
@@ -3087,6 +3180,16 @@ class UpdateConcurrencyLimitResponse(BaseModel):
3087
3180
  plan_type: Annotated[str, Field(title="Plan Type")]
3088
3181
 
3089
3182
 
3183
+ class UpdateMemberRequest(BaseModel):
3184
+ model_config = ConfigDict(
3185
+ extra="allow",
3186
+ )
3187
+ wireguard_ip: Annotated[str | None, Field(title="Wireguard Ip")] = None
3188
+ wireguard_public_key: Annotated[str | None, Field(title="Wireguard Public Key")] = None
3189
+ worker_endpoint: Annotated[str | None, Field(title="Worker Endpoint")] = None
3190
+ status: Annotated[str | None, Field(title="Status")] = None
3191
+
3192
+
3090
3193
  class UpdateReleaseRequest(BaseModel):
3091
3194
  model_config = ConfigDict(
3092
3195
  extra="allow",
@@ -4047,6 +4150,24 @@ class ModelsScoringConfigJSONSchemaDraft7(BaseModel):
4047
4150
  """
4048
4151
 
4049
4152
 
4153
+ class AddSSHKeyResponse(BaseModel):
4154
+ model_config = ConfigDict(
4155
+ extra="allow",
4156
+ )
4157
+ success: Annotated[bool, Field(title="Success")]
4158
+ """
4159
+ Whether all keys were added successfully
4160
+ """
4161
+ session_id: Annotated[str, Field(title="Session Id")]
4162
+ """
4163
+ Session ID
4164
+ """
4165
+ results: Annotated[dict[str, AddSSHKeyResult], Field(title="Results")]
4166
+ """
4167
+ Results keyed by job_id
4168
+ """
4169
+
4170
+
4050
4171
  class AnnotatorAssignmentListItem(BaseModel):
4051
4172
  model_config = ConfigDict(
4052
4173
  extra="allow",
@@ -4395,9 +4516,9 @@ class NodeConfig(BaseModel):
4395
4516
  """
4396
4517
  Build configuration including SSH keys for VMs
4397
4518
  """
4398
- nebula: NodeNebulaConfig | None = None
4519
+ session_network: NodeSessionNetworkConfig | None = None
4399
4520
  """
4400
- Nebula mesh VPN configuration for lighthouse connectivity
4521
+ Session network configuration for WireGuard-based VM-to-VM networking
4401
4522
  """
4402
4523
 
4403
4524
 
plato/v1/cli/agent.py CHANGED
@@ -616,21 +616,17 @@ def agent_run(
616
616
  model: str = typer.Option(None, "--model", "-m", help="Model name (e.g., 'anthropic/claude-sonnet-4')"),
617
617
  dataset: str = typer.Option(None, "--dataset", "-d", help="Dataset to run on"),
618
618
  ):
619
- """
620
- Run an agent using Harbor's runner infrastructure.
621
-
622
- This command wraps `harbor run` to execute agents. For full Harbor options,
623
- use `harbor run` directly or pass additional arguments after --.
619
+ """Run an agent using Harbor's runner infrastructure.
624
620
 
625
- Harbor agents: claude-code, openhands, codex, aider, gemini-cli, goose,
626
- swe-agent, mini-swe-agent, cline-cli, cursor-cli, opencode, qwen-coder
621
+ Wraps `harbor run` to execute agents on a dataset. Supports Harbor built-in agents
622
+ (claude-code, openhands, codex, aider, etc.) and Plato custom agents (computer-use).
627
623
 
628
- Plato agents: computer-use (requires pip install plato-agent-computer-use)
624
+ Options:
625
+ -a, --agent: Agent name to run. See 'plato agent list' for available agents.
626
+ -m, --model: Model name for the agent (e.g., 'anthropic/claude-sonnet-4')
627
+ -d, --dataset: Dataset to run on (e.g., 'swe-bench-lite', 'terminal-bench')
629
628
 
630
- Examples:
631
- plato agent run -a claude-code -m anthropic/claude-sonnet-4 -d swe-bench-lite
632
- plato agent run -a openhands -m openai/gpt-4o -d terminal-bench
633
- plato agent run -- -a claude-code -m anthropic/claude-sonnet-4 -d swe-bench-lite --limit 10
629
+ Additional arguments can be passed to Harbor after '--' separator.
634
630
  """
635
631
  # Check if harbor is installed
636
632
  if not shutil.which("harbor"):
@@ -683,8 +679,10 @@ def agent_run(
683
679
 
684
680
  @agent_app.command(name="list")
685
681
  def agent_list():
686
- """
687
- List all available agents (Harbor built-in + Plato custom).
682
+ """List all available agents.
683
+
684
+ Shows Harbor built-in agents (claude-code, openhands, etc.) and Plato custom agents
685
+ (computer-use) that can be used with 'plato agent run' and 'plato agent publish'.
688
686
  """
689
687
  console.print("[bold]Harbor Agents:[/bold]\n")
690
688
 
@@ -728,14 +726,13 @@ def agent_list():
728
726
  def agent_schema(
729
727
  agent_name: str = typer.Argument(..., help="Agent name to get schema for"),
730
728
  ):
731
- """
732
- Get the configuration schema for a Harbor agent.
729
+ """Get the configuration schema for a Harbor agent.
733
730
 
734
- Shows the JSON schema defining the configuration options for the specified agent.
731
+ Shows the JSON schema defining configuration options for the specified agent.
732
+ The schema describes what fields are available when configuring the agent for runs.
735
733
 
736
- Example:
737
- plato agent schema claude-code
738
- plato agent schema openhands
734
+ Arguments:
735
+ agent_name: Name of the agent (e.g., 'claude-code', 'openhands')
739
736
  """
740
737
  try:
741
738
  from plato.agents import AGENT_SCHEMAS, get_agent_schema
@@ -763,23 +760,19 @@ def agent_publish(
763
760
  all_agents: bool = typer.Option(False, "--all", "-a", help="Publish all agents in directory"),
764
761
  dry_run: bool = typer.Option(False, "--dry-run", help="Build without pushing to ECR"),
765
762
  ):
766
- """
767
- Build and publish an agent Docker image to ECR.
768
-
769
- Can publish either:
770
- - A custom agent from a directory (with Dockerfile + pyproject.toml)
771
- - A Harbor built-in agent by name
772
- - All agents in a directory with --all
773
-
774
- Version is automatic:
775
- - Custom agents: from pyproject.toml
776
- - Harbor agents: from installed Harbor package version
777
-
778
- Examples:
779
- plato agent publish ./agents/my-agent # Custom agent
780
- plato agent publish claude-code # Harbor built-in
781
- plato agent publish --all ./agents # All agents in directory
782
- plato agent publish claude-code --dry-run # Dry run
763
+ """Build and publish an agent Docker image to ECR.
764
+
765
+ Builds a Docker image for the agent and pushes it to the Plato ECR registry.
766
+ Version is determined automatically from pyproject.toml (custom agents) or the
767
+ installed Harbor package version (Harbor agents).
768
+
769
+ Arguments:
770
+ target: Path to custom agent directory with Dockerfile + pyproject.toml,
771
+ OR name of a Harbor built-in agent (e.g., 'claude-code')
772
+
773
+ Options:
774
+ -a, --all: Publish all agents found in the target directory
775
+ --dry-run: Build the Docker image without pushing to ECR
783
776
  """
784
777
 
785
778
  # Handle --all flag with directory
@@ -935,11 +928,10 @@ def _push_single_agent(pkg_path: Path, dry_run: bool) -> None:
935
928
 
936
929
  @agent_app.command(name="images")
937
930
  def agent_images():
938
- """
939
- List all published agent images for your organization.
931
+ """List all published agent images for your organization.
940
932
 
941
- Example:
942
- plato agent images
933
+ Queries the Plato API to show all agent Docker images that have been published
934
+ to your organization's ECR registry. Requires PLATO_API_KEY.
943
935
  """
944
936
  import httpx
945
937
 
@@ -977,11 +969,12 @@ def agent_images():
977
969
  def agent_versions(
978
970
  agent_name: str = typer.Argument(..., help="Agent name"),
979
971
  ):
980
- """
981
- List all published versions of an agent.
972
+ """List all published versions of an agent.
982
973
 
983
- Example:
984
- plato agent versions claude-code
974
+ Shows all available versions of the specified agent in your organization's registry.
975
+
976
+ Arguments:
977
+ agent_name: Name of the agent to list versions for
985
978
  """
986
979
  import httpx
987
980
 
@@ -1021,15 +1014,15 @@ def agent_versions(
1021
1014
  def agent_deploy(
1022
1015
  path: str = typer.Argument(".", help="Path to the agent package directory (default: current directory)"),
1023
1016
  ):
1024
- """
1025
- Deploy a Chronos agent package to AWS CodeArtifact.
1017
+ """Deploy a Chronos agent package to AWS CodeArtifact.
1018
+
1019
+ Builds the Python package, discovers @ai agents from the codebase, and uploads
1020
+ to CodeArtifact via the Plato API for use in Chronos jobs.
1026
1021
 
1027
- Builds the package, discovers @ai agents, and uploads to CodeArtifact
1028
- via the Plato API. Requires PLATO_API_KEY environment variable.
1022
+ Arguments:
1023
+ path: Path to the agent package directory with pyproject.toml (default: current directory)
1029
1024
 
1030
- Example:
1031
- plato agent deploy
1032
- plato agent deploy ./my-agent-package
1025
+ Requires PLATO_API_KEY environment variable.
1033
1026
  """
1034
1027
  try:
1035
1028
  import tomli