plato-sdk-v2 2.1.15__py3-none-any.whl → 2.1.16__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/agents/runner.py +111 -108
- {plato_sdk_v2-2.1.15.dist-info → plato_sdk_v2-2.1.16.dist-info}/METADATA +1 -1
- {plato_sdk_v2-2.1.15.dist-info → plato_sdk_v2-2.1.16.dist-info}/RECORD +5 -5
- {plato_sdk_v2-2.1.15.dist-info → plato_sdk_v2-2.1.16.dist-info}/WHEEL +0 -0
- {plato_sdk_v2-2.1.15.dist-info → plato_sdk_v2-2.1.16.dist-info}/entry_points.txt +0 -0
plato/agents/runner.py
CHANGED
|
@@ -9,7 +9,7 @@ import os
|
|
|
9
9
|
import tempfile
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
-
from plato.agents.logging import log_event, upload_artifacts
|
|
12
|
+
from plato.agents.logging import log_event, span, upload_artifacts
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|
|
15
15
|
|
|
@@ -36,112 +36,115 @@ async def run_agent(
|
|
|
36
36
|
"""
|
|
37
37
|
logs_dir = logs_dir or tempfile.mkdtemp(prefix="agent_logs_")
|
|
38
38
|
agent_name = image.split("/")[-1].split(":")[0]
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# Setup
|
|
54
|
-
os.makedirs(os.path.join(logs_dir, "agent"), exist_ok=True)
|
|
55
|
-
config_file = tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False)
|
|
56
|
-
json.dump(config, config_file)
|
|
57
|
-
config_file.close()
|
|
58
|
-
|
|
59
|
-
try:
|
|
60
|
-
# Build docker command
|
|
61
|
-
docker_cmd = ["docker", "run", "--rm"]
|
|
62
|
-
|
|
63
|
-
# Check if iptables is available for network isolation
|
|
64
|
-
try:
|
|
65
|
-
proc = await asyncio.create_subprocess_exec(
|
|
66
|
-
"iptables",
|
|
67
|
-
"-L",
|
|
68
|
-
"-n",
|
|
69
|
-
stdout=asyncio.subprocess.DEVNULL,
|
|
70
|
-
stderr=asyncio.subprocess.DEVNULL,
|
|
39
|
+
|
|
40
|
+
async with span(agent_name, span_type="agent", source="agent") as agent_span:
|
|
41
|
+
agent_span.log(f"Starting agent: {agent_name} ({image})")
|
|
42
|
+
|
|
43
|
+
# Pull image if requested
|
|
44
|
+
if pull:
|
|
45
|
+
agent_span.log(f"Pulling image: {image}")
|
|
46
|
+
pull_proc = await asyncio.create_subprocess_exec(
|
|
47
|
+
"docker",
|
|
48
|
+
"pull",
|
|
49
|
+
image,
|
|
50
|
+
stdout=asyncio.subprocess.PIPE,
|
|
51
|
+
stderr=asyncio.subprocess.STDOUT,
|
|
71
52
|
)
|
|
72
|
-
await
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
f"{logs_dir}:/logs",
|
|
86
|
-
"-v",
|
|
87
|
-
f"{config_file.name}:/config.json:ro",
|
|
88
|
-
"-w",
|
|
89
|
-
"/workspace",
|
|
90
|
-
]
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
for key, value in secrets.items():
|
|
94
|
-
docker_cmd.extend(["-e", f"{key.upper()}={value}"])
|
|
95
|
-
|
|
96
|
-
docker_cmd.append(image)
|
|
97
|
-
docker_cmd.extend(["--instruction", instruction])
|
|
98
|
-
|
|
99
|
-
# Run container and stream output
|
|
100
|
-
process = await asyncio.create_subprocess_exec(
|
|
101
|
-
*docker_cmd,
|
|
102
|
-
stdout=asyncio.subprocess.PIPE,
|
|
103
|
-
stderr=asyncio.subprocess.STDOUT,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# Stream output line by line
|
|
107
|
-
assert process.stdout is not None
|
|
108
|
-
while True:
|
|
109
|
-
line = await process.stdout.readline()
|
|
110
|
-
if not line:
|
|
111
|
-
break
|
|
112
|
-
logger.info(f"[agent] {line.decode().rstrip()}")
|
|
113
|
-
|
|
114
|
-
await process.wait()
|
|
115
|
-
|
|
116
|
-
if process.returncode != 0:
|
|
117
|
-
raise RuntimeError(f"Agent failed with exit code {process.returncode}")
|
|
118
|
-
|
|
119
|
-
logger.info("Agent completed successfully")
|
|
120
|
-
|
|
121
|
-
finally:
|
|
122
|
-
os.unlink(config_file.name)
|
|
123
|
-
|
|
124
|
-
# Upload artifacts (no-ops if logging not initialized)
|
|
125
|
-
trajectory_path = Path(logs_dir) / "agent" / "trajectory.json"
|
|
126
|
-
if trajectory_path.exists():
|
|
53
|
+
await pull_proc.wait()
|
|
54
|
+
|
|
55
|
+
# Setup
|
|
56
|
+
os.makedirs(os.path.join(logs_dir, "agent"), exist_ok=True)
|
|
57
|
+
config_file = tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False)
|
|
58
|
+
json.dump(config, config_file)
|
|
59
|
+
config_file.close()
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
# Build docker command
|
|
63
|
+
docker_cmd = ["docker", "run", "--rm"]
|
|
64
|
+
|
|
65
|
+
# Check if iptables is available for network isolation
|
|
127
66
|
try:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
67
|
+
proc = await asyncio.create_subprocess_exec(
|
|
68
|
+
"iptables",
|
|
69
|
+
"-L",
|
|
70
|
+
"-n",
|
|
71
|
+
stdout=asyncio.subprocess.DEVNULL,
|
|
72
|
+
stderr=asyncio.subprocess.DEVNULL,
|
|
73
|
+
)
|
|
74
|
+
await proc.wait()
|
|
75
|
+
has_iptables = proc.returncode == 0
|
|
76
|
+
except (FileNotFoundError, PermissionError):
|
|
77
|
+
has_iptables = False
|
|
78
|
+
|
|
79
|
+
if not has_iptables:
|
|
80
|
+
docker_cmd.extend(["--network=host", "--add-host=localhost:127.0.0.1"])
|
|
81
|
+
|
|
82
|
+
docker_cmd.extend(
|
|
83
|
+
[
|
|
84
|
+
"-v",
|
|
85
|
+
f"{workspace}:/workspace",
|
|
86
|
+
"-v",
|
|
87
|
+
f"{logs_dir}:/logs",
|
|
88
|
+
"-v",
|
|
89
|
+
f"{config_file.name}:/config.json:ro",
|
|
90
|
+
"-w",
|
|
91
|
+
"/workspace",
|
|
92
|
+
]
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
for key, value in secrets.items():
|
|
96
|
+
docker_cmd.extend(["-e", f"{key.upper()}={value}"])
|
|
97
|
+
|
|
98
|
+
docker_cmd.append(image)
|
|
99
|
+
docker_cmd.extend(["--instruction", instruction])
|
|
100
|
+
|
|
101
|
+
# Run container and stream output
|
|
102
|
+
process = await asyncio.create_subprocess_exec(
|
|
103
|
+
*docker_cmd,
|
|
104
|
+
stdout=asyncio.subprocess.PIPE,
|
|
105
|
+
stderr=asyncio.subprocess.STDOUT,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Stream output line by line
|
|
109
|
+
assert process.stdout is not None
|
|
110
|
+
while True:
|
|
111
|
+
line = await process.stdout.readline()
|
|
112
|
+
if not line:
|
|
113
|
+
break
|
|
114
|
+
logger.info(f"[agent] {line.decode().rstrip()}")
|
|
115
|
+
|
|
116
|
+
await process.wait()
|
|
117
|
+
|
|
118
|
+
if process.returncode != 0:
|
|
119
|
+
raise RuntimeError(f"Agent failed with exit code {process.returncode}")
|
|
120
|
+
|
|
121
|
+
agent_span.log("Agent completed successfully")
|
|
122
|
+
|
|
123
|
+
finally:
|
|
124
|
+
os.unlink(config_file.name)
|
|
125
|
+
|
|
126
|
+
# Load trajectory and add to span
|
|
127
|
+
trajectory_path = Path(logs_dir) / "agent" / "trajectory.json"
|
|
128
|
+
if trajectory_path.exists():
|
|
129
|
+
try:
|
|
130
|
+
with open(trajectory_path) as f:
|
|
131
|
+
trajectory = json.load(f)
|
|
132
|
+
if isinstance(trajectory, dict) and "schema_version" in trajectory:
|
|
133
|
+
# Add agent image to trajectory
|
|
134
|
+
agent_data = trajectory.get("agent", {})
|
|
135
|
+
extra = agent_data.get("extra") or {}
|
|
136
|
+
extra["image"] = image
|
|
137
|
+
agent_data["extra"] = extra
|
|
138
|
+
trajectory["agent"] = agent_data
|
|
139
|
+
|
|
140
|
+
# Log trajectory as separate event
|
|
141
|
+
await log_event(
|
|
142
|
+
span_type="trajectory",
|
|
143
|
+
log_type="atif",
|
|
144
|
+
extra=trajectory,
|
|
145
|
+
source="agent",
|
|
146
|
+
)
|
|
147
|
+
except Exception as e:
|
|
148
|
+
logger.warning(f"Failed to load trajectory: {e}")
|
|
149
|
+
|
|
150
|
+
await upload_artifacts(logs_dir)
|
|
@@ -299,7 +299,7 @@ plato/agents/base.py,sha256=vUbPQuNSo6Ka2lIB_ZOXgi4EoAjtAD7GIj9LnNotam0,4577
|
|
|
299
299
|
plato/agents/build.py,sha256=CNMbVQFs2_pYit1dA29Davve28Yi4c7TNK9wBB7odrE,1621
|
|
300
300
|
plato/agents/config.py,sha256=VZVMdCmEQnoR0VkrGdScG8p6zSKVFe7BZPd2h8lKNjI,5460
|
|
301
301
|
plato/agents/logging.py,sha256=z9rDlGPbrpcTS8PephbK2rDqT7thC1KyLkua4ypUkv4,12210
|
|
302
|
-
plato/agents/runner.py,sha256=
|
|
302
|
+
plato/agents/runner.py,sha256=rOWYTSAhdola_FdrbviP955NBusNtBUy-q_c5fDA9to,5123
|
|
303
303
|
plato/agents/trajectory.py,sha256=ayXEMCfYvIuXU2JkQWfPOVO9JywNSx8Kf6Ztrgsdh-I,10441
|
|
304
304
|
plato/chronos/__init__.py,sha256=RHMvSrQS_-vkKOyTRuAkp2gKDP1HEuBLDnw8jcZs1Jg,739
|
|
305
305
|
plato/chronos/client.py,sha256=YcOGtHWERyOD9z8LKt8bRMVL0cEwL2hiAP4qQgdZlUI,5495
|
|
@@ -463,7 +463,7 @@ plato/worlds/base.py,sha256=vLAHkYpYg4kl7LgftQ0uC6xXhASVqREogn6msNWA6Hk,9650
|
|
|
463
463
|
plato/worlds/build_hook.py,sha256=KSoW0kqa5b7NyZ7MYOw2qsZ_2FkWuz0M3Ru7AKOP7Qw,3486
|
|
464
464
|
plato/worlds/config.py,sha256=-K1dnlRL5I-DNYEoc1I4cKIsTw53X_1QrRY2SWJvRiQ,6256
|
|
465
465
|
plato/worlds/runner.py,sha256=r9B2BxBae8_dM7y5cJf9xhThp_I1Qvf_tlPq2rs8qC8,4013
|
|
466
|
-
plato_sdk_v2-2.1.
|
|
467
|
-
plato_sdk_v2-2.1.
|
|
468
|
-
plato_sdk_v2-2.1.
|
|
469
|
-
plato_sdk_v2-2.1.
|
|
466
|
+
plato_sdk_v2-2.1.16.dist-info/METADATA,sha256=5S_mx4Iij8UNv8od9y6b3n8T00t6gFzM01-1wS-rLdg,8509
|
|
467
|
+
plato_sdk_v2-2.1.16.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
468
|
+
plato_sdk_v2-2.1.16.dist-info/entry_points.txt,sha256=upGMbJCx6YWUTKrPoYvYUYfFCqYr75nHDwhA-45m6p8,136
|
|
469
|
+
plato_sdk_v2-2.1.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|