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.
- plato/_generated/__init__.py +1 -1
- plato/_generated/api/v2/__init__.py +2 -1
- plato/_generated/api/v2/networks/__init__.py +23 -0
- plato/_generated/api/v2/networks/add_member.py +75 -0
- plato/_generated/api/v2/networks/create_network.py +70 -0
- plato/_generated/api/v2/networks/delete_network.py +68 -0
- plato/_generated/api/v2/networks/get_network.py +69 -0
- plato/_generated/api/v2/networks/list_members.py +69 -0
- plato/_generated/api/v2/networks/list_networks.py +74 -0
- plato/_generated/api/v2/networks/remove_member.py +73 -0
- plato/_generated/api/v2/networks/update_member.py +80 -0
- plato/_generated/api/v2/sessions/__init__.py +4 -0
- plato/_generated/api/v2/sessions/add_ssh_key.py +81 -0
- plato/_generated/api/v2/sessions/connect_network.py +89 -0
- plato/_generated/models/__init__.py +145 -24
- plato/v1/cli/agent.py +45 -52
- plato/v1/cli/chronos.py +46 -58
- plato/v1/cli/main.py +14 -25
- plato/v1/cli/pm.py +129 -98
- plato/v1/cli/proxy.py +343 -0
- plato/v1/cli/sandbox.py +421 -425
- plato/v1/cli/ssh.py +12 -167
- plato/v1/cli/verify.py +79 -55
- plato/v1/cli/world.py +13 -12
- plato/v2/async_/client.py +24 -2
- plato/v2/async_/session.py +48 -0
- plato/v2/sync/client.py +24 -2
- plato/v2/sync/session.py +48 -0
- {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/METADATA +1 -1
- {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/RECORD +32 -20
- {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/WHEEL +0 -0
- {plato_sdk_v2-2.6.2.dist-info → plato_sdk_v2-2.7.1.dist-info}/entry_points.txt +0 -0
plato/v1/cli/chronos.py
CHANGED
|
@@ -48,30 +48,21 @@ def launch(
|
|
|
48
48
|
help="Wait for job completion and stream logs",
|
|
49
49
|
),
|
|
50
50
|
):
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
"runtime": {
|
|
68
|
-
"artifact_id": "..." // optional
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
Examples:
|
|
73
|
-
plato chronos launch config.json
|
|
74
|
-
plato chronos launch config.json --wait
|
|
51
|
+
"""Launch a Chronos job from a config file.
|
|
52
|
+
|
|
53
|
+
Submits a job configuration to the Chronos service to run a world with its
|
|
54
|
+
configured agents and secrets.
|
|
55
|
+
|
|
56
|
+
Arguments:
|
|
57
|
+
config: Path to the job configuration JSON file
|
|
58
|
+
|
|
59
|
+
Options:
|
|
60
|
+
-u, --url: Chronos API URL (default: https://chronos.plato.so, or CHRONOS_URL env var)
|
|
61
|
+
-k, --api-key: Plato API key for authentication (or PLATO_API_KEY env var)
|
|
62
|
+
-w, --wait: Wait for job completion and stream logs (not yet implemented)
|
|
63
|
+
|
|
64
|
+
The config file should contain world.package (required) and optionally world.config,
|
|
65
|
+
runtime.artifact_id, and tags.
|
|
75
66
|
"""
|
|
76
67
|
import httpx
|
|
77
68
|
|
|
@@ -148,12 +139,18 @@ def example(
|
|
|
148
139
|
help="Output file path (prints to stdout if not specified)",
|
|
149
140
|
),
|
|
150
141
|
):
|
|
151
|
-
"""
|
|
152
|
-
|
|
142
|
+
"""Generate an example job config file.
|
|
143
|
+
|
|
144
|
+
Creates a sample JSON configuration for launching Chronos jobs, which can be
|
|
145
|
+
customized for your use case.
|
|
146
|
+
|
|
147
|
+
Arguments:
|
|
148
|
+
world: World type to generate example for (default: "structured-execution")
|
|
153
149
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
150
|
+
Options:
|
|
151
|
+
-o, --output: Output file path. If not specified, prints to stdout.
|
|
152
|
+
|
|
153
|
+
Available worlds: structured-execution, code-world
|
|
157
154
|
"""
|
|
158
155
|
examples = {
|
|
159
156
|
"structured-execution": {
|
|
@@ -724,14 +721,17 @@ def stop(
|
|
|
724
721
|
help="Plato API key for authentication",
|
|
725
722
|
),
|
|
726
723
|
):
|
|
727
|
-
"""
|
|
728
|
-
Stop a running Chronos session.
|
|
724
|
+
"""Stop a running Chronos session.
|
|
729
725
|
|
|
730
|
-
|
|
726
|
+
Marks the session as cancelled with status reason "User cancelled" and terminates
|
|
727
|
+
any running containers.
|
|
731
728
|
|
|
732
|
-
|
|
733
|
-
plato chronos
|
|
734
|
-
|
|
729
|
+
Arguments:
|
|
730
|
+
session_id: The session ID to stop (from 'plato chronos launch' output)
|
|
731
|
+
|
|
732
|
+
Options:
|
|
733
|
+
-u, --url: Chronos API URL (default: https://chronos.plato.so, or CHRONOS_URL env var)
|
|
734
|
+
-k, --api-key: Plato API key for authentication (or PLATO_API_KEY env var)
|
|
735
735
|
"""
|
|
736
736
|
# Set defaults
|
|
737
737
|
if not chronos_url:
|
|
@@ -784,32 +784,20 @@ def dev(
|
|
|
784
784
|
typer.Option("--env-timeout", help="Timeout for environment creation (seconds)"),
|
|
785
785
|
] = 7200,
|
|
786
786
|
):
|
|
787
|
-
"""
|
|
788
|
-
Run a world locally for development/debugging.
|
|
787
|
+
"""Run a world locally for development/debugging.
|
|
789
788
|
|
|
790
|
-
|
|
791
|
-
allowing the world to spawn agent containers.
|
|
789
|
+
Builds and runs the world in a Docker container with docker.sock mounted,
|
|
790
|
+
allowing the world to spawn agent containers. Mounts local source code for
|
|
791
|
+
live development without rebuilding.
|
|
792
792
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
{
|
|
796
|
-
"world": {
|
|
797
|
-
"package": "plato-world-structured-execution:0.1.17",
|
|
798
|
-
"config": {
|
|
799
|
-
"skill_runner": {
|
|
800
|
-
"image": "computer-use:1.1.0",
|
|
801
|
-
"config": { ... }
|
|
802
|
-
},
|
|
803
|
-
"secrets": { ... }
|
|
804
|
-
}
|
|
805
|
-
},
|
|
806
|
-
"runtime": {
|
|
807
|
-
"artifact_id": "..."
|
|
808
|
-
}
|
|
809
|
-
}
|
|
793
|
+
Arguments:
|
|
794
|
+
config: Path to job config JSON file (same format as 'plato chronos launch')
|
|
810
795
|
|
|
811
|
-
|
|
812
|
-
|
|
796
|
+
Options:
|
|
797
|
+
-w, --world-dir: Directory containing world source code to mount into the container
|
|
798
|
+
-a, --agents-dir: Directory containing agent source code to mount (optional)
|
|
799
|
+
-p, --platform: Docker platform for building (e.g., 'linux/amd64' for M1 Macs)
|
|
800
|
+
--env-timeout: Timeout in seconds for environment creation (default: 7200 = 2 hours)
|
|
813
801
|
"""
|
|
814
802
|
logging.basicConfig(
|
|
815
803
|
level=logging.INFO,
|
plato/v1/cli/main.py
CHANGED
|
@@ -11,6 +11,7 @@ from dotenv import load_dotenv
|
|
|
11
11
|
from plato.v1.cli.agent import agent_app
|
|
12
12
|
from plato.v1.cli.chronos import chronos_app
|
|
13
13
|
from plato.v1.cli.pm import pm_app
|
|
14
|
+
from plato.v1.cli.proxy import app as proxy_app
|
|
14
15
|
from plato.v1.cli.sandbox import sandbox_app
|
|
15
16
|
from plato.v1.cli.utils import console
|
|
16
17
|
from plato.v1.cli.world import world_app
|
|
@@ -73,6 +74,7 @@ app.add_typer(pm_app, name="pm")
|
|
|
73
74
|
app.add_typer(agent_app, name="agent")
|
|
74
75
|
app.add_typer(world_app, name="world")
|
|
75
76
|
app.add_typer(chronos_app, name="chronos")
|
|
77
|
+
app.add_typer(proxy_app, name="proxy")
|
|
76
78
|
|
|
77
79
|
|
|
78
80
|
# =============================================================================
|
|
@@ -84,21 +86,13 @@ app.add_typer(chronos_app, name="chronos")
|
|
|
84
86
|
def hub(
|
|
85
87
|
ctx: typer.Context,
|
|
86
88
|
):
|
|
87
|
-
"""
|
|
88
|
-
Launch the Plato Hub CLI (interactive TUI for managing simulators).
|
|
89
|
-
|
|
90
|
-
The hub command opens the Go-based Plato CLI which provides an interactive
|
|
91
|
-
terminal UI for browsing simulators, launching environments, and managing VMs.
|
|
89
|
+
"""Launch the Plato Hub CLI (interactive TUI for managing simulators).
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
- (no args): Start interactive TUI mode
|
|
91
|
+
Opens the Go-based Plato CLI which provides an interactive terminal UI for
|
|
92
|
+
browsing simulators, launching environments, and managing VMs. Any additional
|
|
93
|
+
arguments are passed through to the Go CLI.
|
|
97
94
|
|
|
98
|
-
|
|
99
|
-
plato hub clone espocrm
|
|
100
|
-
plato hub credentials
|
|
101
|
-
plato hub
|
|
95
|
+
Common subcommands: 'clone <service>', 'credentials', or no args for interactive mode.
|
|
102
96
|
"""
|
|
103
97
|
# Find the bundled CLI binary
|
|
104
98
|
plato_bin = _find_bundled_cli()
|
|
@@ -129,14 +123,12 @@ def hub(
|
|
|
129
123
|
def clone(
|
|
130
124
|
service: str = typer.Argument(..., help="Service name to clone (e.g., espocrm)"),
|
|
131
125
|
):
|
|
132
|
-
"""
|
|
133
|
-
Clone a service repository from Plato Hub (Gitea).
|
|
126
|
+
"""Clone a service repository from Plato Hub (Gitea).
|
|
134
127
|
|
|
135
|
-
|
|
128
|
+
Clones the simulator source code to your local machine for development or review.
|
|
136
129
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
plato clone gitea
|
|
130
|
+
Arguments:
|
|
131
|
+
service: Service name to clone (e.g., 'espocrm', 'gitea')
|
|
140
132
|
"""
|
|
141
133
|
plato_bin = _find_bundled_cli()
|
|
142
134
|
if not plato_bin:
|
|
@@ -153,13 +145,10 @@ def clone(
|
|
|
153
145
|
|
|
154
146
|
@app.command()
|
|
155
147
|
def credentials():
|
|
156
|
-
"""
|
|
157
|
-
Display your Plato Hub (Gitea) credentials.
|
|
158
|
-
|
|
159
|
-
Shows the username and password needed to access Plato's Gitea repositories.
|
|
148
|
+
"""Display your Plato Hub (Gitea) credentials.
|
|
160
149
|
|
|
161
|
-
|
|
162
|
-
|
|
150
|
+
Shows the username and password needed to access Plato's Gitea repositories
|
|
151
|
+
for cloning and pushing simulator code.
|
|
163
152
|
"""
|
|
164
153
|
plato_bin = _find_bundled_cli()
|
|
165
154
|
if not plato_bin:
|
plato/v1/cli/pm.py
CHANGED
|
@@ -6,10 +6,12 @@ import os
|
|
|
6
6
|
import re
|
|
7
7
|
import shutil
|
|
8
8
|
import tempfile
|
|
9
|
+
from datetime import datetime, timedelta
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
11
12
|
import httpx
|
|
12
13
|
import typer
|
|
14
|
+
import yaml
|
|
13
15
|
from rich.table import Table
|
|
14
16
|
|
|
15
17
|
from plato._generated.api.v1.env import get_simulator_by_name, get_simulators
|
|
@@ -25,6 +27,7 @@ from plato._generated.models import (
|
|
|
25
27
|
AddReviewRequest,
|
|
26
28
|
AppApiV1SimulatorRoutesUpdateSimulatorRequest,
|
|
27
29
|
Authentication,
|
|
30
|
+
Flow,
|
|
28
31
|
Outcome,
|
|
29
32
|
ReviewType,
|
|
30
33
|
UpdateStatusRequest,
|
|
@@ -41,6 +44,7 @@ from plato.v1.cli.utils import (
|
|
|
41
44
|
)
|
|
42
45
|
from plato.v1.cli.verify import pm_verify_app
|
|
43
46
|
from plato.v2.async_.client import AsyncPlato
|
|
47
|
+
from plato.v2.async_.flow_executor import FlowExecutor
|
|
44
48
|
from plato.v2.types import Env
|
|
45
49
|
|
|
46
50
|
# =============================================================================
|
|
@@ -240,44 +244,20 @@ def _list_pending_reviews(review_type: str):
|
|
|
240
244
|
|
|
241
245
|
@list_app.command(name="base")
|
|
242
246
|
def list_base():
|
|
243
|
-
"""
|
|
244
|
-
List simulators pending base/environment review.
|
|
245
|
-
|
|
246
|
-
Shows simulators waiting for environment review (status: env_review_requested).
|
|
247
|
-
Use this to see what needs reviewing before running 'plato pm review base'.
|
|
248
|
-
|
|
249
|
-
USAGE:
|
|
247
|
+
"""List simulators pending base/environment review.
|
|
250
248
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
OUTPUT COLUMNS:
|
|
254
|
-
|
|
255
|
-
- Name: Simulator name
|
|
256
|
-
- Assignees: Who's assigned to review
|
|
257
|
-
- Notes: Any notes about the simulator
|
|
258
|
-
- base_artifact_id: The artifact to review
|
|
249
|
+
Shows simulators with status 'env_review_requested' in a table format.
|
|
250
|
+
Displays name, assignees, notes, and base_artifact_id for each simulator.
|
|
259
251
|
"""
|
|
260
252
|
_list_pending_reviews("base")
|
|
261
253
|
|
|
262
254
|
|
|
263
255
|
@list_app.command(name="data")
|
|
264
256
|
def list_data():
|
|
265
|
-
"""
|
|
266
|
-
List simulators pending data review.
|
|
257
|
+
"""List simulators pending data review.
|
|
267
258
|
|
|
268
|
-
Shows simulators
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
USAGE:
|
|
272
|
-
|
|
273
|
-
plato pm list data
|
|
274
|
-
|
|
275
|
-
OUTPUT COLUMNS:
|
|
276
|
-
|
|
277
|
-
- Name: Simulator name
|
|
278
|
-
- Assignees: Who's assigned to review
|
|
279
|
-
- Notes: Any notes about the simulator
|
|
280
|
-
- data_artifact_id: The artifact to review
|
|
259
|
+
Shows simulators with status 'data_review_requested' in a table format.
|
|
260
|
+
Displays name, assignees, notes, and data_artifact_id for each simulator.
|
|
281
261
|
"""
|
|
282
262
|
_list_pending_reviews("data")
|
|
283
263
|
|
|
@@ -306,26 +286,31 @@ def review_base(
|
|
|
306
286
|
"--skip-review",
|
|
307
287
|
help="Run login flow and check state, but skip interactive review. For automated verification.",
|
|
308
288
|
),
|
|
289
|
+
local: str = typer.Option(
|
|
290
|
+
None,
|
|
291
|
+
"--local",
|
|
292
|
+
"-l",
|
|
293
|
+
help="Path to a local flow YAML file to run instead of the default login flow.",
|
|
294
|
+
),
|
|
295
|
+
clock: str = typer.Option(
|
|
296
|
+
None,
|
|
297
|
+
"--clock",
|
|
298
|
+
help="Set fake browser time (ISO format or offset like '-30d' for 30 days ago).",
|
|
299
|
+
),
|
|
309
300
|
):
|
|
310
|
-
"""
|
|
311
|
-
Review base/environment artifact for a simulator.
|
|
312
|
-
|
|
313
|
-
Opens the simulator in a browser for manual testing. After testing,
|
|
314
|
-
you can pass (→ env_approved) or reject (→ env_in_progress).
|
|
315
|
-
|
|
316
|
-
SPECIFYING SIMULATOR AND ARTIFACT:
|
|
317
|
-
|
|
318
|
-
-s <simulator> Use server's base_artifact_id
|
|
319
|
-
-s <simulator> -a <artifact-uuid> Explicit artifact
|
|
320
|
-
-s <simulator>:<artifact-uuid> Colon notation (same as above)
|
|
301
|
+
"""Review base/environment artifact for a simulator.
|
|
321
302
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
plato pm review base -s espocrm -a e9c25ca5-1234-5678-9abc-def012345678
|
|
326
|
-
plato pm review base -s espocrm:e9c25ca5-1234-5678-9abc-def012345678
|
|
303
|
+
Creates an environment from the artifact, launches a browser for testing,
|
|
304
|
+
runs the login flow, and checks for database mutations. After testing,
|
|
305
|
+
choose pass (→ env_approved) or reject (→ env_in_progress).
|
|
327
306
|
|
|
328
307
|
Requires simulator status: env_review_requested
|
|
308
|
+
|
|
309
|
+
Options:
|
|
310
|
+
-s, --simulator: Simulator name. Supports colon notation for artifact:
|
|
311
|
+
'-s sim' (uses server's base_artifact_id) or '-s sim:<uuid>'
|
|
312
|
+
-a, --artifact: Explicit artifact UUID to review. Overrides server's value.
|
|
313
|
+
--skip-review: Run automated checks without interactive review session.
|
|
329
314
|
"""
|
|
330
315
|
api_key = require_api_key()
|
|
331
316
|
|
|
@@ -403,16 +388,87 @@ def review_base(
|
|
|
403
388
|
playwright = await async_playwright().start()
|
|
404
389
|
browser = await playwright.chromium.launch(headless=False)
|
|
405
390
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
391
|
+
# Install fake clock if requested
|
|
392
|
+
fake_time = None
|
|
393
|
+
if clock:
|
|
394
|
+
# Parse clock option: ISO format or offset like '-30d'
|
|
395
|
+
if clock.startswith("-") and clock[-1] in "dhms":
|
|
396
|
+
# Offset format: -30d, -1h, -30m, -60s
|
|
397
|
+
unit = clock[-1]
|
|
398
|
+
amount = int(clock[1:-1])
|
|
399
|
+
if unit == "d":
|
|
400
|
+
fake_time = datetime.now() - timedelta(days=amount)
|
|
401
|
+
elif unit == "h":
|
|
402
|
+
fake_time = datetime.now() - timedelta(hours=amount)
|
|
403
|
+
elif unit == "m":
|
|
404
|
+
fake_time = datetime.now() - timedelta(minutes=amount)
|
|
405
|
+
elif unit == "s":
|
|
406
|
+
fake_time = datetime.now() - timedelta(seconds=amount)
|
|
407
|
+
else:
|
|
408
|
+
# ISO format
|
|
409
|
+
fake_time = datetime.fromisoformat(clock)
|
|
410
|
+
|
|
411
|
+
console.print(f"[cyan]Setting fake browser time to:[/cyan] {fake_time.isoformat()}")
|
|
412
|
+
|
|
413
|
+
if local:
|
|
414
|
+
# Use local flow file instead of default login
|
|
415
|
+
local_path = Path(local)
|
|
416
|
+
if not local_path.exists():
|
|
417
|
+
console.print(f"[red]❌ Local flow file not found: {local}[/red]")
|
|
418
|
+
raise typer.Exit(1)
|
|
419
|
+
|
|
420
|
+
console.print(f"[cyan]Loading local flow from: {local}[/cyan]")
|
|
421
|
+
with open(local_path) as f:
|
|
422
|
+
flow_dict = yaml.safe_load(f)
|
|
423
|
+
|
|
424
|
+
# Find login flow (or first flow if only one)
|
|
425
|
+
flows = flow_dict.get("flows", [])
|
|
426
|
+
if not flows:
|
|
427
|
+
console.print("[red]❌ No flows found in flow file[/red]")
|
|
428
|
+
raise typer.Exit(1)
|
|
429
|
+
|
|
430
|
+
# Try to find 'login' flow, otherwise use first flow
|
|
431
|
+
flow_data = next((f for f in flows if f.get("name") == "login"), flows[0])
|
|
432
|
+
flow = Flow.model_validate(flow_data)
|
|
433
|
+
console.print(f"[cyan]Running flow: {flow.name}[/cyan]")
|
|
434
|
+
|
|
435
|
+
# Create page and navigate to public URL
|
|
412
436
|
page = await browser.new_page()
|
|
437
|
+
|
|
438
|
+
# Install fake clock if requested
|
|
439
|
+
if fake_time:
|
|
440
|
+
await page.clock.install(time=fake_time)
|
|
441
|
+
console.print(f"[green]✅ Fake clock installed: {fake_time.isoformat()}[/green]")
|
|
442
|
+
|
|
413
443
|
if public_url:
|
|
414
444
|
await page.goto(public_url)
|
|
415
445
|
|
|
446
|
+
# Execute the flow
|
|
447
|
+
try:
|
|
448
|
+
executor = FlowExecutor(page, flow)
|
|
449
|
+
await executor.execute()
|
|
450
|
+
console.print("[green]✅ Local flow executed successfully[/green]")
|
|
451
|
+
except Exception as e:
|
|
452
|
+
console.print(f"[yellow]⚠️ Flow execution error: {e}[/yellow]")
|
|
453
|
+
else:
|
|
454
|
+
# Use default login via session.login()
|
|
455
|
+
if fake_time:
|
|
456
|
+
console.print("[yellow]⚠️ --clock with default login may not work correctly.[/yellow]")
|
|
457
|
+
console.print("[yellow] Use --local with a flow file for reliable clock testing.[/yellow]")
|
|
458
|
+
try:
|
|
459
|
+
login_result = await session.login(browser, dataset="base")
|
|
460
|
+
page = list(login_result.pages.values())[0] if login_result.pages else None
|
|
461
|
+
console.print("[green]✅ Logged into environment[/green]")
|
|
462
|
+
except Exception as e:
|
|
463
|
+
console.print(f"[yellow]⚠️ Login error: {e}[/yellow]")
|
|
464
|
+
page = await browser.new_page()
|
|
465
|
+
# Install fake clock on fallback page
|
|
466
|
+
if fake_time:
|
|
467
|
+
await page.clock.install(time=fake_time)
|
|
468
|
+
console.print(f"[green]✅ Fake clock installed: {fake_time.isoformat()}[/green]")
|
|
469
|
+
if public_url:
|
|
470
|
+
await page.goto(public_url)
|
|
471
|
+
|
|
416
472
|
# ALWAYS check state after login to verify no mutations
|
|
417
473
|
console.print("\n[cyan]Checking environment state after login...[/cyan]")
|
|
418
474
|
has_mutations = False
|
|
@@ -676,25 +732,18 @@ def review_data(
|
|
|
676
732
|
help="Artifact UUID to review. If not provided, uses server's data_artifact_id.",
|
|
677
733
|
),
|
|
678
734
|
):
|
|
679
|
-
"""
|
|
680
|
-
Launch browser with EnvGen Recorder extension for data review.
|
|
735
|
+
"""Launch browser with EnvGen Recorder extension for data review.
|
|
681
736
|
|
|
682
737
|
Opens Chrome with the EnvGen Recorder extension installed for reviewing
|
|
683
|
-
data artifacts.
|
|
684
|
-
|
|
685
|
-
SPECIFYING SIMULATOR AND ARTIFACT:
|
|
686
|
-
|
|
687
|
-
-s <simulator> Use server's data_artifact_id
|
|
688
|
-
-s <simulator> -a <artifact-uuid> Explicit artifact
|
|
689
|
-
-s <simulator>:<artifact-uuid> Colon notation (same as above)
|
|
690
|
-
|
|
691
|
-
EXAMPLES:
|
|
692
|
-
|
|
693
|
-
plato pm review data -s fathom
|
|
694
|
-
plato pm review data -s fathom -a e9c25ca5-1234-5678-9abc-def012345678
|
|
695
|
-
plato pm review data -s fathom:e9c25ca5-1234-5678-9abc-def012345678
|
|
738
|
+
data artifacts. The extension sidebar can be used to record and submit reviews.
|
|
739
|
+
Press Control-C to exit when done.
|
|
696
740
|
|
|
697
741
|
Requires simulator status: data_review_requested
|
|
742
|
+
|
|
743
|
+
Options:
|
|
744
|
+
-s, --simulator: Simulator name. Supports colon notation for artifact:
|
|
745
|
+
'-s sim' (uses server's data_artifact_id) or '-s sim:<uuid>'
|
|
746
|
+
-a, --artifact: Explicit artifact UUID to review. Overrides server's value.
|
|
698
747
|
"""
|
|
699
748
|
api_key = require_api_key()
|
|
700
749
|
|
|
@@ -924,27 +973,14 @@ def review_data(
|
|
|
924
973
|
|
|
925
974
|
@submit_app.command(name="base")
|
|
926
975
|
def submit_base():
|
|
927
|
-
"""
|
|
928
|
-
Submit base/environment artifact for review after snapshot.
|
|
976
|
+
"""Submit base/environment artifact for review after snapshot.
|
|
929
977
|
|
|
930
|
-
Reads simulator name and
|
|
931
|
-
plato
|
|
932
|
-
creating a snapshot.
|
|
933
|
-
|
|
934
|
-
Transitions simulator from env_in_progress → env_review_requested.
|
|
935
|
-
|
|
936
|
-
USAGE:
|
|
937
|
-
|
|
938
|
-
plato pm submit base # No args needed - reads from .sandbox.yaml
|
|
939
|
-
|
|
940
|
-
PREREQUISITES:
|
|
941
|
-
|
|
942
|
-
1. plato sandbox start --from-config
|
|
943
|
-
2. plato sandbox start-services
|
|
944
|
-
3. plato sandbox snapshot
|
|
945
|
-
4. plato pm submit base ← you are here
|
|
978
|
+
Reads simulator name and artifact_id from .sandbox.yaml, syncs metadata from
|
|
979
|
+
plato-config.yml to the server, and transitions status to env_review_requested.
|
|
980
|
+
Run from the simulator directory after creating a snapshot.
|
|
946
981
|
|
|
947
982
|
Requires simulator status: env_in_progress
|
|
983
|
+
No arguments needed - reads everything from .sandbox.yaml and plato-config.yml.
|
|
948
984
|
"""
|
|
949
985
|
api_key = require_api_key()
|
|
950
986
|
|
|
@@ -1091,22 +1127,17 @@ def submit_data(
|
|
|
1091
1127
|
help="Artifact UUID to submit for data review (required).",
|
|
1092
1128
|
),
|
|
1093
1129
|
):
|
|
1094
|
-
"""
|
|
1095
|
-
Submit data artifact for review after data generation.
|
|
1130
|
+
"""Submit data artifact for review after data generation.
|
|
1096
1131
|
|
|
1097
|
-
Transitions simulator from data_in_progress → data_review_requested
|
|
1098
|
-
|
|
1099
|
-
SPECIFYING SIMULATOR AND ARTIFACT (both required):
|
|
1100
|
-
|
|
1101
|
-
-s <simulator> -a <artifact-uuid> Explicit artifact
|
|
1102
|
-
-s <simulator>:<artifact-uuid> Colon notation (same as above)
|
|
1103
|
-
|
|
1104
|
-
EXAMPLES:
|
|
1105
|
-
|
|
1106
|
-
plato pm submit data -s espocrm -a e9c25ca5-1234-5678-9abc-def012345678
|
|
1107
|
-
plato pm submit data -s espocrm:e9c25ca5-1234-5678-9abc-def012345678
|
|
1132
|
+
Transitions simulator from data_in_progress → data_review_requested and
|
|
1133
|
+
tags the artifact as 'data-pending-review'.
|
|
1108
1134
|
|
|
1109
1135
|
Requires simulator status: data_in_progress
|
|
1136
|
+
|
|
1137
|
+
Options:
|
|
1138
|
+
-s, --simulator: Simulator name. Supports colon notation:
|
|
1139
|
+
'-s sim:<uuid>' or use separate -a flag
|
|
1140
|
+
-a, --artifact: Artifact UUID to submit (required)
|
|
1110
1141
|
"""
|
|
1111
1142
|
api_key = require_api_key()
|
|
1112
1143
|
|