verifiers 0.2.2.dev83__py3-none-any.whl → 0.2.2.dev85__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.
@@ -165,6 +165,8 @@ class JudgeTask(vf.Task):
165
165
  image=solved.image,
166
166
  workdir=solved.workdir,
167
167
  resources=solved.resources,
168
+ network_allow=solved.network_allow,
169
+ network_block=solved.network_block,
168
170
  ),
169
171
  files=files,
170
172
  artifacts={} if share_runtime else solution.state.artifacts,
verifiers/v1/graph.py CHANGED
@@ -101,6 +101,11 @@ class MessageNode(BaseModel):
101
101
  logprobs: list[float] = Field(default_factory=list)
102
102
  """Sampling logprobs for the sampled tokens — length equals the number of True entries in
103
103
  `mask`; empty for input messages."""
104
+ advantages: list[float] | None = None
105
+ """Per-token credit over the sampled tokens, same layout as `logprobs`. `None` until a
106
+ consumer's RL algorithm assigns it, which is not the same as a credit of zero: a group whose
107
+ rewards were all equal is assigned zeros and carries no gradient, while an unassigned node was
108
+ never scored at all."""
104
109
  multi_modal_data: SkipJsonSchema[MultiModalData | None] = None
105
110
  """The renderer items for the images this message's content introduces (pixel tensors,
106
111
  grids, hashes, placeholders) — the only carrier of the pixels from the env server to the
@@ -332,19 +332,17 @@ class Runtime(ABC):
332
332
  return url
333
333
 
334
334
  async def prepare_setup(self) -> None:
335
- """Claim the runtime for trusted setup; restricted runtimes may reject reuse."""
335
+ """Open egress for trusted setup when reusing a restricted runtime."""
336
336
  if not self.network_restricted:
337
337
  return
338
338
  if self._setup_claimed:
339
- raise SandboxError(
340
- f"network-filtered {self.type} runtimes are single-rollout; "
341
- "provision a fresh runtime instead of reusing this one"
342
- )
339
+ await self.prepare_execution(None)
343
340
  self._setup_claimed = True
344
341
 
345
- async def prepare_execution(self, routes: list[str]) -> None:
342
+ async def prepare_execution(self, routes: list[str] | None) -> None:
346
343
  """Last setup step, right before the agent starts. Restricted runtimes enforce
347
- their policy here; `routes` identifies the interception and MCP endpoints."""
344
+ their policy here; `routes` identifies the interception and MCP endpoints.
345
+ None restores unrestricted egress for another trusted setup phase."""
348
346
 
349
347
  @property
350
348
  def network_restricted(self) -> bool:
@@ -233,11 +233,16 @@ class DockerRuntime(Runtime):
233
233
  return url.replace(host, "host.docker.internal", 1)
234
234
  return url
235
235
 
236
- async def prepare_execution(self, routes: list[str]) -> None:
236
+ async def prepare_execution(self, routes: list[str] | None) -> None:
237
237
  """Allow the declared framework routes, then leave the proxy as the only route."""
238
238
  if not self.network_restricted:
239
239
  return
240
240
  assert self._proxy is not None
241
+ if routes is None:
242
+ self._proxy.policy = NetworkPolicy(
243
+ ["*"], [], [HOST_ALIAS], allow_non_global=True
244
+ )
245
+ return
241
246
  framework = [
242
247
  urlsplit(url)._replace(path="", query="", fragment="").geturl()
243
248
  for url in routes
@@ -247,6 +252,8 @@ class DockerRuntime(Runtime):
247
252
  self.config.block,
248
253
  framework,
249
254
  )
255
+ if self._cut:
256
+ return
250
257
  script = (
251
258
  "set -eu; HOST=$1; "
252
259
  "PORT=$2; "
@@ -181,22 +181,25 @@ class PrimeRuntime(Runtime):
181
181
  ) as e: # provisioning failure is one rollout's problem, not the eval's
182
182
  raise SandboxError(f"prime sandbox provisioning failed: {e}") from e
183
183
 
184
- async def prepare_execution(self, routes: list[str]) -> None:
184
+ async def prepare_execution(self, routes: list[str] | None) -> None:
185
185
  """Apply the host policy after setup and wait until the platform enforces it."""
186
186
  if not self.network_restricted:
187
187
  return
188
188
  try:
189
- hosts = list(
190
- dict.fromkeys(
191
- h for h in (urlsplit(route).hostname for route in routes) if h
192
- )
193
- )
194
- if self.config.allow == ["*"]:
195
- policy = {"deny": self.config.block}
189
+ if routes is None:
190
+ policy = {"allow": ["*"]}
196
191
  else:
197
- entries = list(dict.fromkeys([*hosts, *self.config.allow]))
198
- validate_egress_lists(entries, None)
199
- policy = {"allow": entries} if entries else {"deny": ["*"]}
192
+ hosts = list(
193
+ dict.fromkeys(
194
+ h for h in (urlsplit(route).hostname for route in routes) if h
195
+ )
196
+ )
197
+ if self.config.allow == ["*"]:
198
+ policy = {"deny": self.config.block}
199
+ else:
200
+ entries = list(dict.fromkeys([*hosts, *self.config.allow]))
201
+ validate_egress_lists(entries, None)
202
+ policy = {"allow": entries} if entries else {"deny": ["*"]}
200
203
  status = await self._client.set_network(self.info.id, **policy)
201
204
  try:
202
205
  async with asyncio.timeout(60):
@@ -217,8 +220,8 @@ class PrimeRuntime(Runtime):
217
220
  logger.info(
218
221
  "prime: egress policy applied on sandbox %s (allow=%s block=%s)",
219
222
  self.info.id,
220
- self.config.allow,
221
- self.config.block,
223
+ policy.get("allow"),
224
+ policy.get("deny"),
222
225
  )
223
226
 
224
227
  async def run(self, argv: list[str], env: dict[str, str]) -> ProgramResult:
verifiers/v1/trace.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import time
4
4
  import traceback
5
5
  import uuid
6
- from collections.abc import Mapping
6
+ from collections.abc import Callable, Mapping
7
7
  from typing import TYPE_CHECKING, Annotated, Any, Generic, Literal
8
8
 
9
9
  import numpy as np
@@ -200,28 +200,45 @@ class Branch(BaseModel):
200
200
  mask.extend(node.mask)
201
201
  return mask
202
202
 
203
- @property
204
- def logprobs(self) -> list[float]:
205
- """Per-token sampling logprobs aligned to `token_ids` — the node logprobs spread onto
206
- their sampled positions, 0.0 on every non-sampled token."""
203
+ def spread(
204
+ self, values: Callable[[MessageNode], list[float] | None]
205
+ ) -> list[float]:
206
+ """A per-sampled-token node field widened to `token_ids`: each node's values land on its
207
+ sampled positions, 0.0 everywhere else. A node holding nothing contributes zeros."""
207
208
  out: list[float] = []
208
209
  for node in self.nodes:
209
- mask = node.mask
210
- sampled = sum(mask) if node.logprobs else 0
210
+ mask, node_values = node.mask, values(node) or []
211
+ sampled = sum(mask) if node_values else 0
211
212
  # Bulk-fill the canonical unsampled-prefix/sampled-suffix layout.
212
213
  if not sampled or all(mask[-sampled:]):
213
- out += [0.0] * (len(mask) - sampled) + node.logprobs[:sampled]
214
- out += [0.0] * max(0, sampled - len(node.logprobs))
214
+ out += [0.0] * (len(mask) - sampled) + node_values[:sampled]
215
+ out += [0.0] * max(0, sampled - len(node_values))
215
216
  continue
216
217
  li = 0
217
- for sampled in mask:
218
- if sampled:
219
- out.append(node.logprobs[li] if li < len(node.logprobs) else 0.0)
218
+ for is_sampled in mask:
219
+ if is_sampled:
220
+ out.append(node_values[li] if li < len(node_values) else 0.0)
220
221
  li += 1
221
222
  else:
222
223
  out.append(0.0)
223
224
  return out
224
225
 
226
+ @property
227
+ def logprobs(self) -> list[float]:
228
+ """Per-token sampling logprobs aligned to `token_ids` — the node logprobs spread onto
229
+ their sampled positions, 0.0 on every non-sampled token."""
230
+ return self.spread(lambda node: node.logprobs)
231
+
232
+ @property
233
+ def advantages(self) -> list[float] | None:
234
+ """Per-token credit aligned to `token_ids`, spread like `logprobs` — or `None` when no node
235
+ on the path was ever assigned any, which a branch of zeros would otherwise be
236
+ indistinguishable from. A partially assigned path spreads, the unassigned nodes reading
237
+ 0.0."""
238
+ if all(node.advantages is None for node in self.nodes):
239
+ return None
240
+ return self.spread(lambda node: node.advantages)
241
+
225
242
  @property
226
243
  def multi_modal_data(self) -> MultiModalData | None:
227
244
  """Node image data concatenated in token order for training; never persisted."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifiers
3
- Version: 0.2.2.dev83
3
+ Version: 0.2.2.dev85
4
4
  Summary: Verifiers: Environments for LLM Reinforcement Learning
5
5
  Project-URL: Homepage, https://github.com/primeintellect-ai/verifiers
6
6
  Project-URL: Documentation, https://github.com/primeintellect-ai/verifiers
@@ -172,7 +172,7 @@ verifiers/v1/agent.py,sha256=MQVKGjUhrP8uzRXAq94uJHkEsdHFziPxQHZ7TOD324I,31306
172
172
  verifiers/v1/env.py,sha256=g6fpoG-Z9lM3vTKrrU-QRJY3S88_y9zsPHwBvfs5vdY,17865
173
173
  verifiers/v1/episode.py,sha256=8G5OaGOku9S_gavQdpfUZgRZfrf1zmpjFrBL-TsppIk,4123
174
174
  verifiers/v1/errors.py,sha256=kQeEPX06TwAIuiz7MlWFYirrpKbx5STi6A5b_dtQQoA,6885
175
- verifiers/v1/graph.py,sha256=aBAzh1Ibp3klKNYjvzNyJSbjV8Oi5TJ791dN7o6ex1E,29070
175
+ verifiers/v1/graph.py,sha256=psE4gww42TuSy_B4rJfGauycGTzPes6Z2SKFAzPYg7M,29427
176
176
  verifiers/v1/harness.py,sha256=eKuqvYbQjnCMavkiYWZQDHJgH08m6SJ4PuevPuShjS0,11097
177
177
  verifiers/v1/judge.py,sha256=Pvr0C41ah1qkNSZ0WXdkDvBMfv5YSfY1REHncwlJ8cg,9346
178
178
  verifiers/v1/legacy.py,sha256=YvcWF6d8xvkeqUPM36oif0ZrjmB0mj7nNrfwha0Nr2w,22850
@@ -181,7 +181,7 @@ verifiers/v1/session.py,sha256=p8vz89DJUmb9r8dkq80zn2WBEqo8Vwh8ot1ZXm_WVAM,7210
181
181
  verifiers/v1/state.py,sha256=EckF2bWp-vV4b1jYJ9sLI5xrfGuI5spIgYYwW926toI,595
182
182
  verifiers/v1/task.py,sha256=jwMKiKlMtksTd8j2dcDlFtb6LC8BRE-N5jkNXlMp2jc,9457
183
183
  verifiers/v1/taskset.py,sha256=fp2E0IEhL_Ybj9cegZwljfTmW27p_30zTWHFKw_kXE4,4374
184
- verifiers/v1/trace.py,sha256=esJE1aT9jRCbBad-BVR9xjX5Emk4mHdYmC7Zct-3zK8,19129
184
+ verifiers/v1/trace.py,sha256=Mjc9NaqmUVKXhn6RKaTaGVxPRldCGqgHxb74cqtp5_k,20026
185
185
  verifiers/v1/types.py,sha256=1PxamJspmoTc3OlFZAwH6o_2i_Tg9ZNvHxttIHWIxq8,8948
186
186
  verifiers/v1/acp/__init__.py,sha256=9SYCFtzGUM_wH98ldpVLcFhoq2M999jbG0tU5ODY70U,2297
187
187
  verifiers/v1/acp/_runner.py,sha256=BcYaNZHuawzCgxOVdhiF6PY_B1HMxIA1MwHy0mOzhSk,7740
@@ -232,7 +232,7 @@ verifiers/v1/dialects/chat.py,sha256=R_otqi5N0snB1QVKIYloNeLHR9kc7OmI06HYg1ir_Lw
232
232
  verifiers/v1/dialects/responses.py,sha256=ismnxUikPcPUIm80FUTPBbj-Cn1e0yGAsISMEseAWRc,13679
233
233
  verifiers/v1/envs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
234
234
  verifiers/v1/envs/agentic_judge/__init__.py,sha256=6vwtMCQ_cuvuubCF5-nrE5W7gGgzE-LIPKorkM5DXdw,309
235
- verifiers/v1/envs/agentic_judge/env.py,sha256=0KXuTEg4nd0jprPqFgQYFxf2JLdPVbUmljbgPOT-5Bg,13810
235
+ verifiers/v1/envs/agentic_judge/env.py,sha256=ZgNDanhSQYpP3K5Vz2rUW0UjWGApdqz86ng9BXhj6PA,13914
236
236
  verifiers/v1/envs/best_of_n/__init__.py,sha256=mubASiwXMNIhnQFDccNAc7yZ0OFsOVK8hH8WIx9b2A4,119
237
237
  verifiers/v1/envs/best_of_n/env.py,sha256=KEUJBCVqblnXP_lEwm3mjGdaikBMkecz8UjOFPBhxc0,1987
238
238
  verifiers/v1/envs/single_agent/__init__.py,sha256=r0edAc_6gtHBhPzeBGVcdHZZqSdCPZnLMje6eVgyz5U,138
@@ -296,12 +296,12 @@ verifiers/v1/mcp/launch.py,sha256=wBpyeiOO86l1H2lVMbLVSV9Lbp90XeyXqauuK8snfEU,20
296
296
  verifiers/v1/mcp/server.py,sha256=dRBxytFgS6rv1BS6t5EgBd3xeF6U1nTyt0ArDCLk3VE,12301
297
297
  verifiers/v1/mcp/toolset.py,sha256=T8Ioiq4wphxVOTHUDf28ZoQBM2ZYEevGnGgw8TFEMiA,1002
298
298
  verifiers/v1/runtimes/__init__.py,sha256=Kwe612RjtGzrQhc19QdXc7CmZAnQLH-EdK_xqkKP3Tk,2629
299
- verifiers/v1/runtimes/base.py,sha256=tZRELSfZmi3l_1BsjabnNC3mEPfqNvUNevdnRvLPv6w,16257
299
+ verifiers/v1/runtimes/base.py,sha256=0vLTBATJplxVAgXRNqbUzX4J26p88f-r7JQmWsOugxg,16180
300
300
  verifiers/v1/runtimes/limiters.py,sha256=ZjjYUFEt20yH8ggL5uU9w9U500AOB44qSUTQ7bYyh0c,2730
301
301
  verifiers/v1/runtimes/modal.py,sha256=eFiT-Ovf_RwQZbSw3Dwv2EXeHV0d6uGvPswqKYKCw5k,8826
302
- verifiers/v1/runtimes/prime.py,sha256=kwvPqUI8D-GvcFwYRdpTHE1hXS0vfJGPlFOLgzm4Mvs,14756
302
+ verifiers/v1/runtimes/prime.py,sha256=gJf-Ap5N-9Ecp-GpCNlPta7Gc9C5--Bzbk3rbK-vBIQ,14901
303
303
  verifiers/v1/runtimes/subprocess.py,sha256=ZrHRlTuTyCrcSKpiPD2ElcPpe97EvVsXJ8BfwUaNXiI,5988
304
- verifiers/v1/runtimes/docker/__init__.py,sha256=vyEgf6XgAwjGgBicJchJvNgcDgYXrRvyQC4W52-23GU,14556
304
+ verifiers/v1/runtimes/docker/__init__.py,sha256=ObGNk7Uc5I4C3sumwIuD0Z30sO3FeDxl62hElfrGyWw,14775
305
305
  verifiers/v1/runtimes/docker/egress.py,sha256=37UXgNX9gnoLxjMg4KZaJIGoApCAM6MK22eJGNoMi38,14514
306
306
  verifiers/v1/serve/__init__.py,sha256=sr_zkDzAHnOcQm-QRm8xwJBmCMFD-xhKIFPaDZvMbUs,641
307
307
  verifiers/v1/serve/client.py,sha256=CxpOwCn4ehuCXfqDJeV9zj7O0XC7MPcI-OZ1L_CSDlo,7057
@@ -337,8 +337,8 @@ verifiers/v1/utils/platform.py,sha256=56Ixmk1SER6q5LvzyYcA0hgzGpzhxKZL8Hiqp4c_XV
337
337
  verifiers/v1/utils/retries.py,sha256=Y2ZgrAjn-qNkRKZP_RVNL_7EK0iaRcZeCa404lpGYi4,5417
338
338
  verifiers/v1/utils/score.py,sha256=-R5Cog14r_tJ6Q_oOfGr5VPAm2CCUhofYZB6B9lm4wM,5787
339
339
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
340
- verifiers-0.2.2.dev83.dist-info/METADATA,sha256=OUiuO72iMqAkO4SE5Jo824igRE0CARGjQB-3P9XLXd0,4545
341
- verifiers-0.2.2.dev83.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
342
- verifiers-0.2.2.dev83.dist-info/entry_points.txt,sha256=v6v0QT9vVExnfn4br42MostI_o3f3ZbWYlTormz-U3g,515
343
- verifiers-0.2.2.dev83.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
344
- verifiers-0.2.2.dev83.dist-info/RECORD,,
340
+ verifiers-0.2.2.dev85.dist-info/METADATA,sha256=SXrfQrFds4Ppx3ye69DlhIspd3t9JAz7gx4EfYB7CA0,4545
341
+ verifiers-0.2.2.dev85.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
342
+ verifiers-0.2.2.dev85.dist-info/entry_points.txt,sha256=v6v0QT9vVExnfn4br42MostI_o3f3ZbWYlTormz-U3g,515
343
+ verifiers-0.2.2.dev85.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
344
+ verifiers-0.2.2.dev85.dist-info/RECORD,,