plato-sdk-v2 2.4.1__py3-none-any.whl → 2.5.0__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/v1/cli/agent.py +7 -7
- plato/v1/cli/chronos.py +49 -70
- plato/v1/cli/world.py +10 -43
- plato/worlds/__init__.py +12 -1
- plato/worlds/config.py +55 -10
- {plato_sdk_v2-2.4.1.dist-info → plato_sdk_v2-2.5.0.dist-info}/METADATA +1 -1
- {plato_sdk_v2-2.4.1.dist-info → plato_sdk_v2-2.5.0.dist-info}/RECORD +9 -9
- {plato_sdk_v2-2.4.1.dist-info → plato_sdk_v2-2.5.0.dist-info}/WHEEL +0 -0
- {plato_sdk_v2-2.4.1.dist-info → plato_sdk_v2-2.5.0.dist-info}/entry_points.txt +0 -0
plato/v1/cli/agent.py
CHANGED
|
@@ -757,8 +757,8 @@ def agent_schema(
|
|
|
757
757
|
console.print(json.dumps(schema, indent=2))
|
|
758
758
|
|
|
759
759
|
|
|
760
|
-
@agent_app.command(name="
|
|
761
|
-
def
|
|
760
|
+
@agent_app.command(name="publish")
|
|
761
|
+
def agent_publish(
|
|
762
762
|
target: str = typer.Argument(".", help="Path to agent directory OR Harbor agent name"),
|
|
763
763
|
all_agents: bool = typer.Option(False, "--all", "-a", help="Publish all agents in directory"),
|
|
764
764
|
dry_run: bool = typer.Option(False, "--dry-run", help="Build without pushing to ECR"),
|
|
@@ -776,10 +776,10 @@ def agent_push(
|
|
|
776
776
|
- Harbor agents: from installed Harbor package version
|
|
777
777
|
|
|
778
778
|
Examples:
|
|
779
|
-
plato agent
|
|
780
|
-
plato agent
|
|
781
|
-
plato agent
|
|
782
|
-
plato agent
|
|
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
|
|
783
783
|
"""
|
|
784
784
|
|
|
785
785
|
# Handle --all flag with directory
|
|
@@ -964,7 +964,7 @@ def agent_images():
|
|
|
964
964
|
agents = data.get("agents", [])
|
|
965
965
|
if not agents:
|
|
966
966
|
console.print("[yellow]No published agents found[/yellow]")
|
|
967
|
-
console.print("\n[dim]Publish with: plato agent
|
|
967
|
+
console.print("\n[dim]Publish with: plato agent publish <path-or-name>[/dim]")
|
|
968
968
|
return
|
|
969
969
|
|
|
970
970
|
console.print("[bold]Published Agent Images:[/bold]\n")
|
plato/v1/cli/chronos.py
CHANGED
|
@@ -51,41 +51,27 @@ def launch(
|
|
|
51
51
|
"""
|
|
52
52
|
Launch a Chronos job from a config file.
|
|
53
53
|
|
|
54
|
-
The config file should be a JSON file with the following structure:
|
|
55
|
-
|
|
56
54
|
\b
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
Config format:
|
|
56
|
+
{
|
|
57
|
+
"world": {
|
|
58
|
+
"package": "plato-world-structured-execution:0.1.17",
|
|
59
|
+
"config": {
|
|
60
|
+
"skill_runner": {
|
|
61
|
+
"image": "computer-use:1.1.0",
|
|
62
|
+
"config": { ... }
|
|
63
|
+
},
|
|
64
|
+
"secrets": { ... }
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"runtime": {
|
|
68
|
+
"artifact_id": "..." // optional
|
|
69
|
+
}
|
|
65
70
|
}
|
|
66
|
-
},
|
|
67
|
-
"secret_ids": [1, 2, 3] // IDs of secrets from Chronos
|
|
68
|
-
}
|
|
69
71
|
|
|
70
72
|
Examples:
|
|
71
73
|
plato chronos launch config.json
|
|
72
74
|
plato chronos launch config.json --wait
|
|
73
|
-
plato chronos launch config.json --url https://chronos.example.com
|
|
74
|
-
|
|
75
|
-
Config format (simplified - agents/secrets embedded in world_config):
|
|
76
|
-
{
|
|
77
|
-
"world_package": "plato-world-structured-execution",
|
|
78
|
-
"world_version": "latest", // optional
|
|
79
|
-
"world_config": {
|
|
80
|
-
"skill_runner": {
|
|
81
|
-
"image": "claude-code:2.1.5",
|
|
82
|
-
"config": { ... }
|
|
83
|
-
},
|
|
84
|
-
"plato_api_key": "pk_xxx", // secrets embedded
|
|
85
|
-
...
|
|
86
|
-
},
|
|
87
|
-
"runtime_artifact_id": "..." // optional
|
|
88
|
-
}
|
|
89
75
|
"""
|
|
90
76
|
import httpx
|
|
91
77
|
|
|
@@ -107,22 +93,19 @@ def launch(
|
|
|
107
93
|
raise typer.Exit(1)
|
|
108
94
|
|
|
109
95
|
# Validate required fields
|
|
110
|
-
if "
|
|
111
|
-
console.print("[red]❌ Missing required field:
|
|
96
|
+
if "world" not in job_config or "package" not in job_config.get("world", {}):
|
|
97
|
+
console.print("[red]❌ Missing required field: world.package[/red]")
|
|
112
98
|
raise typer.Exit(1)
|
|
113
99
|
|
|
114
|
-
# Build request
|
|
100
|
+
# Build request
|
|
115
101
|
request_body = {
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"world_config": job_config.get("world_config", {}),
|
|
119
|
-
"runtime_artifact_id": job_config.get("runtime_artifact_id"),
|
|
102
|
+
"world": job_config["world"],
|
|
103
|
+
"runtime": job_config.get("runtime", {}),
|
|
120
104
|
}
|
|
121
105
|
|
|
106
|
+
world_package = job_config["world"]["package"]
|
|
122
107
|
console.print("[blue]🚀 Launching job...[/blue]")
|
|
123
|
-
console.print(f" World: {
|
|
124
|
-
if request_body.get("world_version"):
|
|
125
|
-
console.print(f" Version: {request_body['world_version']}")
|
|
108
|
+
console.print(f" World: {world_package}")
|
|
126
109
|
|
|
127
110
|
try:
|
|
128
111
|
with httpx.Client(timeout=60) as client:
|
|
@@ -489,22 +472,22 @@ async def _run_dev_impl(
|
|
|
489
472
|
with open(config_path) as f:
|
|
490
473
|
raw_config = json.load(f)
|
|
491
474
|
|
|
492
|
-
#
|
|
493
|
-
if "
|
|
494
|
-
|
|
495
|
-
top_level_secrets = raw_config.get("secrets", {})
|
|
496
|
-
if top_level_secrets:
|
|
497
|
-
config_data.setdefault("secrets", {})
|
|
498
|
-
config_data["secrets"].update(top_level_secrets)
|
|
499
|
-
else:
|
|
500
|
-
config_data = raw_config.copy()
|
|
475
|
+
# Validate config format: { world: { package, config }, runtime: { artifact_id } }
|
|
476
|
+
if "world" not in raw_config or "package" not in raw_config.get("world", {}):
|
|
477
|
+
raise ValueError("Invalid config: missing world.package")
|
|
501
478
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
479
|
+
world_package = raw_config["world"]["package"]
|
|
480
|
+
config_data = raw_config["world"].get("config", {}).copy()
|
|
481
|
+
runtime_artifact_id = raw_config.get("runtime", {}).get("artifact_id")
|
|
482
|
+
if runtime_artifact_id:
|
|
483
|
+
config_data["runtime_artifact_id"] = runtime_artifact_id
|
|
484
|
+
|
|
485
|
+
# Parse world name from package (e.g., "plato-world-structured-execution:0.1.17")
|
|
486
|
+
world_package_name = world_package.split(":")[0] if ":" in world_package else world_package
|
|
487
|
+
if world_package_name.startswith("plato-world-"):
|
|
488
|
+
world_name = world_package_name[len("plato-world-") :]
|
|
506
489
|
else:
|
|
507
|
-
world_name =
|
|
490
|
+
world_name = world_package_name or "unknown"
|
|
508
491
|
|
|
509
492
|
# Build local agent images if agents_dir is provided
|
|
510
493
|
if agents_dir:
|
|
@@ -553,8 +536,8 @@ async def _run_dev_impl(
|
|
|
553
536
|
plato_session_id = session.session_id
|
|
554
537
|
console.print(f"[green]✅ Created Plato session: {plato_session_id}[/green]")
|
|
555
538
|
|
|
556
|
-
# Add session to config
|
|
557
|
-
config_data["plato_session"] = session.dump()
|
|
539
|
+
# Add session to config (convert Pydantic model to dict for JSON serialization)
|
|
540
|
+
config_data["plato_session"] = session.dump().model_dump()
|
|
558
541
|
|
|
559
542
|
# Create Chronos session
|
|
560
543
|
console.print("[blue]Creating Chronos session...[/blue]")
|
|
@@ -748,27 +731,23 @@ def dev(
|
|
|
748
731
|
\b
|
|
749
732
|
Config format (same as Chronos launch):
|
|
750
733
|
{
|
|
751
|
-
"
|
|
752
|
-
|
|
753
|
-
"
|
|
754
|
-
"steps": [...],
|
|
755
|
-
"agents": {
|
|
734
|
+
"world": {
|
|
735
|
+
"package": "plato-world-structured-execution:0.1.17",
|
|
736
|
+
"config": {
|
|
756
737
|
"skill_runner": {
|
|
757
|
-
"image": "computer-use:
|
|
758
|
-
"config": {
|
|
759
|
-
}
|
|
738
|
+
"image": "computer-use:1.1.0",
|
|
739
|
+
"config": { ... }
|
|
740
|
+
},
|
|
741
|
+
"secrets": { ... }
|
|
760
742
|
}
|
|
761
743
|
},
|
|
762
|
-
"
|
|
763
|
-
"
|
|
764
|
-
"plato_api_key": "..."
|
|
744
|
+
"runtime": {
|
|
745
|
+
"artifact_id": "..."
|
|
765
746
|
}
|
|
766
747
|
}
|
|
767
748
|
|
|
768
|
-
|
|
769
|
-
plato chronos dev config.json
|
|
770
|
-
plato chronos dev config.json -w ~/worlds/my-world -a ~/agents
|
|
771
|
-
plato chronos dev config.json -w ~/worlds/my-world --platform linux/amd64
|
|
749
|
+
Example:
|
|
750
|
+
plato chronos dev config.json -w ~/worlds/my-world -a ~/agents --platform linux/amd64
|
|
772
751
|
"""
|
|
773
752
|
logging.basicConfig(
|
|
774
753
|
level=logging.INFO,
|
plato/v1/cli/world.py
CHANGED
|
@@ -62,41 +62,6 @@ def _extract_schema_from_wheel(wheel_path: Path, module_name: str) -> dict | Non
|
|
|
62
62
|
return None
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
def _register_world_schema(
|
|
66
|
-
api_url: str,
|
|
67
|
-
api_key: str,
|
|
68
|
-
package_name: str,
|
|
69
|
-
version: str,
|
|
70
|
-
schema_data: dict,
|
|
71
|
-
) -> bool:
|
|
72
|
-
"""Register world schema with plato.so registry."""
|
|
73
|
-
import httpx
|
|
74
|
-
|
|
75
|
-
try:
|
|
76
|
-
with httpx.Client(base_url=api_url, timeout=30.0) as client:
|
|
77
|
-
response = client.post(
|
|
78
|
-
f"/v2/pypi/worlds/packages/{package_name}/schema",
|
|
79
|
-
json={
|
|
80
|
-
"version": version,
|
|
81
|
-
"config_schema": schema_data,
|
|
82
|
-
},
|
|
83
|
-
headers={"X-API-Key": api_key},
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
if response.status_code in (200, 201):
|
|
87
|
-
return True
|
|
88
|
-
elif response.status_code == 404:
|
|
89
|
-
# Endpoint doesn't exist yet - that's ok
|
|
90
|
-
console.print("[dim]Schema registration endpoint not available[/dim]")
|
|
91
|
-
return False
|
|
92
|
-
else:
|
|
93
|
-
console.print(f"[yellow]Warning: Schema registration returned {response.status_code}[/yellow]")
|
|
94
|
-
return False
|
|
95
|
-
except Exception as e:
|
|
96
|
-
console.print(f"[yellow]Warning: Could not register schema: {e}[/yellow]")
|
|
97
|
-
return False
|
|
98
|
-
|
|
99
|
-
|
|
100
65
|
@world_app.command(name="publish")
|
|
101
66
|
def world_publish(
|
|
102
67
|
path: str = typer.Argument(".", help="Path to the world package directory (default: current directory)"),
|
|
@@ -218,11 +183,19 @@ def world_publish(
|
|
|
218
183
|
schema_data = _extract_schema_from_wheel(wheel_file, module_name)
|
|
219
184
|
if schema_data:
|
|
220
185
|
props = schema_data.get("properties", {})
|
|
221
|
-
|
|
186
|
+
agents = schema_data.get("agents", [])
|
|
187
|
+
secrets = schema_data.get("secrets", [])
|
|
188
|
+
console.print(
|
|
189
|
+
f"[green]Schema found:[/green] {len(props)} properties, {len(agents)} agents, {len(secrets)} secrets"
|
|
190
|
+
)
|
|
222
191
|
console.print(f"[dim] Properties: {', '.join(props.keys()) if props else 'none'}[/dim]")
|
|
192
|
+
if agents:
|
|
193
|
+
console.print(f"[dim] Agents: {', '.join(a.get('name', '?') for a in agents)}[/dim]")
|
|
223
194
|
else:
|
|
224
|
-
console.print("[
|
|
195
|
+
console.print("[red]Error: No schema.json found in wheel[/red]")
|
|
225
196
|
console.print("[dim] Add a hatch build hook to generate schema.json from get_schema()[/dim]")
|
|
197
|
+
console.print("[dim] See: https://docs.plato.so/worlds/publishing#schema-generation[/dim]")
|
|
198
|
+
raise SystemExit(1)
|
|
226
199
|
|
|
227
200
|
if dry_run:
|
|
228
201
|
console.print("\n[yellow]Dry run - skipping upload[/yellow]")
|
|
@@ -272,11 +245,5 @@ def world_publish(
|
|
|
272
245
|
console.print(f"[red]Upload error: {e}[/red]")
|
|
273
246
|
raise typer.Exit(1) from e
|
|
274
247
|
|
|
275
|
-
# Register schema if we have one
|
|
276
|
-
if schema_data:
|
|
277
|
-
console.print("\n[cyan]Registering schema...[/cyan]")
|
|
278
|
-
if _register_world_schema(api_url, api_key, package_name, version, schema_data):
|
|
279
|
-
console.print("[green]Schema registered![/green]")
|
|
280
|
-
|
|
281
248
|
console.print("\n[bold]Install with:[/bold]")
|
|
282
249
|
console.print(f" uv add {package_name} --index-url {api_url}/v2/pypi/worlds/simple/")
|
plato/worlds/__init__.py
CHANGED
|
@@ -52,7 +52,17 @@ from plato.worlds.base import (
|
|
|
52
52
|
get_world,
|
|
53
53
|
register_world,
|
|
54
54
|
)
|
|
55
|
-
from plato.worlds.config import
|
|
55
|
+
from plato.worlds.config import (
|
|
56
|
+
Agent,
|
|
57
|
+
AgentConfig,
|
|
58
|
+
CheckpointConfig,
|
|
59
|
+
Env,
|
|
60
|
+
EnvConfig,
|
|
61
|
+
EnvList,
|
|
62
|
+
RunConfig,
|
|
63
|
+
Secret,
|
|
64
|
+
StateConfig,
|
|
65
|
+
)
|
|
56
66
|
from plato.worlds.runner import run_world
|
|
57
67
|
|
|
58
68
|
__all__ = [
|
|
@@ -72,6 +82,7 @@ __all__ = [
|
|
|
72
82
|
"Agent",
|
|
73
83
|
"Secret",
|
|
74
84
|
"Env",
|
|
85
|
+
"EnvList",
|
|
75
86
|
"EnvConfig",
|
|
76
87
|
# Env types (re-exported from generated models)
|
|
77
88
|
"EnvFromArtifact",
|
plato/worlds/config.py
CHANGED
|
@@ -55,7 +55,7 @@ class Secret:
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
class Env:
|
|
58
|
-
"""Annotation marker for environment fields.
|
|
58
|
+
"""Annotation marker for single environment fields.
|
|
59
59
|
|
|
60
60
|
Environments are VMs that run alongside the world's runtime.
|
|
61
61
|
They can be specified by artifact ID, simulator name, or resource config.
|
|
@@ -72,6 +72,24 @@ class Env:
|
|
|
72
72
|
self.required = required
|
|
73
73
|
|
|
74
74
|
|
|
75
|
+
class EnvList:
|
|
76
|
+
"""Annotation marker for a list of arbitrary environments.
|
|
77
|
+
|
|
78
|
+
Use this when the world accepts a dynamic list of environments
|
|
79
|
+
rather than named, fixed environment fields.
|
|
80
|
+
|
|
81
|
+
Usage:
|
|
82
|
+
envs: Annotated[
|
|
83
|
+
list[EnvFromSimulator | EnvFromArtifact | EnvFromResource],
|
|
84
|
+
EnvList(description="Environments to create for this task"),
|
|
85
|
+
Field(discriminator="type"),
|
|
86
|
+
] = []
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
def __init__(self, description: str = ""):
|
|
90
|
+
self.description = description
|
|
91
|
+
|
|
92
|
+
|
|
75
93
|
class StateConfig(BaseModel):
|
|
76
94
|
"""Configuration for world state persistence.
|
|
77
95
|
|
|
@@ -92,12 +110,12 @@ class CheckpointConfig(BaseModel):
|
|
|
92
110
|
"""Configuration for automatic checkpointing during world execution.
|
|
93
111
|
|
|
94
112
|
Attributes:
|
|
95
|
-
enabled: Whether to enable automatic checkpoints after steps.
|
|
113
|
+
enabled: Whether to enable automatic checkpoints after steps (default: False).
|
|
96
114
|
interval: Create checkpoint every N steps (default: 1 = every step).
|
|
97
115
|
exclude_envs: Environment aliases to exclude from checkpoints (default: ["runtime"]).
|
|
98
116
|
"""
|
|
99
117
|
|
|
100
|
-
enabled: bool =
|
|
118
|
+
enabled: bool = False
|
|
101
119
|
interval: int = 1
|
|
102
120
|
exclude_envs: list[str] = Field(default_factory=lambda: ["runtime"])
|
|
103
121
|
|
|
@@ -150,16 +168,16 @@ class RunConfig(BaseModel):
|
|
|
150
168
|
model_config = {"extra": "allow"}
|
|
151
169
|
|
|
152
170
|
@classmethod
|
|
153
|
-
def get_field_annotations(cls) -> dict[str, Agent | Secret | Env | None]:
|
|
154
|
-
"""Get Agent/Secret/Env annotations for each field."""
|
|
155
|
-
result: dict[str, Agent | Secret | Env | None] = {}
|
|
171
|
+
def get_field_annotations(cls) -> dict[str, Agent | Secret | Env | EnvList | None]:
|
|
172
|
+
"""Get Agent/Secret/Env/EnvList annotations for each field."""
|
|
173
|
+
result: dict[str, Agent | Secret | Env | EnvList | None] = {}
|
|
156
174
|
|
|
157
175
|
for field_name, field_info in cls.model_fields.items():
|
|
158
176
|
marker = None
|
|
159
177
|
|
|
160
178
|
# Pydantic stores Annotated metadata in field_info.metadata
|
|
161
179
|
for meta in field_info.metadata:
|
|
162
|
-
if isinstance(meta, (Agent, Secret, Env)):
|
|
180
|
+
if isinstance(meta, (Agent, Secret, Env, EnvList)):
|
|
163
181
|
marker = meta
|
|
164
182
|
break
|
|
165
183
|
|
|
@@ -182,6 +200,7 @@ class RunConfig(BaseModel):
|
|
|
182
200
|
agents = []
|
|
183
201
|
secrets = []
|
|
184
202
|
envs = []
|
|
203
|
+
env_list_field: dict | None = None # For EnvList marker (arbitrary envs)
|
|
185
204
|
|
|
186
205
|
# Skip runtime fields
|
|
187
206
|
runtime_fields = {"session_id", "otel_url", "upload_url", "all_secrets", "plato_session", "checkpoint", "state"}
|
|
@@ -228,6 +247,12 @@ class RunConfig(BaseModel):
|
|
|
228
247
|
"default": default_value,
|
|
229
248
|
}
|
|
230
249
|
)
|
|
250
|
+
elif isinstance(marker, EnvList):
|
|
251
|
+
# Field marked as a list of arbitrary environments
|
|
252
|
+
env_list_field = {
|
|
253
|
+
"name": field_name,
|
|
254
|
+
"description": marker.description,
|
|
255
|
+
}
|
|
231
256
|
else:
|
|
232
257
|
world_properties[field_name] = prop_schema
|
|
233
258
|
|
|
@@ -236,7 +261,7 @@ class RunConfig(BaseModel):
|
|
|
236
261
|
r for r in full_schema.get("required", []) if r not in runtime_fields and annotations.get(r) is None
|
|
237
262
|
]
|
|
238
263
|
|
|
239
|
-
|
|
264
|
+
result = {
|
|
240
265
|
"properties": world_properties,
|
|
241
266
|
"required": required,
|
|
242
267
|
"agents": agents,
|
|
@@ -244,6 +269,16 @@ class RunConfig(BaseModel):
|
|
|
244
269
|
"envs": envs,
|
|
245
270
|
}
|
|
246
271
|
|
|
272
|
+
# Include $defs if present (for nested type references)
|
|
273
|
+
if "$defs" in full_schema:
|
|
274
|
+
result["$defs"] = full_schema["$defs"]
|
|
275
|
+
|
|
276
|
+
# Add env_list if present (for worlds with arbitrary environment lists)
|
|
277
|
+
if env_list_field:
|
|
278
|
+
result["env_list"] = env_list_field
|
|
279
|
+
|
|
280
|
+
return result
|
|
281
|
+
|
|
247
282
|
def get_envs(self) -> list[EnvConfig]:
|
|
248
283
|
"""Get all environment configurations from this config.
|
|
249
284
|
|
|
@@ -287,8 +322,13 @@ class RunConfig(BaseModel):
|
|
|
287
322
|
# Handle secrets dict -> individual secret fields
|
|
288
323
|
secrets_dict = data.pop("secrets", {})
|
|
289
324
|
|
|
290
|
-
#
|
|
291
|
-
|
|
325
|
+
# Check if there's an EnvList field - if so, don't pop envs as a dict
|
|
326
|
+
has_env_list = any(isinstance(m, EnvList) for m in annotations.values())
|
|
327
|
+
|
|
328
|
+
# Handle envs dict -> individual env fields (only for named Env pattern)
|
|
329
|
+
envs_dict: dict = {}
|
|
330
|
+
if not has_env_list:
|
|
331
|
+
envs_dict = data.pop("envs", {})
|
|
292
332
|
|
|
293
333
|
# Merge world_config into top-level
|
|
294
334
|
parsed.update(world_config)
|
|
@@ -310,6 +350,11 @@ class RunConfig(BaseModel):
|
|
|
310
350
|
parsed[field_name] = _parse_env_config(env_data)
|
|
311
351
|
else:
|
|
312
352
|
parsed[field_name] = env_data
|
|
353
|
+
elif isinstance(marker, EnvList) and field_name in parsed:
|
|
354
|
+
# Parse list of env configs
|
|
355
|
+
env_list = parsed[field_name]
|
|
356
|
+
if isinstance(env_list, list):
|
|
357
|
+
parsed[field_name] = [_parse_env_config(e) if isinstance(e, dict) else e for e in env_list]
|
|
313
358
|
|
|
314
359
|
# Store all secrets for agent use
|
|
315
360
|
parsed["all_secrets"] = secrets_dict
|
|
@@ -386,15 +386,15 @@ plato/v1/sync_env.py,sha256=UIfDpx3nPHBNWzahSddvol0SvfK9vU4mr3MOIOPCGr8,24878
|
|
|
386
386
|
plato/v1/sync_flow_executor.py,sha256=kgvNYOtA9FHeNfP7qb8ZPUIlTsfIss_Z98W8uX5veck,19233
|
|
387
387
|
plato/v1/sync_sdk.py,sha256=2sedg1QJiSxr1I3kCyfaLAnlAgHlbblc3QQP_47O30k,25697
|
|
388
388
|
plato/v1/cli/__init__.py,sha256=om4b7PxgsoI7rEwuQelmQkqPdhMVn53_5qEN8kvksYw,105
|
|
389
|
-
plato/v1/cli/agent.py,sha256=
|
|
390
|
-
plato/v1/cli/chronos.py,sha256=
|
|
389
|
+
plato/v1/cli/agent.py,sha256=EbmEKWCMC5DJjmVDrYuwGenhIDgPjie8hdwrDOTSXaY,43766
|
|
390
|
+
plato/v1/cli/chronos.py,sha256=uSgvj9uvBElBWP5me30OhH5eFVvFtH8TxvcIPEie3gA,25601
|
|
391
391
|
plato/v1/cli/main.py,sha256=iKUz6Mu-4-dgr29qOUmDqBaumOCzNQKZsHAalVtaH0Q,6932
|
|
392
392
|
plato/v1/cli/pm.py,sha256=TIvXBIWFDjr4s1girMMCuvHWQJkjpmsS-igAamddIWE,49746
|
|
393
393
|
plato/v1/cli/sandbox.py,sha256=jhTney-Pr8bGmWIXOjVIMtZJ7v7uIoRnuh3wfG7weRg,98718
|
|
394
394
|
plato/v1/cli/ssh.py,sha256=enrf7Y01ZeRIyHDEX0Yt7up5zEe7MCvE9u8SP4Oqiz4,6926
|
|
395
395
|
plato/v1/cli/utils.py,sha256=ba7Crv4OjDmgCv4SeB8UeZDin-iOdQw_3N6fd-g5XVk,4572
|
|
396
396
|
plato/v1/cli/verify.py,sha256=7QmQwfOOkr8a51f8xfVIr2zif7wGl2E8HOZTbOaIoV0,20671
|
|
397
|
-
plato/v1/cli/world.py,sha256=
|
|
397
|
+
plato/v1/cli/world.py,sha256=05onBuwVQOJ0PV9lEIZQkl80SZWeTOtHWEDd49P3Xkk,8709
|
|
398
398
|
plato/v1/cli/templates/world-runner.Dockerfile,sha256=p59nPCAOUgphSiOpWA3eteRXUWTmZV6n57zn3dWUoYM,932
|
|
399
399
|
plato/v1/examples/doordash_tasks.py,sha256=8Sz9qx-vTmiOAiCAbrDRvZGsA1qQQBr1KHbxXdjr7OI,23233
|
|
400
400
|
plato/v1/examples/loadtest.py,sha256=ZsQYNN_fZjE7CbrbVJb4KDc0OLaH7b66iPrEHDhuw0U,5609
|
|
@@ -459,12 +459,12 @@ plato/v2/utils/db_cleanup.py,sha256=lnI5lsMHNHpG85Y99MaE4Rzc3618piuzhvH-uXO1zIc,
|
|
|
459
459
|
plato/v2/utils/models.py,sha256=PwehSSnIRG-tM3tWL1PzZEH77ZHhIAZ9R0UPs6YknbM,1441
|
|
460
460
|
plato/v2/utils/proxy_tunnel.py,sha256=8ZTd0jCGSfIHMvSv1fgEyacuISWnGPHLPbDglWroTzY,10463
|
|
461
461
|
plato/worlds/README.md,sha256=XFOkEA3cNNcrWkk-Cxnsl-zn-y0kvUENKQRSqFKpdqw,5479
|
|
462
|
-
plato/worlds/__init__.py,sha256=
|
|
462
|
+
plato/worlds/__init__.py,sha256=nwuEerEkP2TSfadPiOMcUE3p6u1vhaS7ZxfTh2zNcF8,2217
|
|
463
463
|
plato/worlds/base.py,sha256=1O3iKilXlr56mUPVovHY_BjM3S8T57FrotF4895qv5Y,30675
|
|
464
464
|
plato/worlds/build_hook.py,sha256=KSoW0kqa5b7NyZ7MYOw2qsZ_2FkWuz0M3Ru7AKOP7Qw,3486
|
|
465
|
-
plato/worlds/config.py,sha256=
|
|
465
|
+
plato/worlds/config.py,sha256=OJtBygnVACQl_kGF8iLofTIk8zMu8tTCNYav6lHdwNI,12874
|
|
466
466
|
plato/worlds/runner.py,sha256=r9B2BxBae8_dM7y5cJf9xhThp_I1Qvf_tlPq2rs8qC8,4013
|
|
467
|
-
plato_sdk_v2-2.
|
|
468
|
-
plato_sdk_v2-2.
|
|
469
|
-
plato_sdk_v2-2.
|
|
470
|
-
plato_sdk_v2-2.
|
|
467
|
+
plato_sdk_v2-2.5.0.dist-info/METADATA,sha256=B5O9klRDioab0Ay7I_0V0q-yNvWes23frcHXt-3rGbU,8652
|
|
468
|
+
plato_sdk_v2-2.5.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
469
|
+
plato_sdk_v2-2.5.0.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
|
|
470
|
+
plato_sdk_v2-2.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|